-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
757 lines (502 loc) · 88 KB
/
atom.xml
File metadata and controls
757 lines (502 loc) · 88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[iOS Coding]]></title>
<link href="http://ios-coding.com/atom.xml" rel="self"/>
<link href="http://ios-coding.com/"/>
<updated>2016-09-09T14:38:10+02:00</updated>
<id>http://ios-coding.com/</id>
<author>
<name><![CDATA[Michael Ochs]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[Making progress on ViewDeck 3.0]]></title>
<link href="http://ios-coding.com/blog/2016/09/08/making-progress-on-viewdeck-3/"/>
<updated>2016-09-08T10:38:00+02:00</updated>
<id>http://ios-coding.com/blog/2016/09/08/making-progress-on-viewdeck-3</id>
<content type="html"><![CDATA[<p>I took over ViewDeck as a maintainer from Tom about a year ago. Since then not much has happened, it looks like. In this post I want to talk about what I have done in the last year and where I clearly have underestimated the amount of work maintaining an Open Source project like this takes. I’ll then talk a bit about what the next steps will be.</p>
<!--more-->
<h2>Taking Over</h2>
<p>Tom was looking for someone to take over the project because he was unable to maintain it anymore as he joined Apple. Even though I never used ViewDeck myself I always thought it was a very nice and helpful project and I did not want to see it die.</p>
<p>Back then I was working at HRS and already pushed forward the open sourcing of some of the components we developed there. I had some spare time and wanted to get more involved in the Open Source community to give something back after years of benefitting from it. So I contacted Tom and asked him if he already had found a maintainer and if not, I’d love to take over – he had not, so I did take over.</p>
<p>Due to the fact that Tom did not had any time to maintain it for the last couple of years, I was confronted with a huge amount of issues that were lacking a response when I first looked into the repository. My first task was to create a couple of labels and start tagging all the things to get a better overview about what were questions from people that had issues, what might be bugs, and feature requests. I then started answering them as good as possible. There were a couple of issues that required me to dig deep into the code and while doing so I already realized that there are many, many lines of code in ViewDeck that are from the ages where child view controllers were not supported by UIKit – an inconvenient state when you are maintaining a view controller whose purpose is to manage child view controllers. ViewDeck contained, and still contains, a ton of legacy code. The other part of ViewDeck is a ton of code that makes this legacy code work on current iOS versions. And while it was a very noble approach from Tom to keep that project working on all the old iOS versions as well, I quickly decided that I don’t want to go down that route, but I will come back to this in a minute.</p>
<p>While answering a lot of questions and bug reports, I fixed a bunch of bugs and was working on getting the first version of ViewDeck out that fixed the most critical issues that were reported in the current versions of iOS. This is what version 2.4.0 was about. Another thing I did in this version was, I deprecated a lot of methods in <code>IIViewDeckController</code>. In fact I probably deprecated half of its features. My main reasoning behind this was to cut down the complexity of the controller and see what was actually used in the wild. Each deprecation had a warning on it to file an issue if people would still want to use this feature – the results surprised me, but we come to that later. I did two more bug fix releases and at the time I am writing this the latest release is 2.4.2.</p>
<h2>Setting the Course for 3.0</h2>
<p>As I said above, I did not want to maintain the library in a way that would still keep it compatible to old iOS versions. It requires a huge amount of work as in my eyes the only way to do this without piling up a huge amount of patches in the code is to always refactor the stuff you are working on to the latest technologies and then make it also work on old versions. If you do not do it this way, you inadvertently end up with code that has the architecture and the features of the minimum iOS Version you are supporting and then a bunch of patches that try to get this code working with the latest iOS versions. This results in a UI that doesn’t feel right anymore as it doesn’t take advantage of all the new features available, while other apps do.</p>
<p>I don’t have the time to do it the right way, the benefit is very little, and I could build a ton of features while instead trying to make a version working almost nobody is using anymore. My goal here is clear: I want to maintain the last two major iOS releases. If stuff works on older versions, fine, but if I need to write a single line of code to get it working on anything that is older than that, it’s not going to happen as it would be code that someone would need to clean up again at some point.</p>
<h2>The Current State of ViewDeck 3.0</h2>
<p>Because of the amount of outdated code and the huge number of features, I started reimplementing ViewDeck 3.0 from scratch after I tried to remove all the outdated stuff piece by piece. There is simply no point in removing a single piece and make the newly written code work with the other outdated parts, just to then start removing the next outdated part. By now I have an implementation that restores the main functionality of showing and hiding side view controllers via buttons and gesture recognizers. I also have put some effort in making the presentation of side view controllers customizable. As I am not entirely settled on the API yet, my plan is to have most of that customization methods still private in 3.0 and then open this up more and more through out the minor releases of ViewDeck 3.</p>
<p>There are a couple of other, smaller things on my todo list for ViewDeck 3.0 but I plan to release a minimal set of features shortly after iOS 10 launches in order to get a new release out as soon as possible. I want to enable people to move to a new version as soon as possible as the current release still has a couple of issues when it comes to rotation and resizing. So I decided to release with the feature set that probably is enough for 90% of the apps using ViewDeck. The other 10% might need to wait a little longer but I see no point in holding back code that works for most people just to take care of a bunch of rarely used features.</p>
<p>I deprecated a lot of features and currently I don’t plan to reintroduce most of them because I did not get a lot of responses after deprecating all these methods. This either means nobody is using them or nobody is updating to the most recent version of ViewDeck. The update behavior may be worse than on other projects as at some point there was a broken release version and the solution was to use an old version. Therefore I think many people have pinned their version of ViewDeck to an old one, not even noticing that there are updates available. In either case it doesn’t really matter if the old features are still in the next major version and the less features there are, the easier it is to maintain everything. If, of course, there are feature requests coming in and enough people would love to see the same feature, I am more than happy to add them. I just want to try and keep things small and simple so that the code base is easy to understand.</p>
<p>Let me know what you think about my approach and check out the <a href="https://github.com/ViewDeck/ViewDeck/tree/feature/v3-reintegration">v3-reintegration branch</a> on GitHub. I will publish another post about versioning in ViewDeck shortly, so stay tuned.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Maintaining ViewDeck]]></title>
<link href="http://ios-coding.com/blog/2015/11/01/maintaining-viewdeck/"/>
<updated>2015-11-01T13:08:00+01:00</updated>
<id>http://ios-coding.com/blog/2015/11/01/maintaining-viewdeck</id>
<content type="html"><![CDATA[<p>For a couple of weeks now I have taken over <a href="https://github.com/ViewDeck/ViewDeck">ViewDeck</a> as the maintainer of the library. The original author and maintainer <a href="http://inferis.org">Tom Adriaenssen</a> aka <a href="https://twitter.com/inferis">@inferis</a> was able to get a Software Engineering job at Apple and therefore is not able to maintain the library anymore. Congratulations on the new job! Tom has been looking for a new owner <a href="http://blog.inferis.org/blog/2015/09/14/wanted-new-maintainer-for-viewdeck/">for some time now</a>. I want to thank Tom for his work on this great library and I hope I will be able to keep up his good work.</p>
<p>I am planning on changing a couple of things in this library in order to lift this very big project which technically still supports iOS 4 to a current set of technologies. My goal is to provide a future proof option to easily integrate a side bar into every iOS project.</p>
<!--more-->
<h2>tl;dr</h2>
<p>If you are using ViewDeck, you might at least want to read ‘Transition to 3.x’. But if you don’t even want to read that, the message basically is: There will be a 2.4.0, after that there will be a 3.0.0 and unless you open an issue on GitHub, a couple of features will go away in 3.0.0.</p>
<h2>Hamburger menu</h2>
<p>The hamburger menu has always been discussed very controversial. I myself am a very strong objector of the hamburger menu. So how comes I now maintain a library that does exactly that? Because I think the problem with the hamburger menu is that it is done wrong most of the time. Often a couple of people are discussing what the most important aspects of an application are and if they can’t decide, they simply use a hamburger menu and show all of the features of an app, letting the user figure out what really is important. This is bad user experience, in my opinion, and if you have so many features in your app that are all equally important, you may want to reconsider your decision to put them all in one app. For these kind of menus there is the <code>UITabBarController</code> and there is a reason why it can only show a maximum of 5 elements at a time. This is the use case that I would refer to as hamburger menus.</p>
<p>However there are many other reasons where a side menu might make sense. One is Facebook’s chat list on the right side. The right side of the screen isn’t occupied by any native iOS gestures, so it is a great place to show stuff like a buddy list. This is not a list that shows different features but it is a selection where the user can choose from a list of equal items, in this case their buddies.</p>
<p>The left side of an iOS application is a bit more tricky. In every navigation controller based application the left side of the screen is occupied by the back gesture of the navigation controller. Putting a side menu there leads to a bad user experience. Unless you are an application that is not navigation controller based or you only show the menu in the lowest content controller, where no back gesture is available. A good example for this is Slack. It is an application that technically has a navigation controller but the vast majority of time you spend in the app will be with only one view controller of the navigation stack. So it makes sense to put a list of channels in a left side menu. Metaphorically they are below the main view controller that shows what is going on in a channel, however they are not and should not be the entry point of the application as you are always inside a channel. It makes sense to use a side menu in this case. And again, it shows a list of the same kind of items.</p>
<h2>Semantic versioning</h2>
<p>Currently I am working on a stable 2.4.0 version that fixes the most common bugs that are currently in ViewDeck. This probably will not be the last 2.x version but after this I will start working on a 3.0.0 version which, according to my current plan, will remove a couple of features where I don’t see a use case anymore.</p>
<p>I will maintain ViewDeck strickly under the Semantic Versioning system. In short this means, within a given major release (e.g. 2.x) you can be sure that you will not see any breaking changes in the API. There might be methods getting deprecated but they are guaranteed to at least function until the next major release.</p>
<h2>Transition to 3.x</h2>
<p>With the release of 2.4.0 I will flag a lot of methods as deprecated. This does not necessarily mean that the methods and features will go away in 3.0.0. It is a great way for me to get a feeling of what features are currently in use. If you find one of your favorite features to be deprecated in 2.4.0 please create an <a href="https://github.com/ViewDeck/ViewDeck/issues/new">issue on GitHub</a> and let me know.</p>
<p>One of the single biggest changes in 3.0.0 will probably be that it removes compatibility to old iOS releases. I am currently planning to make ViewDeck iOS 8+. As the 3.0.0 release will be at least a couple of month in the future, I think by then the adoption of iOS 8 and iOS 9 will be big enough to safely remove iOS 7 compatibility. This enables a lot of other cleanup work in the code. ViewDeck can then finally move to a fully child-controller enabled pattern where it doesn’t need to call appearance methods (<code>viewWillAppear:</code>, <code>viewDidAppear:</code>, …) manually anymore. Everybody who has written a container view controller in the past knows that this is a big step forward and probably eliminates a lot of code which always means less bugs.</p>
<p>Another thing that I am pretty sure can be removed is the support for top and bottom menues. Not only does this mean less code to maintain but I also think that these menues collide with the iOS notification center and control center, leading to a bad user experience.</p>
<p>There are other features where I want to change the API for them or, in some cases, remove API but not the feature. ViewDeck currently has too many options and it is very hard to get your head around all of them, especially if you are new to the framework and try to integrate this the first time.</p>
<h2>Documentation</h2>
<p>The last thing that I find is very important for a new major release is documentation. For the 3.0.0 release my goal is to have a documentation for all public methods of ViewDeck in the header and in <a href="http://cocoadocs.org">cocoadocs.org</a>.</p>
<p>My goal is to make this a required thing for contributing to this project. In order for a pull request to get merged, the pull request needs to have full, extensive documentation of every newly added public method. Also in order to keep a clean API I will not merge pull requests that implement new features that are not requested by at least a couple of users.</p>
<p>I hope you see my thoughts as an improvement to the library and agree with them. If not, please let me know in the comments or open an issue on GitHub; after all this is an open source project and changes should be made in a democratic way.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Connection handling in UIViewController]]></title>
<link href="http://ios-coding.com/blog/2014/10/11/connection-handling-in-uiviewcontroller/"/>
<updated>2014-10-11T13:24:12+02:00</updated>
<id>http://ios-coding.com/blog/2014/10/11/connection-handling-in-uiviewcontroller</id>
<content type="html"><![CDATA[<p>This is the second post in my <code>UIViewController</code> series. This time I want to explain what I think is the best practice to do connection handling in your custom view controller instances.</p>
<p>There are a couple of ways to implement a connection handling in your application and different reasons for an application to load data from the web. If you are for example developing an application like a todo application, you probably do not want to load data in the view controllers at all. A better way to do this would be to have a synchronization manager that does all the loading and the view controllers are only showing the locally cached data. If you are developing one of these apps, this post is not helping you at all. Connection handling is not part of your view controller, but updating your view according to changes in your model is, so you might want to have a look at my previous post about <a href="http://ios-coding.com/blog/2014/06/22/model-handling-in-uiviewcontroller/">model handling in UIViewController</a>. This post is only about the how and when to load data in your view controllers and how to respond to error events.</p>
<!--more-->
<h2>Use AFNetworking</h2>
<p>There is not much to say about it. Use <code>AFNetworking</code> when making connections! You have a very comfortable block based API when dealing with your requests and you do not need to deal with taming <code>NSURLConnection</code> in a background thread yourself. The framework is constantly improved and the development community is very active in this open source project. It is maintained by <a href="http://mattt.me">Mattt Thompson</a>, who is well known for <a href="https://github.com/mattt">a lot of very great projects</a>.</p>
<h2>Use the presenting view controller</h2>
<p>So we are going to load data in our view controllers. My first point is something that you might not be able to do, but still: Do not do it! Well, that is not entirely true, you just should not load the data in the view controller that is also displaying it. In my experience it is a lot easier if the previous view controller starts the connection and presents the displaying view controller only if the connection was successful. In my opinion this also leads to a much better user experience with less effort.</p>
<p>One thing people tend to forget is: Your connection might fail. It is even very likely that your connection will fail. Do not make the mistake to think that everybody around the world has a LTE or 4G connection with speeds around 100MBit/s. Mobile networks are still very bad in a lot of places around the world! Make sure to design your app and your connection handling around a slow EDGE connection. This are the circumstances people will use your app the most in. If you have an app that has something to do with travel, chances are high that a large number of your customers don’t have access to the internet at all, when they are using your app, as most people still have roaming disabled.</p>
<p>The point I am trying to make here is that people will see your error dialog way more often than you think. Design it wisely and make sure it interupts the user’s workflow as less as possible. Empty pages with a text that tells the user that he or she needs an internet connection might look nice, but it forces the user to read the text to realize what went wrong and leave the screen again before he can continue to use your app. A popover telling the user that the request failed with a ‘cancel’ and a ‘retry’ button lets the user quickly decide how to preceed and if he taps ‘cancel’ he is right back where he was.</p>
<p>This is one of the reasons why I think the workflow should be as follows: The user taps on whatever makes the next view controller appear. The current view controller triggers the connection and shows a loading overlay. If an error occurs, show it to the user, either in an alert view or in a custom designed popover. You can do this very easily with the techniques described in my post about <a href="http://ios-coding.com/blog/2014/10/03/custom-error-handling-on-ios/">custom error handling on iOS</a>. Make sure to give the user an option to retry, if it was an error from the <code>NSURLErrorDomain</code> error domain. If no error occurs, instantiate the target view controller, set the model on it and display the controller.</p>
<p>To make sure you do not need to setup the same response in a variety of view controllers that all have a transition to the same view controller, you can still let the target view controller create the connection that is needed. With blocks you can create a very easy to use pattern that can be implemented by all of your view controllers:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">+</span> <span class="p">(</span><span class="n">NSURLConnection</span> <span class="o">*</span><span class="p">)</span><span class="nf">loadData:</span><span class="p">(</span><span class="kt">void</span><span class="p">(</span><span class="o">^</span><span class="p">)(</span><span class="kt">id</span> <span class="n">data</span><span class="p">,</span> <span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">))</span><span class="nv">completionHandler</span><span class="p">;</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">setData:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">data</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>
<p>Make sure to implement the first method as a class method. This way you can load the data before you instantiate the view controller. If you use a framework like <code>AFNetworking</code> the implementation of this method is as simple as creating the request and enqueuing a new operation with it. You already have a success and a failure completion handler that you can use to call the completion handler from in there. If you like the approach of having two different completion handler, one for the success case and one for the failure case, you can easily adjust the method above to represent that as well. If you are using <code>AFNetworking</code> you should also change the return value of the method to <code>AFHTTPRequestOperation</code>. The return value of the operation is to be able to cancel the operation if you have to, e.g. when the view controller that started the connection is removed from the navigation stack.</p>
<p>The <code>setData:</code> method takes the <code>data</code> from the completion handler and configures the view controller.</p>
<p>So to display a view controller with prefetched data, all you need to do is:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">IBAction</span><span class="p">)</span><span class="nf">showDetails:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">sender</span> <span class="p">{</span>
</span><span class='line'> <span class="p">[</span><span class="n">ViewController</span> <span class="nl">loadData:</span><span class="o">^</span><span class="p">(</span><span class="kt">id</span> <span class="n">data</span><span class="p">,</span> <span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">// handle the error (e.g. present it!)</span>
</span><span class='line'> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'> <span class="n">ViewController</span> <span class="o">*</span><span class="n">viewController</span> <span class="o">=</span> <span class="p">[</span><span class="n">ViewController</span> <span class="n">new</span><span class="p">];</span>
</span><span class='line'> <span class="n">viewController</span><span class="p">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">;</span>
</span><span class='line'> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">navigationController</span> <span class="nl">pushViewController:</span><span class="n">viewController</span> <span class="nl">animated:</span><span class="n">YES</span><span class="p">];</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">}];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>If you use the <a href="http://ios-coding.com/blog/2014/10/03/custom-error-handling-on-ios/">custom error handling</a> I mentioned, your error handling is also only a couple of lines:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="p">[</span><span class="n">self</span> <span class="nl">presentError:</span><span class="n">error</span> <span class="nl">completionHandler:</span><span class="o">^</span><span class="p">(</span><span class="kt">BOOL</span> <span class="n">didRecover</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">didRecover</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="p">[</span><span class="n">self</span> <span class="nl">showDetails:</span><span class="n">sender</span><span class="p">];</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}];</span>
</span></code></pre></td></tr></table></div></figure>
<h2>What about the target view controller?</h2>
<p>If you cannot load your data in the presenting view controller for whatever reason, you can still use a very similar API design as above and add a couple of guards. The important part is to make sure the reload trigger can be called at every time, regardless of whether your view controller is currently visible or not. Your view controller does not know when its view will be displayed or hidden, so make sure that it does not matter.</p>
<p>If you do that, you can then load the data during initialization or when your view controller is displayed. Your connection layer does not have to care about the surrondings and so do you. The only thing you should ensure is to <strong>not</strong> enqueue the operation in your <code>viewDidLoad</code> method. <code>viewDidLoad</code> has a very random execution behavior. <code>UIKit</code> does not gurantee you that this method is only called once. This method could get called multiple times, but the time depends on the current memory situation. Since iOS6 I have not seen this happen anymore, but it is still the documented way for this method! Anyway, this method basically tells you that your view needs to be configured. As we are dealing with a connection here and a connection deals with your model, this simply has nothing to do with your view being loaded, so don’t put it there!</p>
<p>Keep in mind: It is totally valid for a view controller to present another view controller several times instead of instantiating a new one each time! This is one of the reasons why your loading method should not care about the view state of your controlller. The fact that you are not doing this at the moment does not mean you – or anybody else, for that matter – will not do it in the future.</p>
<p>That being said, make sure to call your load method only once during the initial setup of your view controller. If you trigger a reload in <code>viewWillAppear:</code>, do not already start a request during initialization. That does not mean that you should only trigger your connection during the setup phase. It is totally valid to have a <code>reload</code> action the user can trigger or poll again after a certain timeout.</p>
<p>Make sure to keep a reference to the connection or the operation that you started to</p>
<ol>
<li>cancel it when dealloc is called</li>
<li>Check in <code>viewDidLoad</code> if you are still loading and present a loading indicator in that case</li>
</ol>
<p>In your completion handler you then check if your view has already been loaded and dismiss the loading indicator, if this was the case.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">@property</span> <span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">weak</span><span class="p">,</span> <span class="n">readwrite</span><span class="p">)</span> <span class="n">AFHTTPRequestOperation</span> <span class="o">*</span><span class="n">operation</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">initWithCoder:</span><span class="p">(</span><span class="n">NSCoder</span> <span class="o">*</span><span class="p">)</span><span class="nv">aDecoder</span> <span class="p">{</span>
</span><span class='line'> <span class="n">self</span> <span class="o">=</span> <span class="p">[</span><span class="n">super</span> <span class="nl">initWithCoder:</span><span class="n">aDecoder</span><span class="p">];</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="p">[</span><span class="n">self</span> <span class="n">loadDataIfNeeded</span><span class="p">];</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="k">return</span> <span class="n">self</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">instancetype</span><span class="p">)</span><span class="nf">initWithNibName:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">nibNameOrNil</span> <span class="nf">bundle:</span><span class="p">(</span><span class="n">NSBundle</span> <span class="o">*</span><span class="p">)</span><span class="nv">nibBundleOrNil</span> <span class="p">{</span>
</span><span class='line'> <span class="n">self</span> <span class="o">=</span> <span class="p">[</span><span class="n">super</span> <span class="nl">initWithNibName:</span><span class="n">nibNameOrNil</span> <span class="nl">bundle:</span><span class="n">nibBundleOrNil</span><span class="p">];</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="p">[</span><span class="n">self</span> <span class="n">loadDataIfNeeded</span><span class="p">];</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="k">return</span> <span class="n">self</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">loadDataIfNeeded</span> <span class="p">{</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">connection</span> <span class="o">||</span> <span class="n">self</span><span class="p">.</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="k">return</span><span class="p">;</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">isViewLoaded</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">// show loading indicator</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="n">self</span><span class="p">.</span><span class="n">operation</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span> <span class="nl">loadData:</span><span class="o">^</span><span class="p">(</span><span class="kt">id</span> <span class="n">data</span><span class="p">,</span> <span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">isViewLoaded</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">// hide loading indicator</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">// handle the error (e.g. present it)</span>
</span><span class='line'> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'> <span class="n">self</span><span class="p">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="p">;</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">}];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">viewDidLoad</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="p">[</span><span class="n">super</span> <span class="n">viewDidLoad</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">operation</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">// present loading indicator</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>If you use this and make your data property’s setter handle the reload as described in my post about <a href="http://ios-coding.com/blog/2014/06/22/model-handling-in-uiviewcontroller/">model handling in UIViewController</a>, you should be good to go with this approach.</p>
<p>By making your connection property <code>weak</code> when using <code>AFNetworking</code>, you have the benefit that as soon as your connection finished, it will be deallocated as the queue is no longer retaining it. With this trick you do not need to <code>nil</code> your property and you can easily check if a connection is already running.</p>
<h2>Conclusion</h2>
<p>No matter which of the described approaches you use, keep in mind that most of your users are in a bad network connection! Give them the ability to retry easily if the connection fails. Also try to make your connections state as easily detectable as possible. Your view controller should be able to handle a connection at every point in time, no matter if your UI is visible or not. If you follow this rule, you don’t have to worry about when to reload your data. You can always call <code>reloadDataIfNeeded</code>.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Custom error handling on iOS]]></title>
<link href="http://ios-coding.com/blog/2014/10/03/custom-error-handling-on-ios/"/>
<updated>2014-10-03T12:56:45+02:00</updated>
<id>http://ios-coding.com/blog/2014/10/03/custom-error-handling-on-ios</id>
<content type="html"><![CDATA[<p>In the last weeks I reimplemented the error handling of the HRS app in a way that is painless and very fast for the developer to use, and gives the user a good, detailed and specific error while even allowing him to recover from certain error cases. The way I did this was basically by reimplementing a concept that is available on OS X for a long time now.</p>
<!--more-->
<h2>tl;dr</h2>
<p>I have created a library that is open sourced and maintained by my company and me. It implements the workflow described below. You can use it under the Apache 2.0 License and it is available on <a href="https://github.com/Hotel-Reservation-Service/HRSCustomErrorHandling">github as HRSCustomErrorHandling</a> and via <a href="http://cocoapods.org/?q=HRSCustomErrorHandling">cocoapods</a>. If you do so, I would be happy if you’d let me know.</p>
<h2>Common error handling</h2>
<p>Error handling on iOS has always been very painful. In general you trigger an action on the users behalf in one of your view controllers and you might get an <code>NSError</code> in return. There are two common approaches to deal with this error:</p>
<ol>
<li>Display a generic error message to the user that says ‘Something went wrong. Please try again later.’</li>
<li>Have a huge block of code that checks the error domain and the error code every time an error can be returned and provide a custom error message to the most common error cases.</li>
</ol>
<p>The latter is definitely the better one as it gives the user a better feedback than ‘something went wrong’. However, it is a much bigger pain for the developer, so it is also the option that is rarely used.</p>
<h2>What is already out there?</h2>
<p>The approach I took was to first look up existing concepts. There is an error handling that is already available in iOS’s big brother, OS X, that reduces the code to display a custom error message to the user to a single line and also gives the user an option to recover from certain errors.</p>
<p>There already is a sample implementation of this error handling from the people over at <a href="http://realmacsoftware.com/blog/cocoa-error-handling-and-recovery">RealMac software</a>. However a couple of features are missing in their sample that I find very useful in the OS X version.</p>
<p>We wanted to have a way to handle specific errors in a custom and asynchronous way but at a central place in the app. Imagine a server connection that returns an error to you and tells you, that the user is not logged in to the server. You don’t want to simply tell the user that this is the case and you also don’t want to handle this with a specific dialog in every single part of your app that might be able to get this error. Instead there should be a single place in the application that checks for this error and displays your login dialog.</p>
<p>The error handling I am going to describe in this blog post can deal with this and a couple of other scenarios.</p>
<h2>Responsibilities</h2>
<p>Let’s first check which component of the app is responsible for what. Again, OS X is a good guideline for this.</p>
<h3>Creation</h3>
<p>Let’s imagine there is a method that creates an <code>NSError</code> instance and passes it to the caller. A method like <code>- (BOOL)save:(NSError **)error</code>. This method usually is somewhere in your data abstraction layer or in other frameworks. If this method is in your code, this is the place where you have as much context information available as possible. You know exactly why the error happened and what went wrong. You might even know what to do to make the error go away. This is the part of code that should put all these informations into the <code>NSError</code> when creating it.</p>
<h3>Handling</h3>
<p>The caller of the <code>save:</code> method mentioned above is your view controller in most of the cases. It is the one that knows what lead to the save action and – if there are any parameters to the method it called – it also knows what parameters have been used and what to do if this action should be executed a second time. This layer does not need to have any information about what went wrong. The only information it is interested in is ‘should I try this again or not?’.</p>
<p>There are a couple of rare cases where your view controller might also want to modify or skip error presentation. For example a login view controller might not want to display the general ‘your credentials are invalid’ error, instead it might want to show an inline error message close to the login screen’s input text fields to show the user that something went wrong. So there needs to be a way to customize error handling in view controllers.</p>
<h3>Displaying</h3>
<p>Displaying an error is a task that should be handled in general in an applcation. You do not want every error dialog to look different. You might want to show all your errors in a simple alert view or in a custom overlay that integrates nicely into your app’s ui, but they should all look the same.</p>
<h2>NSError</h2>
<p>How to create an <code>NSError</code> that has all the information mentioned above? The good thing is, <code>NSError</code> already has an interface to provide all this, and it is right in front of you: Have a look at the keys you can put into the <code>userInfo</code> dictionary of an <code>NSError</code>. There are a couple that are quite common when creating custom errors. The one that is used the most is probably <code>NSLocalizedDescriptionKey</code>. We are not going to use that – bummer.</p>
<p>Instead, we are going to use almost all of the others:</p>
<ul>
<li><p><code>NSLocalizedFailureReasonErrorKey</code><br/>
This describes what went wrong. This is going to be presented in the title of an alert view, later on.</p></li>
<li><p><code>NSLocalizedRecoverySuggestionErrorKey</code><br/>
This describes what the user can do to fix the error. For example you can tell the user something like <em>‘Try turning it off and on again’</em>, but also some more useful information like <em>‘Do you want to overwrite the existing file with your new one? This will delete the existing file permanently.’</em></p></li>
<li><p><code>NSLocalizedRecoveryOptionsErrorKey</code><br/>
This key should contain an <code>NSArray</code> with localized strings that describe the actions the user can take. Each element is used later on as the text of a button. You should make sure that this key contains at least one cancel operation that simply does nothing except dismissing the alert. A possible array could look like this: <code>@[ @"Overwrite", @"Cancel" ]</code><br/>
One important fact about this array is, that the first option in the array is the default option. This means that if you are going to present the error in an alert view, it is the option on the right most button that is displayed in bold text. In this case that would be the <em>‘Overwrite’</em> option, but be carefull when making a destructive operation the default one!</p></li>
<li><p><code>NSRecoveryAttempterErrorKey</code><br/>
Now this is the most interesting key. It contains an object that conforms to <code>NSErrorRecoveryAttempting</code> protocol. This protocol basically contains a method that can be called with the index of the option the user has choosen. The recovery attempter should then try to fullfil the action behind this option and report back whether it was able to recover from the error or not. If the recovery attempter was successful in recoverying from the error, it is safe for the presenter to retry the action that lead to the error.</p></li>
</ul>
<p>With the above keys we are able to carry all information that is necessary to handle an error case properly inside the <code>NSError</code> object that describes the error. Besides the information shown to the user we can also add logic to the error that can try to recover from an error and communicate back whether we can safely retry the action or not.</p>
<h2>Responder chain</h2>
<p>OS X is using the responder chain for handling and displaying the error. The responder chain is something that is rarely used in iOS by applications, yet it is used by the frameworks all the time. It is responsible for delivering actions like text input or motion gestures.</p>
<p>It is very useful for transporting information up to the application from every <code>UIResponder</code> object through out the app. The good think is: A lot of the objects you are dealing with on a daily basis are in fact inheriting from <code>UIResponder</code>. The one that is well known for being a responder is probably <code>UIView</code>. But all your <code>UIViewController</code>s are responder objects, as well. Even your <code>UIApplication</code> is a responder object, and in the case you are making a game, <code>SKNode</code> is one, too. This basically means that all your code that deals with presentation is a responder or has very easy access to a responder.</p>
<p>Another great feature about responders is, that they build a chain. Each responder object implements a method called <code>nextResponder</code> that returns the next responder in the chain. The chain is build from the deepest point in your application up to the application itself and also, since a couple of iOS releases, even up to your app delegate, as long as it inherits from <code>UIResponder</code>. This means you can dispatch a message to <code>nextResponder</code> recursively and it will end up in your app delegate eventually, which is a very great place to handle application wide behaviour such as presenting an error. And because of this, that is exactly what we are going to do.</p>
<h3>Handling</h3>
<p>OS X implements a method on <code>NSResponder</code> that is called <code>-presentError:</code> which returns a bool telling you whether error recovery was successful or not. Due to the fact that showing modal dialogs on OS X are a blocking operation, this method is blocking, too. Obviously, if you would do this in an iOS application your UI would not be responding anymore and your app would be killed by the watch dog very fast. Luckily we do have blocks now, so this method could easily be changed to something like <code>-presentError:completionHandler:</code>.</p>
<p>The completion handler should then tell you whether error recovery was successful or not. If it was, you can simply call the method that lead to the error again. As blocks hold on to their context, this can be done very easily in most scenarios.</p>
<p>You need to implement the present error method yourself, as it is not available on iOS, but it is very simple. You could either use the github project I created or do this yourself. All the method does, is calling <code>-presentError:completionHandler:</code> on the object returned by <code>-nextResponder</code>. Well, not all. There are a couple of exceptions. Before it does forward the message up the responder chain it calls <code>willPresentError:</code> on itself.</p>
<h4><code>-willPresentError:</code></h4>
<p>This method gets the error passed in and returns an error. The base implementation of this method simply returns the error it was passed. You can now override this method to change the error you return or even return <code>nil</code>. If you return <code>nil</code>, the error is not forwarded up the responder chain by <code>presentError:completionHandler:</code>.</p>
<p>You can use this to solve the problem mentioned in the introduction. Your login view controller simply overrides <code>willPresentError:</code>, checks if the error passed in is a login error, and returns <code>nil</code> in this case. With this hook, every responder in the chain is capable of modifying the error or even stopping the error presentation.</p>
<h4><code>UIViewController</code></h4>
<p>Another exception in <code>-presentError:completionHandler:</code> is that it forwards the message to <code>-[UIApplication sharedApplication]</code> if calling <code>nextResponder</code> returns <code>nil</code>. This is because a <code>UIViewController</code> that is currently not participating in the view controller hierarchy will return <code>nil</code> when asked for its <code>nextResponder</code>.</p>
<h4>App Delegate</h4>
<p>There is one thing I simply dropped up to now: The errors you get from a framework you are using do not contain the informations you need for the custom error presentation. To upgrade these errors to enriched ones, you can once again override <code>-willPresentError:</code>, but this time do it in your app delegate. Now you have a place where you can add nice error messages to your most common framework errors. You should also add a fallback error message that probably simply tells the user that <em>‘something went wrong’</em>. That is not a very good error message, but it is for sure better than showing the user a <em>‘The operation couldn’t be completed. (Cocoa error 1570.)’</em>.</p>
<h2>Presenting</h2>
<p>Now that we ensured that your error will get passed to your app delegate, all you have to do is to override <code>-presentError:completionHandler:</code> in your app delegate and configure a <code>UIAlertView</code> or any other custom view that can show the error to the user. In this single place you can easily customize your error UI to fit perfectly into your app design. No more ugly default alert views in your nicely crafted user interface!</p>
<h2>HRSCustomErrorHandling</h2>
<p>I have open sourced the little library that is driving the error handling in the HRS iOS app I am working on during the day. It has a couple of nice little features that make your error creation even easier. For example you can simply create a recovery attempter with recovery blocks that are executed once the user taps on an option in the alert view. It is available under the Apache 2.0 License on <a href="https://github.com/Hotel-Reservation-Service/HRSCustomErrorHandling">github as HRSCustomErrorHandling</a> and via <a href="http://cocoapods.org/?q=HRSCustomErrorHandling">cocoapods</a>. If you use it, I would be happy if you’d let me know.</p>
<p>I also gave a talk about custom error handling. The slides are available in the <a href="http://ios-coding.com/talks/">talks</a> section.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Model handling in UIViewController]]></title>
<link href="http://ios-coding.com/blog/2014/06/22/model-handling-in-uiviewcontroller/"/>
<updated>2014-06-22T12:56:25+02:00</updated>
<id>http://ios-coding.com/blog/2014/06/22/model-handling-in-uiviewcontroller</id>
<content type="html"><![CDATA[<p>This is the first post in a series of posts about <code>UIViewController</code> subclassing best practices I got used to. This series is about how to write a robust view controller that is as dynamic as possible and can be easily adopted to new technices you might use in your app in the future for whatever reason. E.g. you might have handled you view controller instantiation in code in the past but then decided to do it with storyboards; or you might change your underlying connection handling; or you might change from an <code>NSObject</code> based model structure to Core Data. These are all cases that will end up in a big refactoring of your view controllers if you don’t be careful when implementing them. I did all these things with view controllers that where build with the best practices I am going to describe in this series, and most of the time I didn’t even had to change a single line of code in my view controllers.</p>
<!--more-->
<p>In my experience, developers tend to be sloppy when implementing view controllers from time to time. It seems like many people are thinking about view controllers as the passive part that only needs to forward certain events to various layers in your app. The truth is, view controllers are actually one of the most active parts in your app. They need to decide what to do in certain situations and always need to have a proper overview of the state of the application. Therefore it is very important to have a clean structure in your controllers. Once I got used to this structure, I even got faster in implementing my view controllers.</p>
<p>In today’s post I want to talk about proper model handling and how to keep your view controllers clean and reusable, even if you decide to refactor one of the more fundamental parts of your app, like the initialization of your view controllers.</p>
<h2>Controller initialization</h2>
<p>tldr; Do not write custom init methods.</p>
<p>It is as simple as that! There are lots of reasons why not to do this. The most obvious reason is, you loose the option to initialize your view controllers from a xib or a storyboard. Even though this is nothing you might consider at the moment, this is something that could change completely in the future. Apple is very good in making up new things you end up not knowing how you could have ever lived without them. If there will be a new feature you want to use, and it is implemented in Interface Builder, you have to use <code>initWithCoder:</code>. So make sure, your view controllers work with all designated initializers!</p>
<p>Most custom initialization methods I came across are used to hand over the model that should be displayed to the view controller. Sometimes you might want to pass a couple of parameters to the controller. In general, these models or parameters end up in a property at some point. Expose these properties or add a configuration method to your view controllers. Your view controller does not need a model to exist; really! It might need a model from a product point of view, but not from a technical. All the labels, buttons, text fields and other controls you have in your controller can render without the model. A label might be empty, a text field might not change a text inside your model, but your view controller does not crash. Put an assert inside <code>viewDidLoad</code> if you are afraid you might end up with a broken view controller, but in general: Handle these kind of guards in your data flow. Do not enforce things technically that are not technically necessary!</p>
<h2>View initialization</h2>
<p>tldr; Do not override <code>loadView</code>; create an update method for your models and call it in <code>viewDidLoad</code>.</p>
<p>You are loosing the option to initialize your views from a xib file. Interface Builder is the best WYSIWYG UI editor I have worked with, so far. And it is getting better every year. I am pretty confident, that you will end up using it one day, even if you don’t at the moment.</p>
<p>In my eyes, the only reason to override <code>loadView</code> is to have a custom view controller whoes view property is something else than <code>UIView</code> or <code>UITableView</code>. You could write a <code>MyScrollViewController</code> class, whoes main view is a <code>UIScrollView</code>. Of course you could also add a scroll view as a subview to the main view in <code>viewDidLoad</code>, but if you want to implement your view controller in analogy to <code>UITableViewController</code> this is a valid argument to me, but be aware of the ramifications.</p>
<p>The more common case is, that you only want to setup the subviews. Setting your UI state to match your model can be done in <code>viewDidLoad</code> without any negative impact vs. doing it in <code>loadView</code>. In fact you should split up your view creation code from your view configuration code. Build your view hierarchy in <code>viewDidLoad</code> if you are not using interface builder. This will make sure that every time the main view is instanciated, the view hierarchy is set up accordingly.</p>
<p>Add a method <code>updateViewWithCurrentModel</code>, put your configuration code in there and call this method from <code>viewDidLoad</code> after setting up the view hierarchy. With this approach you have a stateless method that always configures your view according to your current model, regardless of when you call it. We will make use of this benefit in the next step.</p>
<p>Do not setup your view hierarchy in <code>viewWillAppear:</code>! I have seen this a couple of times; in the best case you will create new views even though this is not needed. In the worst case you will end up with a view hierarchy where every subview exists multiple times because you did not remove the old views properly.</p>
<h2>Custom setter</h2>
<p>tldr; implement a custom setter for your model and call your update method in it.</p>
<p>You can do the next step either by implementing KVO or through a custom setter. I tend to use a custom setter for mainly two reasons. First, there is not very much you can do wrong in a setter since the existence of ARC and second, I don’t like the fact that it is not save to call super in <code>observeValueForKeyPath:ofObject:change:context:</code> as you need an inside of your superclass that – in my opinion – is non of your bussiness. However if you like KVO better, do it with KVO.</p>
<p>Implement the setter of the property you exposed in the first step yourself (or watch it with KVO). Write your own <code>setMyModel:</code> method, update the ivar and call your <code>updateViewWithCurrentModel</code> method in there if your view is loaded. If your view is not loaded, only set your ivar. As you are calling the <code>updateViewWithCurrentModel</code> in <code>viewDidLoad</code> as well, you don’t have to worry about this when your view is not loaded. Your setter should look like this:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">setMyModel:</span><span class="p">(</span><span class="n">MyModel</span> <span class="o">*</span><span class="p">)</span><span class="nv">myModel</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="n">_myModel</span> <span class="o">=</span> <span class="n">myModel</span><span class="p">;</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">isViewLoaded</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="p">[</span><span class="n">self</span> <span class="n">updateViewWithCurrentModel</span><span class="p">];</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>In case you are in a <code>UITableViewController</code> you propably don’t need an update method. Simply call <code>reloadData</code> on your table view instead, but still make sure, the main view is loaded!</p>
<p>It is important to check whether your view is loaded or not. As the setter can be called by anyone at any time, a call to <code>self.view</code> could cause the view to load even though it is not displayed, which is a memory overhead that is completely useless. A view controller should only load its view when told so by its parent view controller. You should always check if a view is loaded in every method that is exposed in your public controller api before calling <code>self.view</code> or any method that does this internally.</p>
<h2>Asynchronous loading</h2>
<p>With the above view controller design you will get another benefit: If you are loading data asynchronously, you do not need a complex state machine anymore. All you need to do is set your model after the loading is done and your view controller will do the rest. I would recommend loading the data in the previous view controller anyway, but that is a topic I will handle in the next post about <code>UIViewController</code> subclassing.</p>
<h2>Resources</h2>
<p>I uploaded a basic template for a new view controller as <a href="https://gist.github.com/michaelochs/a034f7dfddf1e6f3e1fa">MyViewController.h/m</a> to gist. You could easily create an Xcode template from this or generate custom Xcode snippets if you like.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[An improved way to integrate Reveal into your Xcode project]]></title>
<link href="http://ios-coding.com/blog/2013/11/23/an-improved-way-to-integrate-reveal-into-your-xcode-project/"/>
<updated>2013-11-23T14:06:00+01:00</updated>
<id>http://ios-coding.com/blog/2013/11/23/an-improved-way-to-integrate-reveal-into-your-xcode-project</id>
<content type="html"><![CDATA[<p>Oliver Jones had a great article at the Itty Bitty Apps Blog about how to ‘<a href="http://blog.ittybittyapps.com/blog/2013/11/07/integrating-reveal-without-modifying-your-xcode-project">Integrating Reveal without modifying your Xcode project</a>’ that was also featured in <a href="http://iosdevweekly.com/issues/120" title="iOS Dev Weekly Issue #120">iOS dev weekly</a>. Reveal is a great tool to debug layout issues. I highly encourage everybody to <a href="http://revealapp.com" title="Reveal website">check it out</a>. It improves debugging UI related issues like <code>UIView</code> position and clipping or <code>CALayer</code> ordering and really makes your life easier. Oliver’s blog post explained a great way to integrate Reveal into your Xcode project without linking it automatically and without having it automatically starting up during app start. There are a couple of benefits with this approach.</p>
<!--more-->
<p>As the library is not linked automatically it is not discovered by Apple’s static analyzer. This is great in the case that you forget to remove it before submitting to the App Store. I don’t know if the Reveal library contains private APIs, but as it is a library that is meant to be used during development, I would consider this a possibility, if not at the moment maybe in the future.</p>
<p>The other benefit is that, as the Reveal service is not automatically run at app launch, you can debug your app without interference of the library and only fire up the library when you really need it. In the case you forget to remove it before the App Store build, people that get your app through the App Store still are not able to analyze your view hierarchy with Reveal.</p>
<p>A third great improvement is very useful for all the people that are working in a big office with dozens of other developers. If you have the Reveal library enabled in every build everybody makes, it becomes quite a challenge to select the right device in Reveal. You only want the Reveal service up and running when you really want to debug something.</p>
<p>Oliver used the LLDB init file <code>~/.lldbinit</code> to add a couple of aliases to load and start the Reveal library from the debugger:</p>
<ul>
<li><code>reveal_load_sim</code> – loads the Reveal library in the iOS simulator</li>
<li><code>reveal_load_dev</code> – loads the Reveal library on the device</li>
<li><code>reveal_start</code> – starts the Reveal library</li>
<li><code>reveal_stop</code> – stops the Reveal library</li>
</ul>
<p>However there are a couple of issues with the described approach that bothered me and that don’t work very well with the workflow we have in the company I work at:</p>
<p>You still need to add the library to the copy step of your project file. Chances are high that you forget to remove this before running the App Store build. Even though the library is neither linked nor started automatically you don’t want a library that you don’t need and that increases your app by almost 4MB in your App Store ipa. This might make the difference between being downloadable through WiFi only or not. Besides that, it looks unprofessional in the case someone discovers this and it might open some security threads you don’t think of.</p>
<p>When adding the library to your copy step you have two options: Use the library that is located in the <code>Reveal.app</code> folder or copy it to your project. In the first case you break the build process for everybody that doesn’t have Reveal installed as the file will not be in the place where Xcode is looking for it. With the second approach you will run in to problems when different engineers have different versions of Reveal on their machines. it is pretty likely anyway that you will forget to update the library in the first place and only notice this when you really need it. Updating the library requires you to stop the running application and rebuild it after you updated the library. This reduces the benefit of the automatic approach dramatically.</p>
<p>Last but not least I don’t want to have two load commands, <code>reveal_load_sim</code> and <code>reveal_load_dev</code>. This is more complicated than it should be. The debugger should be able to figure that out by itself or at best use the exact same approach on the device and simulator.</p>
<h2>reveal_load</h2>
<p>Let’s try to fix that little inconvenience first. With Oliver’s approach we use the following aliases:</p>
<figure class='code'><figcaption><span>~/.lldbinit </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>command alias reveal_load_sim expr (void*)dlopen("/Applications/Reveal.app/Contents/SharedSupport/iOS-Libraries/libReveal.dylib", 0x2);
</span><span class='line'>command alias reveal_load_dev expr (void*)dlopen([(NSString*)[(NSBundle*)[NSBundle mainBundle] pathForResource:@"libReveal" ofType:@"dylib"] cStringUsingEncoding:0x4], 0x2);</span></code></pre></td></tr></table></div></figure>
<p>The first alias is <code>reveal_load_sim</code>. It loads the Reveal library from the <code>Reveal.app</code> folder. This is a path that you obviously can only reach in the simulator. The second alias, <code>reveal_load_dev</code>, loads the <code>libReveal.dylib</code> from the application bundle. This only works when you add the library to your copy step before.</p>
<p>When you need to copy and update the library manually within your project it is quite helpful to be able to use Reveal in the simulator without copying the library first. As we try to improve this behavior in the next step anyway, let’s simply remove the <code>reveal_load_sim</code> macro and rename <code>reveal_load_dev</code> to <code>reveal_load</code>. Our complete list of Reveal aliases in the <code>~/.lldbinit</code> now looks like this:</p>
<figure class='code'><figcaption><span>~/.lldbinit </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>command alias reveal_load expr (void*)dlopen([(NSString*)[(NSBundle*)[NSBundle mainBundle] pathForResource:@"libReveal" ofType:@"dylib"] cStringUsingEncoding:0x4], 0x2);
</span><span class='line'>command alias reveal_start expr (void)[(NSNotificationCenter*)[NSNotificationCenter defaultCenter] postNotificationName:@"IBARevealRequestStart" object:nil];
</span><span class='line'>command alias reveal_stop expr (void)[(NSNotificationCenter*)[NSNotificationCenter defaultCenter] postNotificationName:@"IBARevealRequestStop" object:nil];</span></code></pre></td></tr></table></div></figure>
<h2>Using a script instead of the copy phase</h2>
<p>Now that we optimized the load command let’s make sure that we always have the library version that our currently installed version of Reveal needs and that Reveal is not included if it is not available on the machine that is performing the build. Instead of adding the framework to the copy step we simply use a ‘run script’ phase in our build progress to copy the framework into the .app folder. This script can check for the configuration you are currently building and wether the framework exists in the <code>Reveal.app</code> folder.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">APPBUNDLEPATH</span><span class="o">=</span><span class="s2">"${TARGET_BUILD_DIR}/${EXECUTABLE_NAME}.app/"</span>
</span><span class='line'><span class="nv">REVEALFRAMEWORKPATH</span><span class="o">=</span><span class="s2">"/Applications/Reveal.app/Contents/SharedSupport/iOS-Libraries/libReveal.dylib"</span>
</span><span class='line'><span class="k">if</span> <span class="o">[</span> -f <span class="s2">"${REVEALFRAMEWORKPATH}"</span> <span class="o">]</span> <span class="o">&&</span> <span class="o">[</span> <span class="s2">"${CONFIGURATION}"</span> !<span class="o">=</span> <span class="s2">"ReleaseAppStore"</span> <span class="o">]</span>; <span class="k">then</span>
</span><span class='line'><span class="k"> </span>cp <span class="s2">"${REVEALFRAMEWORKPATH}"</span> <span class="s2">"${APPBUNDLEPATH}"</span>
</span><span class='line'><span class="k">fi</span>
</span></code></pre></td></tr></table></div></figure>
<p>The first line defines the path to the .app folder of the application we are building. The second line defines the location of the <code>libReveal.dylib</code> file if you have a standard Reveal installation. Now we only have to perform two checks:</p>
<ul>
<li><em>Does the libReveal.dylib file exist?</em> This is the first part of the condition and makes sure the build is successful on machines that do not have Reveal installed or where Reveal is installed in a different location.</li>
<li><em>Is the configuration we are currently building NOT <code>ReleaseAppStore</code>?</em> This is the configuration we are using for App Store distribution. You might need to change this to meet your environment. Maybe you are simply using the default <code>Release</code> build for App Store distribution or maybe you have another configuration name. Simply replace <code>ReleaseAppStore</code> to whatever configuration you are using. This ensures that the library is only copied when you are not building for the App Store.</li>
</ul>
<p>If you save this file somewhere in your project path, all you have to do is add a ‘run script’ phase to your project and call this project by inserting the following line in the phase:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>bash <span class="s2">"MyProject/Supporting Files/lazy-copy-reveal.sh"</span>
</span></code></pre></td></tr></table></div></figure>
<p>Adjust this path to meet your environment and you are ready to go.</p>
<p>With this script and the above LLDB aliases everybody that has Reveal installed can simply pause the application at any time in the debugger and simply type <code>reveal_load</code> followed by <code>reveal_start</code>. After that, don’t forget to resume your application. You can now immediately attach Reveal to your device. The library that is used in your project will automatically stay up to date with your Reveal version and you don’t have to change anything in your project before submitting to the App Store.</p>
<p>I am only using this approach for a couple of days now and it has already been very useful as you can fire up Reveal anytime you have a UI issue without the need of restarting the application and reproducing the bug first.</p>
<p>I uploaded the two files you need to gist in the case you want to simply copy them:</p>
<ul>
<li><code>.lldbinit</code>: <a href="https://gist.github.com/michaelochs/7614557" title=".lldbinit on gist">https://gist.github.com/michaelochs/7614557</a></li>
<li><code>lazy-copy-reveal.sh</code>: <a href="https://gist.github.com/michaelochs/7614574" title="lazy-copy-reveal.sh on gist">https://gist.github.com/michaelochs/7614574</a></li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Drawing buttons with blurred background]]></title>
<link href="http://ios-coding.com/blog/2013/05/09/drawing-buttons-with-blurred-background/"/>
<updated>2013-05-09T17:25:00+02:00</updated>
<id>http://ios-coding.com/blog/2013/05/09/drawing-buttons-with-blurred-background</id>
<content type="html"><![CDATA[<p>A glossy looking button is a well known and widely used type of button that everybody knows if he or she hasn’t been on the moon the last couple of years. Apple uses these buttons excessive. In OS X as well as on iOS. Those buttons look nice and they work very well when trying to achieve a polished, three dimensional look. However, they are always used with a background color that differs from the surrounding background or the surrounding background doesn’t have much detail. This is because if you use this button on a background that has a lot of detail, like a photo, they don’t look like glass anymore, at all. The button looks very flat if you can see, that the background isn’t distorted by the ‘glass’ in any kind.</p>
<!-- more -->
<h2>CoreImage</h2>
<p>The solution to this problem sounds quite easy at first: As soon as you simply blur the background just a little, the whole thing starts looking great again. This is where CoreImage comes in handy. CoreImage has a ton of useful filters, one of them is a gaussian blur filter. Using this filter is pretty easy. All you need to do is specify you input image and the blur radius you would like to use.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">CIFilter</span><span class="o">*</span> <span class="n">blur</span> <span class="o">=</span> <span class="p">[</span><span class="n">CIFilter</span> <span class="nl">filterWithName:</span><span class="s">@"CIGaussianBlur"</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="n">blur</span> <span class="nl">setValue:</span><span class="err">@</span><span class="p">(</span><span class="n">blurRadius</span><span class="p">)</span> <span class="nl">forKey:</span><span class="s">@"inputRadius"</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="n">blur</span> <span class="nl">setValue:</span><span class="n">inputImage</span> <span class="nl">forKey:</span><span class="s">@"inputImage"</span><span class="p">];</span>
</span><span class='line'><span class="n">CIImage</span><span class="o">*</span> <span class="n">outputImage</span> <span class="o">=</span> <span class="p">[</span><span class="n">blur</span> <span class="n">outputImage</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>
<p><em>Note that you are dealing with <code>CIImage</code>’s instead of <code>UIImage</code>’s. So <code>inputImage</code> has to be a <code>CIImage*</code>.</em></p>
<h2>What to blur?</h2>
<p>Now that we know how to blur, the question would be: What to blur? And here is the point where things are getting difficult. There are three methods on CALayer that sound promising:</p>
<ul>
<li><code>setBackgroundFilters:</code> <em>“An array of Core Image filters to apply to the content immediately behind the layer”</em></li>
<li><code>setFilters</code>: <em>“An array of Core Image filters to apply to the contents of the layer and its sublayers”</em></li>
<li><code>setCompositingFilter</code>: <em>“A CoreImage filter used to composite the layer and the content behind it”</em></li>
</ul>
<p>All three methods are available on iOS, you can call them, the filters are set and they will be returned if you call the getter. But that’s pretty much all these methods do, at least up to iOS6. Under <em>“special considerations”</em> Apple says <em>“This property is not supported on layers in iOS”</em>. Note that there was an error in the documentation on iOS 6.0, where it said <em>“This property relies on the presence of Core Image and its filters. In iOS, Core Image is available in iOS 5 and later only”</em>. They changed this in the iOS 6.1 documentation, so don’t wonder if you see the second text, you selected the <em>old</em> version of the <code>CALayer</code> documentation.</p>
<p>So using one of these properties won’t work on iOS. The only other approach I am aware of on iOS, is to render the underlaying layers into a context and blur it yourself. You can do this with <code>CALayer</code> again. The method you are looking for is <code>-[CALayer renderInContext:]</code></p>
<p>This method renders the receiver and it’s sublayers to the context you specify. ‘But I want to render the views!’ you might think. That’s correct, but <code>UIView</code> is just the delegate of the underlying layer. Each <code>UIView</code> has a layer it is responsible for and the layer hierarchy is the same as the view hierarchy – unless you change something about this by yourself. The visible part of a <code>UIView</code> is the <code>CALayer</code>! If a view has five subviews, its layer has five sublayers and each of these sublayers belong to one of the subviews.</p>
<h2>Drawing</h2>
<p>To render the background of the button we want to blur, we simply walk up the view hierarchy until we find the first view that is opaque. If the view is opaque we can safely render this view and its subviews without worrying about transparent parts from underlaying views.</p>
<p>To achieve this, we create a new graphics context in the size of the button that should get the blurred background. We don’t need to render the whole superview we just found, as we only need to blur the part that is behind our button. The rendered image is what we will use as our input image for the blur filter. Don’t forget to hide the button during rendering, otherwise the button itself will be contained in the button’s background.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">self</span><span class="p">.</span><span class="n">hidden</span> <span class="o">=</span> <span class="n">YES</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="n">CGRect</span> <span class="n">renderRect</span> <span class="o">=</span> <span class="p">[</span><span class="n">viewToRender</span> <span class="nl">convertRect:</span><span class="n">rect</span> <span class="nl">fromView:</span><span class="n">self</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="n">UIGraphicsBeginImageContext</span><span class="p">(</span><span class="n">rect</span><span class="p">.</span><span class="n">size</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="n">CGContextTranslateCTM</span><span class="p">(</span><span class="n">UIGraphicsGetCurrentContext</span><span class="p">(),</span> <span class="o">-</span><span class="n">CGRectGetMinX</span><span class="p">(</span><span class="n">renderRect</span><span class="p">),</span> <span class="n">CGRectGetMaxY</span><span class="p">(</span><span class="n">renderRect</span><span class="p">));</span>
</span><span class='line'><span class="n">CGContextScaleCTM</span><span class="p">(</span><span class="n">UIGraphicsGetCurrentContext</span><span class="p">(),</span> <span class="mf">1.0f</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.0f</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="p">[</span><span class="n">viewToRender</span><span class="p">.</span><span class="n">layer</span> <span class="nl">renderInContext:</span><span class="n">UIGraphicsGetCurrentContext</span><span class="p">()];</span>
</span><span class='line'>
</span><span class='line'><span class="n">CGImageRef</span> <span class="n">blurInputReference</span> <span class="o">=</span> <span class="p">[</span><span class="n">UIGraphicsGetImageFromCurrentImageContext</span><span class="p">()</span> <span class="n">CGImage</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="n">UIGraphicsEndImageContext</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="n">self</span><span class="p">.</span><span class="n">hidden</span> <span class="o">=</span> <span class="n">NO</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>
<p>After rendering the view into a <code>CGImage</code> we convert this to a <code>CIImage</code> and set it as the input image of our blur filter. If you put all this code into your button’s <code>drawInRect:</code> method, you can then draw the output image into the current context for displaying. After that, you can call all the other drawing code, if any, you need for your button.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">CIImage</span><span class="o">*</span> <span class="n">inputImage</span> <span class="o">=</span> <span class="p">[</span><span class="n">CIImage</span> <span class="nl">imageWithCGImage:</span><span class="n">blurInputReference</span><span class="p">];</span>
</span><span class='line'><span class="n">CGImageRef</span> <span class="n">blurOutput</span> <span class="o">=</span> <span class="p">[</span><span class="n">context</span> <span class="nl">createCGImage:</span><span class="n">outputImage</span> <span class="nl">fromRect:</span><span class="n">outputImage</span><span class="p">.</span><span class="n">extent</span><span class="p">];</span>
</span><span class='line'><span class="n">CGContextDrawImage</span><span class="p">(</span><span class="n">UIGraphicsGetCurrentContext</span><span class="p">(),</span> <span class="n">outputImage</span><span class="p">.</span><span class="n">extent</span><span class="p">,</span> <span class="n">blurOutput</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<p><em>Not that we render the output image with the extent of the <code>CIImage</code> as the blur filter will return an image that is larger than your input image. The extent property of you output image has a negative origin so that rendering the image with this extent will place your image exactly above your input image, with a border.</em></p>
<h2>BCBlurView on GitHub</h2>
<p>I have set up a <a href="https://github.com/michaelochs/BCBlurView" title="BCBlurView on github">GitHub project</a> that adds a method to <code>UIView</code> that renders the view’s background with a given blur radius into the current context. You can call this method on any UIView in it’s <code>drawRect:</code> method to get a blurred background. The static library also contains two subclasses, one of UIView and one of UIButton. Those adopt this category and, aside from others, make the blur radius available as a property for easier use.</p>
<h2>Special considerations</h2>
<p>This approach only works with still backgrounds. If you have any kind of animation in the background, this will not work. If the background changes, you have to call <code>setNeedsDisplay</code> on the view that has the blurred background. Note that blurring takes time, it is not possible to e.g. put a <code>UIScrollView</code> in the back of the button and call <code>setNeedsDisplay</code> on every scroll position change of the scroll view.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Welcome]]></title>
<link href="http://ios-coding.com/blog/2013/05/05/welcome/"/>
<updated>2013-05-05T18:26:00+02:00</updated>
<id>http://ios-coding.com/blog/2013/05/05/welcome</id>
<content type="html"><![CDATA[<p>Welcome to ios-coding! My name is Michael Ochs, I am an iOS software engineer working in Cologne. This blog will deal with iOS development and things Apple does, from a developers perspective. I am writing about open source projects I use or participate in and about code samples I find useful during my work. I hope you will find useful ideas and tips on this blog and enjoy reading it. If you want to find out more about myself, check out the <a href="http://ios-coding.com/about">about page</a>.</p>
]]></content>
</entry>
</feed>