-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
634 lines (474 loc) · 83.1 KB
/
atom.xml
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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Code Craftsman</title>
<link href="https://code-craftsman.fr/atom.xml" rel="self"/>
<link href="https://code-craftsman.fr/"/>
<updated>2019-02-15T09:12:39+01:00</updated>
<id>https://code-craftsman.fr</id>
<author>
<name>Sébastien Duperron</name>
</author>
<entry>
<title>Generating the struct's initializer</title>
<link href="https://code-craftsman.fr/2017/09/24/AutoInit/"/>
<updated>2017-09-24T00:00:00+02:00</updated>
<id>https://code-craftsman.fr/2017/09/24/AutoInit</id>
<content type="html"><h1 id="struct-default-initializer"><code class="highlighter-rouge">struct</code> default initializer</h1>
<p>Swift has an awesome feature regarding <code class="highlighter-rouge">struct</code>s and their initializer. By default, an initializer is generated so you can create your <code class="highlighter-rouge">struct</code> with the content you want:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">struct</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="kd">public</span> <span class="k">let</span> <span class="nv">familyName</span><span class="p">:</span> <span class="kt">String</span>
<span class="kd">public</span> <span class="k">let</span> <span class="nv">givenName</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>
<span class="k">let</span> <span class="nv">superDupont</span> <span class="o">=</span> <span class="kt">Person</span><span class="p">(</span><span class="nv">familyName</span><span class="p">:</span> <span class="s">"Dupont"</span><span class="p">,</span> <span class="nv">givenName</span><span class="p">:</span> <span class="s">"Super"</span><span class="p">)</span>
</code></pre>
</div>
<p>You can do this as long as you are in the same module.<br />
However, if you try to instanciate the <code class="highlighter-rouge">struct</code> from outside the module you’ll have this error:</p>
<p><code class="highlighter-rouge">'Person' initializer is inaccessible due to 'internal' protection level</code></p>
<p>As indicated, it’s because the <code class="highlighter-rouge">init</code> is <code class="highlighter-rouge">internal</code>, even if you’ve marked your <code class="highlighter-rouge">struct</code> as <code class="highlighter-rouge">public</code> like above.</p>
<p>Your only solution to access it is to write your own public initializer:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">struct</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="kd">public</span> <span class="k">let</span> <span class="nv">familyName</span><span class="p">:</span> <span class="kt">String</span>
<span class="kd">public</span> <span class="k">let</span> <span class="nv">givenName</span><span class="p">:</span> <span class="kt">String</span>
<span class="kd">public</span> <span class="nf">init</span><span class="p">(</span><span class="nv">familyName</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="nv">givenName</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">familyName</span> <span class="o">=</span> <span class="n">familyName</span>
<span class="k">self</span><span class="o">.</span><span class="n">givenName</span> <span class="o">=</span> <span class="n">givenName</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>And now you have one more problem: you need to update this code every time your <code class="highlighter-rouge">struct</code> changes.</p>
<p>Wouldn’t it be great if we did not have to write and maintain this code?</p>
<h1 id="sourcery-to-the-rescue">Sourcery to the rescue</h1>
<p><a href="https://github.com/krzysztofzablocki/Sourcery"><code class="highlighter-rouge">Sourcery</code></a> is a code generation tool using <code class="highlighter-rouge">SourceKit</code> which has several cool features to use in ths case:</p>
<ul>
<li>source annotations</li>
<li>inline insertion of generated code</li>
</ul>
<p>I have written a template to generate the <code class="highlighter-rouge">init</code> method of annotated <code class="highlighter-rouge">struct</code>s.
Here is how this works:</p>
<h2 id="1-annotate-the-struct">1. Annotate the struct</h2>
<p>You add <code class="highlighter-rouge">// sourcery: AutoInit</code> just before your declaration:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="c1">// sourcery: AutoInit</span>
<span class="kd">public</span> <span class="kd">struct</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="kd">public</span> <span class="k">let</span> <span class="nv">familyName</span><span class="p">:</span> <span class="kt">String</span>
<span class="kd">public</span> <span class="k">let</span> <span class="nv">givenName</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>
</code></pre>
</div>
<h2 id="2-add-autoinitstencil-to-your-sourcery-templates">2. Add <code class="highlighter-rouge">AutoInit.stencil</code> to your Sourcery templates</h2>
<p>Create a <code class="highlighter-rouge">AutoInit.stencil</code> file in your Sourcery templates folder with the following content:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="p">{</span><span class="o">%</span> <span class="k">for</span> <span class="n">type</span> <span class="k">in</span> <span class="n">types</span><span class="o">.</span><span class="n">structs</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{</span><span class="o">%</span> <span class="k">if</span> <span class="n">type</span><span class="o">|</span><span class="nv">annotated</span><span class="p">:</span><span class="s">"AutoInit"</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{</span><span class="o">%</span> <span class="k">set</span> <span class="n">spacing</span> <span class="o">%</span><span class="p">}{</span><span class="o">%</span> <span class="k">if</span> <span class="n">type</span><span class="o">.</span><span class="n">parentName</span> <span class="o">%</span><span class="p">}</span> <span class="p">{</span><span class="o">%</span> <span class="n">endif</span> <span class="o">%</span><span class="p">}{</span><span class="o">%</span> <span class="n">endset</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{</span><span class="o">%</span> <span class="n">map</span> <span class="n">type</span><span class="o">.</span><span class="n">storedVariables</span> <span class="n">into</span> <span class="n">parameters</span> <span class="n">using</span> <span class="kd">var</span> <span class="o">%</span><span class="p">}{{</span> <span class="kd">var</span><span class="o">.</span><span class="n">name</span> <span class="p">}}:</span> <span class="p">{{</span> <span class="kd">var</span><span class="o">.</span><span class="n">typeName</span> <span class="p">}}{</span><span class="o">%</span> <span class="n">endmap</span> <span class="o">%</span><span class="p">}</span>
<span class="c1">// sourcery:inline:auto:{{ type.name }}.AutoInit</span>
<span class="p">{{</span><span class="n">spacing</span><span class="p">}}</span> <span class="p">{{</span> <span class="n">type</span><span class="o">.</span><span class="n">accessLevel</span> <span class="p">}}</span> <span class="nf">init</span><span class="p">({{</span> <span class="n">parameters</span><span class="o">|</span><span class="n">join</span> <span class="p">}})</span> <span class="p">{</span> <span class="c1">// swiftlint:disable:this line_length</span>
<span class="p">{{</span><span class="n">spacing</span><span class="p">}}</span> <span class="p">{</span><span class="o">%</span> <span class="k">for</span> <span class="n">variable</span> <span class="k">in</span> <span class="n">type</span><span class="o">.</span><span class="n">storedVariables</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{{</span><span class="n">spacing</span><span class="p">}}</span> <span class="k">self</span><span class="o">.</span><span class="p">{{</span> <span class="n">variable</span><span class="o">.</span><span class="n">name</span> <span class="p">}}</span> <span class="o">=</span> <span class="p">{{</span> <span class="n">variable</span><span class="o">.</span><span class="n">name</span> <span class="p">}}</span>
<span class="p">{{</span><span class="n">spacing</span><span class="p">}}</span> <span class="p">{</span><span class="o">%</span> <span class="n">endfor</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{{</span><span class="n">spacing</span><span class="p">}}</span> <span class="p">}</span>
<span class="c1">// sourcery:end</span>
<span class="p">{</span><span class="o">%</span> <span class="n">endif</span> <span class="o">%</span><span class="p">}</span>
<span class="p">{</span><span class="o">%</span> <span class="n">endfor</span> <span class="o">%</span><span class="p">}</span>
</code></pre>
</div>
<p>This template is also available as a <a href="https://gist.github.com/Liquidsoul/efa4f65af055acfde64afed6cda0007d">gist</a>.</p>
<h2 id="3-run-sourcery">3. Run Sourcery</h2>
<p>This will generate the <code class="highlighter-rouge">init</code> and insert the code right inside the <code class="highlighter-rouge">struct</code>’s declaration:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="c1">// sourcery: AutoInit</span>
<span class="kd">public</span> <span class="kd">struct</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="kd">public</span> <span class="k">let</span> <span class="nv">familyName</span><span class="p">:</span> <span class="kt">String</span>
<span class="kd">public</span> <span class="k">let</span> <span class="nv">givenName</span><span class="p">:</span> <span class="kt">String</span>
<span class="c1">// sourcery:inline:auto:Person.AutoInit</span>
<span class="kd">public</span> <span class="nf">init</span><span class="p">(</span><span class="nv">familyName</span><span class="p">:</span> <span class="kt">String</span><span class="p">,</span> <span class="nv">givenName</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">familyName</span> <span class="o">=</span> <span class="n">familyName</span>
<span class="k">self</span><span class="o">.</span><span class="n">givenName</span> <span class="o">=</span> <span class="n">givenName</span>
<span class="p">}</span>
<span class="c1">// sourcery:end</span>
<span class="p">}</span>
</code></pre>
</div>
<p>The template use the <a href="https://cdn.rawgit.com/krzysztofzablocki/Sourcery/master/docs/writing-templates.html#inline-code-generation">auto-inlining</a> feature of Sourcery.<br />
It will take the code between the <code class="highlighter-rouge">inline:auto</code> annotations and put it directly inside the specified type and then update the code in place when it needs to change.</p>
<h2 id="4-enjoy">4. Enjoy</h2>
<p>You can now access this initializer from outside the module and every time you update the structure declaration, it will update itself (when you run Sourcery of course).</p>
</content>
</entry>
<entry>
<title>Swift property initialization</title>
<link href="https://code-craftsman.fr/2016/01/21/Swift_property_initialization/"/>
<updated>2016-01-21T00:00:00+01:00</updated>
<id>https://code-craftsman.fr/2016/01/21/Swift_property_initialization</id>
<content type="html"><p>Let’s say we want to share a <code class="highlighter-rouge">NSDateFromatter</code> instance in the scope of a class, for example, a <code class="highlighter-rouge">UITableViewDataSource</code>. We would declare it like this:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MyTableViewController</span><span class="p">:</span> <span class="kt">NSObject</span><span class="p">,</span> <span class="kt">UITableViewDataSource</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">dateFormatter</span><span class="p">:</span> <span class="kt">NSDateFormatter</span>
<span class="k">override</span> <span class="nf">init</span><span class="p">()</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">dateFormatter</span> <span class="o">=</span> <span class="kt">NSDateFormatter</span><span class="p">()</span>
<span class="k">super</span><span class="o">.</span><span class="nf">init</span><span class="p">()</span>
<span class="p">}</span>
<span class="c1">// protocol implementation skipped, not relevant in this example</span>
<span class="p">}</span>
</code></pre>
</div>
<p>As you can see, we need to initialize <code class="highlighter-rouge">dateFormatter</code> in <code class="highlighter-rouge">init()</code>. And to be sure the formatter is correctly configured, we would need to do it there too:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code> <span class="k">override</span> <span class="nf">init</span><span class="p">()</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">dateFormatter</span> <span class="o">=</span> <span class="kt">NSDateFormatter</span><span class="p">()</span>
<span class="k">self</span><span class="o">.</span><span class="n">dateFormatter</span><span class="o">.</span><span class="n">dateStyle</span> <span class="o">=</span> <span class="o">.</span><span class="kt">NoStyle</span>
<span class="k">self</span><span class="o">.</span><span class="n">dateFormatter</span><span class="o">.</span><span class="n">timeStyle</span> <span class="o">=</span> <span class="o">.</span><span class="kt">FullStyle</span>
<span class="k">super</span><span class="o">.</span><span class="nf">init</span><span class="p">()</span>
<span class="p">}</span>
</code></pre>
</div>
<p>I like to have tiny functions with explicit names.
But, as of today, we cannot factorize all of this in a method of <code class="highlighter-rouge">MyTableViewController</code> because <code class="highlighter-rouge">self</code> is not initialized. We need to split instanciation and configuration:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code> <span class="k">override</span> <span class="nf">init</span><span class="p">()</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">dateFormatter</span> <span class="o">=</span> <span class="kt">NSDateFormatter</span><span class="p">()</span>
<span class="k">super</span><span class="o">.</span><span class="nf">init</span><span class="p">()</span>
<span class="k">self</span><span class="o">.</span><span class="nf">configureDateFormatter</span><span class="p">()</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nf">configureDateFormatter</span><span class="p">()</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">dateFormatter</span><span class="o">.</span><span class="n">dateStyle</span> <span class="o">=</span> <span class="o">.</span><span class="kt">NoStyle</span>
<span class="k">self</span><span class="o">.</span><span class="n">dateFormatter</span><span class="o">.</span><span class="n">timeStyle</span> <span class="o">=</span> <span class="o">.</span><span class="kt">FullStyle</span>
<span class="p">}</span>
</code></pre>
</div>
<p>And we need to do that for every property… not very practical.
To prevent cluttering up <code class="highlighter-rouge">init()</code> with all the property initialization values we could do that when we declare <code class="highlighter-rouge">dateFormatter</code>:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MyTableViewController</span><span class="p">:</span> <span class="kt">NSObject</span><span class="p">,</span> <span class="kt">UITableViewDataSource</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">dateFormatter</span> <span class="o">=</span> <span class="kt">NSDateFormatter</span><span class="p">()</span>
<span class="k">override</span> <span class="nf">init</span><span class="p">()</span> <span class="p">{</span>
<span class="k">super</span><span class="o">.</span><span class="nf">init</span><span class="p">()</span>
<span class="k">self</span><span class="o">.</span><span class="nf">configureDateFormatter</span><span class="p">()</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nf">configureDateFormatter</span><span class="p">()</span> <span class="p">{</span>
<span class="k">self</span><span class="o">.</span><span class="n">dateFormatter</span><span class="o">.</span><span class="n">dateStyle</span> <span class="o">=</span> <span class="o">.</span><span class="kt">NoStyle</span>
<span class="k">self</span><span class="o">.</span><span class="n">dateFormatter</span><span class="o">.</span><span class="n">timeStyle</span> <span class="o">=</span> <span class="o">.</span><span class="kt">FullStyle</span>
<span class="p">}</span>
<span class="c1">// protocol implementation skipped, not relevant in this example</span>
<span class="p">}</span>
</code></pre>
</div>
<p>This is better and the property type is now inferred.</p>
<p>But I am not quite satisfied with this.</p>
<p>Isn’t there a way to do this in Swift without declaring and calling <code class="highlighter-rouge">configureDateFormatter()</code>? Which is, by the way, only called once during the lifetime of the object?</p>
<p><strong>Closures</strong>!</p>
<p>Here is how:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">MyTableViewController</span><span class="p">:</span> <span class="kt">NSObject</span><span class="p">,</span> <span class="kt">UITableViewDataSource</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">dateFormatter</span><span class="p">:</span> <span class="kt">NSDateFormatter</span> <span class="o">=</span> <span class="p">{</span>
<span class="k">let</span> <span class="nv">dateFormatter</span> <span class="o">=</span> <span class="kt">NSDateFormatter</span><span class="p">()</span>
<span class="n">dateFormatter</span><span class="o">.</span><span class="n">dateStyle</span> <span class="o">=</span> <span class="o">.</span><span class="kt">NoStyle</span>
<span class="n">dateFormatter</span><span class="o">.</span><span class="n">timeStyle</span> <span class="o">=</span> <span class="o">.</span><span class="kt">FullStyle</span>
<span class="k">return</span> <span class="n">dateFormatter</span>
<span class="p">}()</span>
<span class="c1">// protocol implementation skipped, not relevant in this example</span>
<span class="p">}</span>
</code></pre>
</div>
<p>As you can see, we do not need to override <code class="highlighter-rouge">init()</code> anymore! And we have all <code class="highlighter-rouge">dataFormatter</code> initialization and configuration in one place.</p>
<p>Hope that someone will find this useful!</p>
</content>
</entry>
<entry>
<title>Swift, TDD and Playgrounds</title>
<link href="https://code-craftsman.fr/2015/12/21/Swift_TDD_and_Playgrounds/"/>
<updated>2015-12-21T00:00:00+01:00</updated>
<id>https://code-craftsman.fr/2015/12/21/Swift_TDD_and_Playgrounds</id>
<content type="html"><p>Lately, I have been doing some TDD in Swift.</p>
<p>While following the <code class="highlighter-rouge">red, green, refactor</code> cycle using the default Xcode test target, I found that deploying on the simulator could easily take several seconds.
So, I asked myself if there was not a faster way of doing this in Swift.</p>
<p>And the answer came quite easily. What do we use when we want to test something quickly in Swift?</p>
<p>That’s right, <em>Playgrounds</em>!</p>
<p>So I have looked into how I could do TDD using a Playground with the following objective in mind:</p>
<p><code class="highlighter-rouge">The final code must be easily moved into a classic Xcode project.</code></p>
<h2 id="xctest-in-playgrounds">XCTest in Playgrounds</h2>
<p>When we do unit tests in Xcode, we use the <code class="highlighter-rouge">XCTest</code> framework.
It gives us the <code class="highlighter-rouge">XCTestCase</code> class to run our tests and <code class="highlighter-rouge">XCTAssert</code> methods to check the results.
The class is not necessary in our case because we can call the functions direclty to run the tests. But, the methods are.</p>
<p>Yet, when you try to import <code class="highlighter-rouge">XCTest</code> in your iOS playground you will have this:</p>
<p><code class="highlighter-rouge">error: cannot load underlying module for 'XCTest'</code></p>
<p>In order to use <code class="highlighter-rouge">XCTest</code> directly, you have to use an OSX playground.</p>
<p><img src="/public/images/XCTestPlayground/OSX_Playground.png" alt="OSX Playground" /></p>
<p>Once done, using a method like <code class="highlighter-rouge">XCTFail</code> will show you when there is a problem.</p>
<p><img src="/public/images/XCTestPlayground/XCTest_exception.png" alt="XCTFail error" /></p>
<p>But, as you can see, the error is shown on the line of the top-most caller, not on the line where the error actually is. This can prove finding a failing test cumbersome.</p>
<h2 id="the-xctestplayground-workaround">The XCTestPlayground workaround</h2>
<p>To address these issues, I had the idea to implement my own <code class="highlighter-rouge">XCT</code> methods using a nice feature of Playgrounds: <code class="highlighter-rouge">the display of the return value</code></p>
<p>Here is the result:</p>
<p><img src="/public/images/XCTestPlayground/XCTestPlayground.png" alt="XCTestPlayground_example" /></p>
<p>With that, you can write test code in a Playground and have direct feedback on which assert passes and which does not.</p>
<p>You can find my implementation of the asserts in <a href="https://github.com/Liquidsoul/XCTestPlayground">this repository</a>. If you want to use this, just add the <code class="highlighter-rouge">XCTestPlayground.swift</code> file to your Playground’s sources folder.</p>
<p>Note that I did not implement all the functions. For example, the <code class="highlighter-rouge">WithAccuracy</code> ones are missing.</p>
</content>
</entry>
<entry>
<title>Testing a Reactive Cocoa App that uses CocoaPods</title>
<link href="https://code-craftsman.fr/2015/08/11/Testing-Reactive-Cocoa-App-that-use-CocoaPods/"/>
<updated>2015-08-11T00:00:00+02:00</updated>
<id>https://code-craftsman.fr/2015/08/11/Testing-Reactive-Cocoa-App-that-use-CocoaPods</id>
<content type="html"><p>Last weekend, I stumbled across something while trying to learn MVVM.</p>
<p>I was playing with the <a href="http://www.raywenderlich.com/74106/mvvm-tutorial-with-reactivecocoa-part-1">Colin Eberhardt’s tutorial</a> which explains how to set up the pattern using ReactiveCocoa. As I was progressing through the <a href="http://www.raywenderlich.com/74131/mvvm-tutorial-with-reactivecocoa-part-2">second part</a>, I saw this note:
<code class="highlighter-rouge">If you’re feeling adventurous, prove it by writing a unit test that executes a search and navigates from one ViewModel to the next</code></p>
<p>Because I wanted to be able to set up more tests by using MVVM, I decided that I felt adventurous enough to test the ViewModels without any UI.</p>
<h2 id="well-put-their-name-to-the-test">‘We’ll put their name to the test’</h2>
<p>So I tried to set up a first basic test:</p>
<div class="language-objc highlighter-rouge"><pre class="highlight"><code><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">testPerformSearch</span>
<span class="p">{</span>
<span class="n">XCTestExpectation</span> <span class="o">*</span><span class="n">expectation</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span> <span class="nf">expectationWithDescription</span><span class="p">:</span><span class="s">@"Search success"</span><span class="p">];</span>
<span class="n">id</span><span class="o">&lt;</span><span class="n">RWTViewModelServices</span><span class="o">&gt;</span> <span class="n">viewModelServices</span> <span class="o">=</span> <span class="p">[[</span><span class="n">MockService</span> <span class="nf">alloc</span><span class="p">]</span> <span class="nf">initWithPushBlock</span><span class="p">:</span><span class="o">^</span><span class="p">(</span><span class="n">id</span> <span class="n">viewModel</span><span class="p">)</span> <span class="p">{</span>
<span class="p">[</span><span class="n">expectation</span> <span class="nf">fulfill</span><span class="p">];</span>
<span class="p">}];</span>
<span class="n">RWTFlickrSearchViewModel</span> <span class="o">*</span><span class="n">viewModel</span> <span class="o">=</span> <span class="p">[[</span><span class="n">RWTFlickrSearchViewModel</span> <span class="nf">alloc</span><span class="p">]</span> <span class="nf">initWithServices</span><span class="p">:</span><span class="n">viewModelServices</span><span class="p">];</span>
<span class="n">viewModel</span><span class="p">.</span><span class="n">searchText</span> <span class="o">=</span> <span class="s">@"beach"</span><span class="p">;</span>
<span class="p">[</span><span class="n">viewModel</span><span class="p">.</span><span class="n">executeSearch</span> <span class="nf">execute</span><span class="p">:</span><span class="nb">nil</span><span class="p">];</span>
<span class="p">[</span><span class="n">self</span> <span class="nf">waitForExpectationsWithTimeout</span><span class="p">:</span><span class="mi">2</span> <span class="nf">handler</span><span class="p">:</span><span class="nb">nil</span><span class="p">];</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Because I was using some ReactiveCocoa here, it was necessary to import the ReactiveCocoa header to make this work. To do this, I just applied the same pod configuration to my test target:</p>
<p><img src="/public/images/RAC_Issue/TestConfigurationFile.png" alt="Test configuration file" /></p>
<p>Once my test compiled, I was quite confident that it would pass. However, here is what I got:</p>
<div class="language-objc highlighter-rouge"><pre class="highlight"><code><span class="nl">error:</span> <span class="o">-</span><span class="p">[</span><span class="n">ReactiveCocoaTestIssueTests</span> <span class="nf">testExecute</span><span class="p">]</span> <span class="o">:</span> <span class="n">failed</span><span class="o">:</span> <span class="n">caught</span> <span class="s">"NSInternalInconsistencyException"</span><span class="p">,</span> <span class="s">"-and must only be used on a signal of RACTuples of NSNumbers. Instead, received: &lt;RACTuple: 0x7fdd8bd40af0&gt; (</span><span class="err">
</span><span class="s"> 0,</span><span class="err">
</span><span class="s"> 1</span><span class="err">
</span><span class="s">)"</span>
</code></pre>
</div>
<p>This was weird… a <code class="highlighter-rouge">RACTuple</code> that is not a <code class="highlighter-rouge">RACTuple</code>…</p>
<p>After some time digging, I found <a href="https://github.com/ReactiveCocoa/ReactiveCocoa/issues/901">this isssue</a> in ReactiveCocoa github.</p>
<p>One explaination might be that we have more than only one <code class="highlighter-rouge">RACTuple</code> class.</p>
<p>It appears that this is related to some setup issues with CocoaPods that does not operate well with the default test setup of Xcode.
By default, tests are run against the Host Application (see your Project &gt; Targets &gt; General)</p>
<p><img src="/public/images/RAC_Issue/TestingDefaultSetup.jpg" alt="Testing target image" /></p>
<p>and linking the test target to ReactiveCocoa <em>doubles</em> the symbols because Xcode perform some dynamic code injection behind the scene.</p>
<h2 id="getting-out-of-the-pit">Getting out of the pit</h2>
<p>There are multiple solutions to this, but, unfortunately, nothing straightforward which use CocoaPods. As I discovered, I am not the first one to stumble upon <a href="https://github.com/CocoaPods/CocoaPods/issues/1411">this</a> and the feature is still <a href="https://github.com/CocoaPods/CocoaPods/issues/840">missing</a>.</p>
<p>So what can one do?</p>
<ul>
<li>One solution is to change your testing settings and stop testing against the Application. In this case, you need to compile all the code you want to test in your test target. This can be quite cumbersome because every time you add a class in your App, you may need to add it to your test target. Another problem is that you run your tests outside the context of your running App, this can be problematic in some cases.</li>
<li>Another quicker solution I found was to add the Pods headers folder to the Test target’s header path recursively: <code class="highlighter-rouge">$(PROJECT_DIR)/Pods/Headers</code>. This is kind of dirty, but it does the trick.</li>
<li>Last, but not least, setting up your project/workspace entirely by yourself is, of course, a viable solution. I am still new to CocoaPods, and as I see its immediate value<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup>, I am also wondering if relying on it in the long run might have some annoying downsides. I have been a long time user of git submodules. So you could still do this because you won’t be relying of some generated settings on your project.</li>
</ul>
<p>Maybe there are other solutions but, for now, I have just used the second one for my problem.</p>
<p>If you want to see an example of the problem, I shared <a href="https://github.com/Liquidsoul/ReactiveCocoaTestIssue">a project on github</a>.</p>
<p>I hope this will help someone!</p>
<div class="footnotes">
<ol>
<li id="fn:1">
<p>injecting third-party libraries like if it was nothing&nbsp;<a href="#fnref:1" class="reversefootnote">&#8617;</a></p>
</li>
</ol>
</div>
</content>
</entry>
<entry>
<title>Saving CoreData objects</title>
<link href="https://code-craftsman.fr/2015/08/04/saving-core-data-objects/"/>
<updated>2015-08-04T00:00:00+02:00</updated>
<id>https://code-craftsman.fr/2015/08/04/saving-core-data-objects</id>
<content type="html"><p>The associated playground can be found <a href="https://github.com/Liquidsoul/coredata-saving-contexts">in this repo</a>!</p>
<h2 id="the-context">The context</h2>
<p>I am quite new at using Core Data.
I have started to use it just a few months back, and I’ve been using it extensively the last couple of months.
During this time, I have learned some things about <code class="highlighter-rouge">NSManagedObjectContext</code> that I want to share.
Here, I’ll explain how the saving mechanism works with multiple contexts created using different methods.</p>
<p>We’ll work with a very basic Core Data model which will contain only one single entity.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>+-----------------+
| Person |
+-----------------+
| name |
+-----------------+
</code></pre>
</div>
<p>Here is our context:</p>
<ul>
<li>we’ve got a main context that is used by our controllers</li>
<li>we want to refresh our data using server requests and store it asynchronously to Core Data (server requests are another topic so we will skip this part)</li>
</ul>
<h2 id="the-first-approach">The first approach</h2>
<p>To get started quickly with our topic, the heavy lifting of creating the model and persistent store coordinator will be done behind the scene<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup>:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">import</span> <span class="kt">CoreData</span>
<span class="k">let</span> <span class="nv">persistentStoreCoordinator</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">createPersistentStoreCoordinator</span><span class="p">()</span>
</code></pre>
</div>
<p>Now that we have our persistentStoreCoordinator, we create our main context:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">mainContext</span> <span class="o">=</span> <span class="kt">NSManagedObjectContext</span><span class="p">(</span><span class="nv">concurrencyType</span><span class="p">:</span> <span class="o">.</span><span class="kt">MainQueueConcurrencyType</span><span class="p">)</span>
<span class="n">mainContext</span><span class="o">.</span><span class="n">persistentStoreCoordinator</span> <span class="o">=</span> <span class="n">persistentStoreCoordinator</span>
</code></pre>
</div>
<p>As we want to share data between the two contexts, we create a child context for our background update:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">childContext</span> <span class="o">=</span> <span class="kt">NSManagedObjectContext</span><span class="p">(</span><span class="nv">concurrencyType</span><span class="p">:</span> <span class="o">.</span><span class="kt">MainQueueConcurrencyType</span><span class="p">)</span>
<span class="n">childContext</span><span class="o">.</span><span class="n">parentContext</span> <span class="o">=</span> <span class="n">mainContext</span>
</code></pre>
</div>
<p>Then, we create a new entity in the child context as if it came from the server<sup id="fnref:1:1"><a href="#fn:1" class="footnote">1</a></sup>:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">person</span> <span class="o">=</span> <span class="nf">addPersonToContext</span><span class="p">(</span><span class="n">childContext</span><span class="p">,</span> <span class="nv">name</span><span class="p">:</span> <span class="s">"John"</span><span class="p">)</span>
</code></pre>
</div>
<p>Now we save our content<sup id="fnref:2"><a href="#fn:2" class="footnote">2</a></sup>:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">try</span> <span class="n">childContext</span><span class="o">.</span><span class="nf">save</span><span class="p">()</span>
</code></pre>
</div>
<p>Let’s check that we have the new content in the main context using a fetch request:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">results</span> <span class="o">=</span> <span class="k">try</span> <span class="n">mainContext</span><span class="o">.</span><span class="nf">executeFetchRequest</span><span class="p">(</span><span class="kt">NSFetchRequest</span><span class="p">(</span><span class="nv">entityName</span><span class="p">:</span> <span class="s">"Person"</span><span class="p">))</span>
<span class="k">if</span> <span class="k">let</span> <span class="nv">createdPerson</span> <span class="o">=</span> <span class="n">results</span><span class="o">.</span><span class="n">first</span> <span class="k">as?</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="n">createdPerson</span><span class="p">)</span> <span class="c1">// "name: John"</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"Noone there!"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Yes! Everything seems ok.</p>
<p>To be sure, let’s just check if everything was saved in the persistent store using a third context as if we were launching our app again:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">secondLaunchMainContext</span> <span class="o">=</span> <span class="kt">NSManagedObjectContext</span><span class="p">(</span><span class="nv">concurrencyType</span><span class="p">:</span> <span class="o">.</span><span class="kt">MainQueueConcurrencyType</span><span class="p">)</span>
<span class="n">secondLaunchMainContext</span><span class="o">.</span><span class="n">persistentStoreCoordinator</span> <span class="o">=</span> <span class="n">persistentStoreCoordinator</span>
</code></pre>
</div>
<p>and fetch our data:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="k">let</span> <span class="nv">createdPerson</span> <span class="o">=</span> <span class="k">try</span> <span class="n">secondLaunchMainContext</span><span class="o">.</span><span class="nf">executeFetchRequest</span><span class="p">(</span><span class="kt">NSFetchRequest</span><span class="p">(</span><span class="nv">entityName</span><span class="p">:</span> <span class="s">"Person"</span><span class="p">))</span><span class="o">.</span><span class="n">first</span> <span class="k">as?</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="n">createdPerson</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"Noone there!"</span><span class="p">)</span> <span class="c1">// "Noone there!"</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Wait, what? There is no data? What happened?</p>
<p>Here is the first important lesson to learn.
Let’s have a look at the official documentation of <code class="highlighter-rouge">save()</code>:</p>
<div class="highlighter-rouge"><pre class="highlight"><code>Attempts to commit unsaved changes to registered objects to the receiver’s
parent store.
</code></pre>
</div>
<p>This can be misleading. When one see <code class="highlighter-rouge">parent store</code> he can understand <code class="highlighter-rouge">the parent persitent store of my context hierarchy</code>.
However, what is meant by <code class="highlighter-rouge">parent store</code> is either:</p>
<ul>
<li>the persistentStoreCoordinator</li>
<li>the parentContext</li>
</ul>
<p>So, if your context was setup with a parent context, changes are commited to his parent but no further.
To save it to the persistent store, you’ll need to call <code class="highlighter-rouge">save()</code> on contexts all the way up in the hierarchy until you reach the persistent store.</p>
<h2 id="fixing-our-first-approach">Fixing our first approach</h2>
<p>So, we have our initial setup.</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">import</span> <span class="kt">CoreData</span>
<span class="k">let</span> <span class="nv">persistentStoreCoordinator</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">createPersistentStoreCoordinator</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">mainContext</span> <span class="o">=</span> <span class="kt">NSManagedObjectContext</span><span class="p">(</span><span class="nv">concurrencyType</span><span class="p">:</span> <span class="o">.</span><span class="kt">MainQueueConcurrencyType</span><span class="p">)</span>
<span class="n">mainContext</span><span class="o">.</span><span class="n">persistentStoreCoordinator</span> <span class="o">=</span> <span class="n">persistentStoreCoordinator</span>
</code></pre>
</div>
<p>But to spice it a little, let’s create another entity that will exist in the main context.
For example, this entity could’ve come from another child context:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">ourOtherPerson</span> <span class="o">=</span> <span class="nf">addPersonToContext</span><span class="p">(</span><span class="n">mainContext</span><span class="p">,</span> <span class="nv">name</span><span class="p">:</span> <span class="s">"Billy"</span><span class="p">)</span>
</code></pre>
</div>
<p>Now, we continue as before with the server data we want to save in the persistent store:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">childContext</span> <span class="o">=</span> <span class="kt">NSManagedObjectContext</span><span class="p">(</span><span class="nv">concurrencyType</span><span class="p">:</span> <span class="o">.</span><span class="kt">MainQueueConcurrencyType</span><span class="p">)</span>
<span class="n">childContext</span><span class="o">.</span><span class="n">parentContext</span> <span class="o">=</span> <span class="n">mainContext</span>
<span class="k">let</span> <span class="nv">person</span> <span class="o">=</span> <span class="nf">addPersonToContext</span><span class="p">(</span><span class="n">childContext</span><span class="p">,</span> <span class="nv">name</span><span class="p">:</span> <span class="s">"John"</span><span class="p">)</span>
</code></pre>
</div>
<p>Now, as we’ve learned before, we save our content in the child context and then in the main context<sup id="fnref:3"><a href="#fn:3" class="footnote">3</a></sup>:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">try</span> <span class="n">childContext</span><span class="o">.</span><span class="nf">save</span><span class="p">()</span>
<span class="k">try</span> <span class="n">mainContext</span><span class="o">.</span><span class="nf">save</span><span class="p">()</span>
</code></pre>
</div>
<p>We have saved our “John” in the persistent store, let’s check that:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">secondLaunchMainContext</span> <span class="o">=</span> <span class="kt">NSManagedObjectContext</span><span class="p">(</span><span class="nv">concurrencyType</span><span class="p">:</span> <span class="o">.</span><span class="kt">MainQueueConcurrencyType</span><span class="p">)</span>
<span class="n">secondLaunchMainContext</span><span class="o">.</span><span class="n">persistentStoreCoordinator</span> <span class="o">=</span> <span class="n">persistentStoreCoordinator</span>
<span class="k">let</span> <span class="nv">fetchRequest</span> <span class="o">=</span> <span class="kt">NSFetchRequest</span><span class="p">(</span><span class="nv">entityName</span><span class="p">:</span> <span class="s">"Person"</span><span class="p">)</span>
<span class="n">fetchRequest</span><span class="o">.</span><span class="n">predicate</span> <span class="o">=</span> <span class="kt">NSPredicate</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span><span class="s">"%K like %@"</span><span class="p">,</span> <span class="s">"name"</span><span class="p">,</span> <span class="s">"John"</span><span class="p">)</span>
<span class="k">if</span> <span class="k">let</span> <span class="nv">createdPerson</span> <span class="o">=</span> <span class="k">try</span> <span class="n">secondLaunchMainContext</span><span class="o">.</span><span class="nf">executeFetchRequest</span><span class="p">(</span><span class="n">fetchRequest</span><span class="p">)</span><span class="o">.</span><span class="n">first</span> <span class="k">as?</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="n">createdPerson</span><span class="p">)</span> <span class="c1">// "name: John"</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"Noone there!"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Problem solved!</p>
<p>But wait… what happened to our “Billy”. We wanted to store only “John” into the persitent store, not “Billy”:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="n">fetchRequest</span><span class="o">.</span><span class="n">predicate</span> <span class="o">=</span> <span class="kt">NSPredicate</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span><span class="s">"%K like %@"</span><span class="p">,</span> <span class="s">"name"</span><span class="p">,</span> <span class="s">"Billy"</span><span class="p">)</span>
<span class="k">if</span> <span class="k">let</span> <span class="nv">createdPerson</span> <span class="o">=</span> <span class="k">try</span> <span class="n">secondLaunchMainContext</span><span class="o">.</span><span class="nf">executeFetchRequest</span><span class="p">(</span><span class="n">fetchRequest</span><span class="p">)</span><span class="o">.</span><span class="n">first</span> <span class="k">as?</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="n">createdPerson</span><span class="p">)</span> <span class="c1">// "name: Billy"</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"Noone there!"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Oh no! We’ve saved “Billy” as well!</p>
<p>Yet, this seems coherent with the fact that, as we’ve performed a <code class="highlighter-rouge">save()</code> on the main context, <em>all</em> objects it contains are saved.</p>
<p>So what can we do if we only want to save John without saving Billy?</p>
<h2 id="confined-save">Confined save</h2>
<p>Let’s do it again, we setup our main context with “Billy”</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">import</span> <span class="kt">CoreData</span>
<span class="k">let</span> <span class="nv">persistentStoreCoordinator</span> <span class="o">=</span> <span class="k">try</span> <span class="nf">createPersistentStoreCoordinator</span><span class="p">()</span>
<span class="k">let</span> <span class="nv">mainContext</span> <span class="o">=</span> <span class="kt">NSManagedObjectContext</span><span class="p">(</span><span class="nv">concurrencyType</span><span class="p">:</span> <span class="o">.</span><span class="kt">MainQueueConcurrencyType</span><span class="p">)</span>
<span class="n">mainContext</span><span class="o">.</span><span class="n">persistentStoreCoordinator</span> <span class="o">=</span> <span class="n">persistentStoreCoordinator</span>
<span class="k">let</span> <span class="nv">ourOtherPerson</span> <span class="o">=</span> <span class="nf">addPersonToContext</span><span class="p">(</span><span class="n">mainContext</span><span class="p">,</span> <span class="nv">name</span><span class="p">:</span> <span class="s">"Billy"</span><span class="p">)</span>
</code></pre>
</div>
<p>Then, to prevent “Billy” to be saved while we just want to save “John”, we will not create our editing context as a child of the main.
We will create what we’ll call a <em>sibling</em> context. These are contexts that share the same persitent store coordinator:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">siblingContext</span> <span class="o">=</span> <span class="kt">NSManagedObjectContext</span><span class="p">(</span><span class="nv">concurrencyType</span><span class="p">:</span> <span class="o">.</span><span class="kt">MainQueueConcurrencyType</span><span class="p">)</span>
<span class="n">siblingContext</span><span class="o">.</span><span class="n">persistentStoreCoordinator</span> <span class="o">=</span> <span class="n">persistentStoreCoordinator</span>
<span class="k">let</span> <span class="nv">person</span> <span class="o">=</span> <span class="nf">addPersonToContext</span><span class="p">(</span><span class="n">siblingContext</span><span class="p">,</span> <span class="nv">name</span><span class="p">:</span> <span class="s">"John"</span><span class="p">)</span>
</code></pre>
</div>
<p>Now, all we have to do is save the sibling context:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">try</span> <span class="n">siblingContext</span><span class="o">.</span><span class="nf">save</span><span class="p">()</span>
</code></pre>
</div>
<p>Let’s check that we can access our “John” from our main context:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">fetchRequest</span> <span class="o">=</span> <span class="kt">NSFetchRequest</span><span class="p">(</span><span class="nv">entityName</span><span class="p">:</span> <span class="s">"Person"</span><span class="p">)</span>
<span class="n">fetchRequest</span><span class="o">.</span><span class="n">predicate</span> <span class="o">=</span> <span class="kt">NSPredicate</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span><span class="s">"%K like %@"</span><span class="p">,</span> <span class="s">"name"</span><span class="p">,</span> <span class="s">"John"</span><span class="p">)</span>
<span class="k">if</span> <span class="k">let</span> <span class="nv">createdPerson</span> <span class="o">=</span> <span class="k">try</span> <span class="n">mainContext</span><span class="o">.</span><span class="nf">executeFetchRequest</span><span class="p">(</span><span class="n">fetchRequest</span><span class="p">)</span><span class="o">.</span><span class="n">first</span> <span class="k">as?</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="n">createdPerson</span><span class="p">)</span> <span class="c1">// "name: John"</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"Noone there!"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Yes! Now let’s see if “Billy” was saved:</p>
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">let</span> <span class="nv">secondLaunchMainContext</span> <span class="o">=</span> <span class="kt">NSManagedObjectContext</span><span class="p">(</span><span class="nv">concurrencyType</span><span class="p">:</span> <span class="o">.</span><span class="kt">MainQueueConcurrencyType</span><span class="p">)</span>
<span class="n">secondLaunchMainContext</span><span class="o">.</span><span class="n">persistentStoreCoordinator</span> <span class="o">=</span> <span class="n">persistentStoreCoordinator</span>
<span class="n">fetchRequest</span><span class="o">.</span><span class="n">predicate</span> <span class="o">=</span> <span class="kt">NSPredicate</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span><span class="s">"%K like %@"</span><span class="p">,</span> <span class="s">"name"</span><span class="p">,</span> <span class="s">"Billy"</span><span class="p">)</span>
<span class="k">if</span> <span class="k">let</span> <span class="nv">createdPerson</span> <span class="o">=</span> <span class="k">try</span> <span class="n">secondLaunchMainContext</span><span class="o">.</span><span class="nf">executeFetchRequest</span><span class="p">(</span><span class="n">fetchRequest</span><span class="p">)</span><span class="o">.</span><span class="n">first</span> <span class="k">as?</span> <span class="kt">Person</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="n">createdPerson</span><span class="p">)</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"Noone there!"</span><span class="p">)</span> <span class="c1">// "Noone there!"</span>
<span class="p">}</span>
</code></pre>
</div>
<p>We did it!</p>
<h2 id="conclusion">Conclusion</h2>
<p>Here, we learned that:</p>
<ul>
<li>calling <code class="highlighter-rouge">save()</code> on a context will only send changes one step up the hierarchy</li>
<li><code class="highlighter-rouge">save()</code> will commit changes contained in the whole context</li>
</ul>
<p>I hope that this may help anyone who did not yet grasp how Core Data save its content throught contexts.</p>
<p><strong>As a side note</strong>: for the sake of simplicity here, we have only worked with entity insertion.
When you start playing with entity attributes, you’ll need to perform some <a href="https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/index.html#//apple_ref/occ/instm/NSManagedObjectContext/refreshObject:mergeChanges:"><code class="highlighter-rouge">refreshObject(_:mergeChanges:)</code></a> calls to see the saved values in other contexts.</p>
<div class="footnotes">
<ol>
<li id="fn:1">
<p><code class="highlighter-rouge">createPersistentStoreCoordinator</code> and <code class="highlighter-rouge">addPersonToContext</code> are helper functions to shorten the code in the article. You can find the code <a href="https://github.com/Liquidsoul/coredata-saving-contexts/blob/master/CoreDataSavingContexts.playground/Sources/CoreDataSetup.swift">here</a>&nbsp;<a href="#fnref:1" class="reversefootnote">&#8617;</a>&nbsp;<a href="#fnref:1:1" class="reversefootnote">&#8617;<sup>2</sup></a></p>
</li>
<li id="fn:2">
<p>Note that you should use <code class="highlighter-rouge">performBlock()</code> to execute calls on a <code class="highlighter-rouge">NSManagedObjectContext</code> to ensure that the correct thread is using it.&nbsp;<a href="#fnref:2" class="reversefootnote">&#8617;</a></p>
</li>
<li id="fn:3">
<p>as told before<sup id="fnref:2:1"><a href="#fn:2" class="footnote">2</a></sup>, don’t forget to use <code class="highlighter-rouge">performBlock()</code> to call CoreData context code&nbsp;<a href="#fnref:3" class="reversefootnote">&#8617;</a></p>
</li>
</ol>
</div>
</content>
</entry>
<entry>
<title>My very first post</title>
<link href="https://code-craftsman.fr/2015/07/30/my-very-first-post/"/>
<updated>2015-07-30T00:00:00+02:00</updated>
<id>https://code-craftsman.fr/2015/07/30/my-very-first-post</id>
<content type="html"><p>Hi!</p>
<p>This is my first blog post ever and, hopefully, it will be the first of many to come.</p>
</content>
</entry>
</feed>