<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Core Data on Andrew Bancroft</title>
    <link>https://www.andrewcbancroft.com/categories/core-data/</link>
    <description>Recent content about iOS development with Swift in Core Data  from Andrew Bancroft.</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 31 Jul 2019 04:40:54 +0000</lastBuildDate>
    
        <atom:link href="https://www.andrewcbancroft.com/categories/core-data/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Using Core Data With SwiftUI - An Introduction</title>
      <link>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/using-core-data-with-swiftui-introduction/</link>
      <pubDate>Wed, 31 Jul 2019 04:40:54 +0000</pubDate>
      
      <guid>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/using-core-data-with-swiftui-introduction/</guid>
      <description>&lt;p&gt;How does Apple intend for us to use Core Data with SwiftUI?&lt;/p&gt;
&lt;p&gt;They gave us a path forward with the most recent beta release of iOS 13 (Beta 5 at the time of this writing)!&lt;/p&gt;
&lt;p&gt;&lt;a name=&#34;resources&#34; class=&#34;jump-target&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;resources&#34;&gt;
&lt;div class=&#34;resources-header&#34;&gt;
Resources
&lt;/div&gt;
&lt;ul class=&#34;resources-content&#34;&gt;
&lt;li&gt;
&lt;i class=&#34;fas fa-file-code&#34;&gt;&lt;/i&gt; &lt;a href=&#34;https://github.com/andrewcbancroft/BlogIdeaList-SwiftUI&#34;&gt; Blog Idea List SwiftUI Example Xcode Project&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;i class=&#34;fas fa-link&#34;&gt;&lt;/i&gt; &lt;a href=&#34;https://developer.apple.com/videos/play/wwdc2019/226/&#34; rel=&#34;nofollow&#34;&gt;Data Flow Through SwiftUI - WWDC 2019 Session 226&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&#34;first-things-first&#34;&gt;First Things First&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To work effectively with Core Data in SwiftUI, the &lt;a href=&#34;https://developer.apple.com/videos/play/wwdc2019/226/&#34;&gt;Data Flow Through SwiftUI&lt;/a&gt; WWDC session is a huge help.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;With this talk under your belt, you&amp;rsquo;ll have at least been introduced to key words like &lt;code&gt;@State&lt;/code&gt;, &lt;code&gt;@Binding&lt;/code&gt;, &lt;code&gt;@ObservableObject&lt;/code&gt; (which replaces &lt;code&gt;@BindableObject&lt;/code&gt; as of Beta 5), and &lt;code&gt;@Environment&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;on-the-right-path&#34;&gt;On the Right Path&lt;/h2&gt;
&lt;p&gt;Even prior to Beta 5, the &amp;ldquo;right path&amp;rdquo; for using Core Data with SwiftUI seemed to be through the &lt;code&gt;@Environment&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the release notes for iOS Beta 5, Apple seems to be leading us there:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NSManagedObject&lt;/code&gt; now conforms to &lt;code&gt;ObservableObject&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;The new &lt;code&gt;@FetchRequest&lt;/code&gt; property wrapper can drive views from the results of a fetch request&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;managedObjectContext&lt;/code&gt; is now &lt;strong&gt;included in the environment&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;With these three pieces in place, Apple has given us out-of-the-box support for using Core Data with SwiftUI.&lt;/p&gt;
&lt;p&gt;So&amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;how-do-you-get-started&#34;&gt;How Do You Get Started?&lt;/h2&gt;
&lt;p&gt;I decided to create a basic, single-view app that can&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Persist a list of &lt;code&gt;BlogIdea&lt;/code&gt;s to a Core Data persistent store&lt;/li&gt;
&lt;li&gt;Use the new &lt;code&gt;@FetchRequest&lt;/code&gt; property wrapper to fetch &lt;code&gt;BlogIdea&lt;/code&gt;s&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;@Environment&lt;/code&gt;&amp;rsquo;s &lt;code&gt;managedObjectContext&lt;/code&gt; to create, update, and delete &lt;code&gt;BlogIdea&lt;/code&gt;s&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Grab the project &lt;a href=&#34;https://github.com/andrewcbancroft/BlogIdeaList-SwiftUI&#34;&gt;over at GitHub&lt;/a&gt; and explore!&lt;/p&gt;
&lt;p&gt;The sample project that includes a single Core Data Entity named &lt;code&gt;BlogIdea&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.andrewcbancroft.com/blog/ios-development/data-persistence/using-core-data-with-swiftui-introduction/blog-idea-entity.png&#34; alt=&#34;Blog Idea Entity&#34;&gt;&lt;/p&gt;
&lt;p&gt;I kept as much out-of-the-box stuff as I could.&lt;/p&gt;
&lt;h2 id=&#34;how-does-it-work&#34;&gt;How Does It Work?&lt;/h2&gt;
&lt;p&gt;Throughout the project, you&amp;rsquo;ll notice emoji symbols to help draw your eye to the Core Data pieces.&lt;/p&gt;
&lt;p&gt;❇️ Alerts you to Core Data pieces&lt;/p&gt;
&lt;p&gt;ℹ️ Alerts you to general info about what my brain was thinking when I wrote the code&lt;/p&gt;
&lt;h2 id=&#34;code-walkthroughs&#34;&gt;Code Walkthroughs&lt;/h2&gt;
&lt;p&gt;I completely relate if you need to chunk things up and inspect the details of how each piece of the puzzle looks in isolation before you dive into the full app.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve written up two separate how-tos that show you more specific details:&lt;/p&gt;
&lt;div class=&#34;row align-items-center&#34;&gt;
&lt;div class=&#34;col&#34;&gt;
&lt;div class=&#34;card&#34; style=&#34;width: 25rem;&#34;&gt;
  &lt;a href=&#34;https://www.andrewcbancroft.com/blog/ios-development/data-persistence/passing-nsmanagedobjectcontext-to-swiftui-view/&#34;&gt;&lt;img src=&#34;https://www.andrewcbancroft.com/images/social-assets/Twitter - How to Pass NSManagedObjectContext to a SwiftUI View.png&#34; class=&#34;card-img-top&#34; alt=&#34;How to Pass NSManagedObjectContext to a SwiftUI View&#34;&gt;&lt;/a&gt;
  &lt;div class=&#34;card-body&#34;&gt;
    &lt;p class=&#34;card-text&#34;&gt;Breaks down how to pass an NSManagedObjectContext instance to your SwiftUI Views.&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&#34;col&#34;&gt;
&lt;div class=&#34;card&#34; style=&#34;width: 25rem;&#34;&gt;
  &lt;a href=&#34;https://www.andrewcbancroft.com/blog/ios-development/data-persistence/how-to-use-fetchrequest-swiftui/&#34;&gt;&lt;img src=&#34;https://www.andrewcbancroft.com/images/social-assets/Twitter - How to Use @FetchRequest in SwiftUI.png&#34; class=&#34;card-img-top&#34; alt=&#34;How to Use @FetchRequest in SwiftUI&#34;&gt;&lt;/a&gt;
  &lt;div class=&#34;card-body&#34;&gt;
    &lt;p class=&#34;card-text&#34;&gt;Breaks down how to use the @FetchRequest property wrapper in your SwiftUI Views.&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>NSPersistentCloudKitContainer Buggy Behavior List</title>
      <link>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/nspersistentcloudkitcontainer-buggy-behavior-list/</link>
      <pubDate>Thu, 11 Jul 2019 04:40:54 +0000</pubDate>
      
      <guid>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/nspersistentcloudkitcontainer-buggy-behavior-list/</guid>
      <description>&lt;p&gt;&lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; is brand new with Xcode 11 and iOS 13.&lt;/p&gt;
&lt;p&gt;It works&amp;hellip; kind of&amp;hellip; sometimes&amp;hellip;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m keeping this list of buggy behavior to help keep my head straight.  I&amp;rsquo;ve also filed bug reports on each.&lt;/p&gt;
&lt;p&gt;Hopefully others in the iOS community who are experimenting with &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; can confirm or deny these same oddities.  If they&amp;rsquo;re fixed in a subsequent beta, I&amp;rsquo;ll come back here and note it!&lt;/p&gt;
&lt;h2 id=&#34;which-beta-version-does-this-affect&#34;&gt;Which Beta Version Does This Affect?&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve tested out each of these on iOS 13 Beta 5 and Xcode 11 Beta 5.&lt;/p&gt;
&lt;h2 id=&#34;enabling-cloudkit-doesnt-create-a-default-container&#34;&gt;Enabling CloudKit doesn&amp;rsquo;t create a default container&lt;/h2&gt;
&lt;p&gt;In Xcode 11, adding the iCloud capability and clicking the CloudKit checkbox is not automatically creating a default container for new apps that I&amp;rsquo;m testing&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Xcode 10&lt;/strong&gt;
&lt;img src=&#34;XC10_CKDefaultContainer.gif&#34; alt=&#34;Xcode 10 - Creates Default Container&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Xcode 11&lt;/strong&gt;
&lt;img src=&#34;XC11_NoCKDefaultContainer.gif&#34; alt=&#34;Xcode 11 - Does Not Create Default Container&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;existing-data-doesnt-sync&#34;&gt;Existing data doesn&amp;rsquo;t sync&lt;/h2&gt;
&lt;p&gt;Suppose that&amp;hellip;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You have an existing Core Data app&lt;/li&gt;
&lt;li&gt;The app is installed on two devices with the same user signed in to iCloud&lt;/li&gt;
&lt;li&gt;Data has been saved independently on both devices&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now suppose that you want to take advantage of the automagic syncing offered with &lt;code&gt;NSPersistendCloudKitContainer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;hellip;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set up your app to work with &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Rebuild your app and install it on both devices&lt;/li&gt;
&lt;li&gt;Launch the app on both devices&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You might expect the existing data to show up on both devices.  &lt;strong&gt;It doesn&amp;rsquo;t.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you add &lt;em&gt;new&lt;/em&gt; data on one device, &lt;em&gt;only the new data&lt;/em&gt; that gets saved &lt;em&gt;after&lt;/em&gt; the &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; conversion gets synced.  Existing data never does.&lt;/p&gt;
&lt;p&gt;🤷🏼‍♂️&lt;/p&gt;
&lt;h2 id=&#34;data-only-syncs-after-you-close-and-re-launch-your-app&#34;&gt;Data only syncs after you close and re-launch your app&lt;/h2&gt;
&lt;p&gt;I really thought I had this figured out.  Beta 5 has proved me wrong.&lt;/p&gt;
&lt;p&gt;In Beta 2, simply &lt;a href=&#34;https://www.andrewcbancroft.com/blog/ios-development/data-persistence/getting-started-with-nspersistentcloudkitcontainer/#reflecting-changes-in-the-ui&#34;&gt;setting &lt;code&gt;automaticallyMergesChangesFromParent&lt;/code&gt; on the container&amp;rsquo;s &lt;code&gt;viewContext&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;&lt;/a&gt; seemed to work.&lt;/p&gt;
&lt;p&gt;Not with Beta 5.&lt;/p&gt;
&lt;p&gt;You can save new data and wait (and wait&amp;hellip; and wait&amp;hellip;).  It doesn&amp;rsquo;t show up in the UI until after you re-launch the app.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what I&amp;rsquo;m experiencing:&lt;/p&gt;

&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
  &lt;iframe src=&#34;https://www.youtube.com/embed/DLAwrSCl3Cc&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allowfullscreen title=&#34;YouTube Video&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;h2 id=&#34;record-accessor-methods-missing-in-xcode&#34;&gt;Record accessor methods missing in Xcode&lt;/h2&gt;
&lt;p&gt;&amp;ldquo;On &lt;em&gt;my&lt;/em&gt; machine&amp;rdquo;, attempting to use the &lt;code&gt;record(for:)&lt;/code&gt; methods on &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; produce the following error message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Value of type &amp;lsquo;NSPersistentCloudKitContainer&amp;rsquo; has no member &amp;lsquo;record&amp;rsquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&#34;no-record-method.png&#34; alt=&#34;Has no member &amp;lsquo;record&amp;rsquo;&#34;&gt;&lt;/p&gt;
&lt;p&gt;I can &amp;ldquo;Jump to definition&amp;rdquo; and the methods appear to be there&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;jump-definition.gif&#34; alt=&#34;Jump to Definition&#34;&gt;&lt;/p&gt;
&lt;p&gt;Attempting to use the function in code doesn&amp;rsquo;t work&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;no-member.gif&#34; alt=&#34;No Member&#34;&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How Smart (Or Dumb?) Should NSManagedObjects Be?</title>
      <link>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/how-smart-dumb-should-nsmanagedobjects-be/</link>
      <pubDate>Wed, 19 Jun 2019 04:40:54 +0000</pubDate>
      
      <guid>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/how-smart-dumb-should-nsmanagedobjects-be/</guid>
      <description>&lt;p&gt;Apps aren&amp;rsquo;t &amp;ldquo;dumb&amp;rdquo;.  Apps do things.  &lt;em&gt;Smart&lt;/em&gt; things.  The question is:  Where do the &amp;ldquo;smart parts&amp;rdquo; go?&lt;/p&gt;
&lt;p&gt;So how you smart or how dumb should &lt;code&gt;NSManagedObject&lt;/code&gt; subclasses be?&lt;/p&gt;
&lt;p&gt;What code should you write in one of these? What should you &lt;em&gt;not&lt;/em&gt;?&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TLDR;&lt;/h2&gt;
&lt;p&gt;Keep &lt;code&gt;NSManagedObject&lt;/code&gt;s about Core Data-y things.&lt;/p&gt;
&lt;p&gt;Ask, &amp;ldquo;Does this help my &lt;code&gt;NSManagedObject&lt;/code&gt; subclass work with Core Data-related functionality?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Let the answer to that question guide your decision about whether to extend your &lt;code&gt;NSManagedObject&lt;/code&gt; subclass with additional features.&lt;/p&gt;
&lt;h2 id=&#34;designed-overrides&#34;&gt;Designed Overrides&lt;/h2&gt;
&lt;p&gt;Apple has designed some spots for you to customize an &lt;code&gt;NSManagedObject&lt;/code&gt;&amp;rsquo;s default behavior.&lt;/p&gt;
&lt;h3 id=&#34;managed-object-life-cycle-events&#34;&gt;Managed Object &amp;ldquo;Life Cycle&amp;rdquo; Events&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;NSManagedObject&lt;/code&gt; comes with several overridable methods that you can implement in order to &amp;ldquo;hook in&amp;rdquo; to the life cycle of the object.  What do I mean?  Check out this sampling of overrideable methods:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;awakeFromFetch()&lt;/code&gt;: Provides an opportunity to add code into the life cycle of the managed object when Core Data is bringing the object from the persistent store into memory.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;awakeFromInsert()&lt;/code&gt;: Provides an opportunity to add code into the life cycle of the managed object when it is initially created.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;willSave()&lt;/code&gt;: Provides an opportunity to add code into the life cycle of the managed object when it is about to be saved.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;didSave()&lt;/code&gt;: Provides an opportunity to add code into the life cycle of the managed object after the managed object’s context completes a save operation.&lt;/p&gt;
&lt;p&gt;These methods can be overwritten to add code that should be strategically executed at these pre-determined-by-Apple points in time.&lt;/p&gt;
&lt;h3 id=&#34;validation-code&#34;&gt;Validation Code&lt;/h3&gt;
&lt;p&gt;You can implement custom validation logic in an &lt;code&gt;NSManagedObject&lt;/code&gt; subclass.  Don&amp;rsquo;t override &lt;code&gt;validateValue(_:forKey:)&lt;/code&gt; though.&lt;/p&gt;
&lt;p&gt;Instead, implement a custom method with a signature that matches the signature of &lt;code&gt;validatePropertyName:error:&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example, if your &lt;code&gt;NSManagedObject&lt;/code&gt; subclass has an &lt;code&gt;age&lt;/code&gt; property and you wanted to implement special validation logic, you could do this:&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;validateAge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;AutoreleasingUnsafeMutablePointer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;AnyObject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;throws&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;guard&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;valueNumber&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pointee&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSNumber&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;valueNumber&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;floatValue&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;errorStr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSLocalizedString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Age must be greater than zero&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tableName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Employee&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;comment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;validation: zero age error&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;userInfoDict&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NSLocalizedDescriptionKey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;errorStr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;domain&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;EMPLOYEE_ERROR_DOMAIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1123&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;userInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;userInfoDict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
You could also override one of these methods to add advanced validation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;validateForInsert()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;validateForUpdate()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;validateForDelete()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;key-value-observing&#34;&gt;Key-Value Observing&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;NSManagedObject&lt;/code&gt; subclasses inherit methods related to key-value observing that could be appropriate to override.&lt;/p&gt;
&lt;h3 id=&#34;summarizing-designed-overrides&#34;&gt;Summarizing Designed Overrides&lt;/h3&gt;
&lt;p&gt;Have you noticed a pattern in each of these sections?&lt;/p&gt;
&lt;p&gt;Key word:  &lt;strong&gt;override&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Apple designed &lt;code&gt;NSManagedObject&lt;/code&gt; with intentional, overrideable methods.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Should I implement &lt;code&gt;this code&lt;/code&gt; here?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Take a look at the method names and let that be a guiding factor in your decision-making.&lt;/p&gt;
&lt;h2 id=&#34;on-fetching-behavior&#34;&gt;On Fetching Behavior&lt;/h2&gt;
&lt;p&gt;Xcode adds a &lt;code&gt;fetchRequest&lt;/code&gt; method when it auto-generates code for you.  So&amp;hellip;I&amp;rsquo;d say it&amp;rsquo;s probably okay to put some &lt;em&gt;basic&lt;/em&gt; fetching behavior with an &lt;code&gt;NSManagedObject&lt;/code&gt; subclass.  Keep it simple though:&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nonobjc&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fetchRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSFetchRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EntityName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSFetchRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EntityName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;entityName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;EntityName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
My personal preference is to put object fetching behavior in a separate Type.&lt;/p&gt;
&lt;p&gt;You might make a &lt;code&gt;DataProvider&lt;/code&gt; Type and let &lt;em&gt;it&lt;/em&gt; handle setting up &lt;code&gt;NSFetchRequest&lt;/code&gt;(s) with appropriate predicates and sort descriptors.&lt;/p&gt;
&lt;p&gt;Avoid putting &lt;em&gt;all&lt;/em&gt; data-providing code in a catch-all &lt;code&gt;DataProvider&lt;/code&gt;.  If you&amp;rsquo;re fetching &lt;code&gt;Note&lt;/code&gt;s, make a &lt;code&gt;NoteProvider&lt;/code&gt;.  If you&amp;rsquo;re fetching &lt;code&gt;Tag&lt;/code&gt;s, make a &lt;code&gt;TagProvider&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;on-convenience-properties--functions&#34;&gt;On Convenience Properties &amp;amp; Functions&lt;/h2&gt;
&lt;p&gt;One piece of convenience code that I extend my &lt;code&gt;NSManagedObject&lt;/code&gt; subclasses with is an &lt;code&gt;entityName&lt;/code&gt; property.&lt;/p&gt;
&lt;p&gt;This helps me avoid sprinkling the name of an Entity in &lt;code&gt;String&lt;/code&gt; form throughout my code.&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;extension&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;EntityName&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entityName&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;EntityName&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
When it comes to other types of functionality, my recommendation is to put that code elsewhere.&lt;/p&gt;
&lt;p&gt;Keep &lt;code&gt;NSManagedObject&lt;/code&gt;s about Core Data-y things.&lt;/p&gt;
&lt;p&gt;Ask, &amp;ldquo;Does this help my &lt;code&gt;NSManagedObject&lt;/code&gt; subclass work with Core Data-related functionality?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Let the answer to that question guide your decision about whether to extend your &lt;code&gt;NSManagedObject&lt;/code&gt; subclass with additional features.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Additional features&amp;rdquo; often translates to &amp;ldquo;additional responsibility&amp;rdquo;. Single responsibility is the name of the game if you can achieve it.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>On Core Data Object Fetching and Display Strategies</title>
      <link>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/on-core-data-object-fetching-and-display-strategies/</link>
      <pubDate>Fri, 14 Jun 2019 04:40:54 +0000</pubDate>
      
      <guid>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/on-core-data-object-fetching-and-display-strategies/</guid>
      <description>&lt;h2 id=&#34;setting-the-stage&#34;&gt;Setting the Stage&lt;/h2&gt;
&lt;p&gt;Suppose one of the &lt;code&gt;NSManagedObject&lt;/code&gt; subclasses from your Core Data data model looked like this:&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BlogIdea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSManagedObject&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;@NSManaged&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ideaTitle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;@NSManaged&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ideaDescription&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
Suppose that you also have a class that will provide &lt;code&gt;BlogIdeas&lt;/code&gt; to your view controller:&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BlogIdeaProvider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// fetches BlogIdea instances to use in your view controller&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;strong&gt;Requirement:&lt;/strong&gt; Say that you need to list all of the &lt;code&gt;ideaTitle&lt;/code&gt;s you have inside of a table view (note that you &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; need to display the &lt;code&gt;ideaDescription&lt;/code&gt; at this time).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Question:&lt;/strong&gt;  Which of the following strategies would you recommend for this requirement?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fetch all the &lt;code&gt;BlogIdea&lt;/code&gt; objects, return them, and then use those returned &lt;code&gt;NSManagedObject&lt;/code&gt; instances to display the &lt;code&gt;ideaTitle&lt;/code&gt; in the table view.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BlogIdeaProvider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fetchBlogIdeas&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlogIdea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// fetch BlogIdea instances&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// return the BlogIdea NSManagedObject subclass for the view controller to use&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Fetch all of the &lt;code&gt;BlogIdea&lt;/code&gt; objects, but make a &lt;code&gt;fetchBlogIdeaTitles&lt;/code&gt; function instead. Just return the &lt;code&gt;ideaTitle&lt;/code&gt;s, say, in an array of strings to display in the table view.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BlogIdeaProvider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;ln&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fetchBlogIdeaTitles&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// fetch BlogIdea instances&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// pull out ONLY the ideaTitle, &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// assemble an array for the titles, &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// return the array&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;swifting-out-loud&#34;&gt;Swifting Out Loud&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll give my recommendation and then walk through my reasoning.&lt;/p&gt;
&lt;p&gt;In nearly all situations, I would go with option number 1: fetch the &lt;code&gt;NSManagedObject&lt;/code&gt; instances that I need to display, and work with those fully-featured objects, rather than go through the effort to return only the &lt;code&gt;String&lt;/code&gt;s that I need for display.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To that, I&amp;rsquo;d ask the question:  &amp;ldquo;What are you planning to do &lt;em&gt;next&lt;/em&gt;, once the &lt;code&gt;ideaTitle&lt;/code&gt;s are displayed in the table view?&lt;/p&gt;
&lt;p&gt;Presumably, you&amp;rsquo;re displaying them &lt;em&gt;so that&lt;/em&gt; a user can tap on a cell and&amp;hellip;do something with them.  And that &amp;ldquo;do something with them&amp;rdquo; part almost always means&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Show &lt;em&gt;more&lt;/em&gt; details (in which case, you need the &lt;code&gt;ideaDescription&lt;/code&gt; property as well now)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Edit&lt;/em&gt; the object (in which case you get all your saving features only &lt;strong&gt;if&lt;/strong&gt; it&amp;rsquo;s in &lt;code&gt;NSManagedObject&lt;/code&gt; form)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Delete&lt;/em&gt; the object (again&amp;hellip;needs to be a full &lt;code&gt;NSManagedObject&lt;/code&gt; to easily delete)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;efficiency-trade-offs&#34;&gt;Efficiency Trade-offs&lt;/h2&gt;
&lt;p&gt;One might be concerned about efficiency &amp;ndash; &amp;ldquo;Why return a full object when you only need one of its properties?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s true. You only need one property&amp;hellip;&lt;em&gt;for now&lt;/em&gt;.  Again, I think it goes back to &amp;ldquo;what happens next?&amp;rdquo;&lt;/p&gt;
&lt;h3 id=&#34;fetching-efficiency&#34;&gt;Fetching Efficiency&lt;/h3&gt;
&lt;p&gt;Will you display the &lt;code&gt;ideaTitle&lt;/code&gt; and then have to go fetch &lt;em&gt;again&lt;/em&gt; to get the rest of what you need from your persistent store?  That&amp;rsquo;s almost guaranteed to be less efficient than holding the full &lt;code&gt;NSManagedObject&lt;/code&gt; in memory from the start.&lt;/p&gt;
&lt;h3 id=&#34;memory-efficiency&#34;&gt;Memory Efficiency&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re trying to stay memory-efficient, perhaps another idea is to fetch only a subset of the &lt;code&gt;BlogIdea&lt;/code&gt;s&amp;hellip; You could limit the number of results that come back (after all, only so many can be shown in a table view at a time, anyway, right?).&lt;/p&gt;
&lt;h3 id=&#34;code-efficiency&#34;&gt;Code Efficiency&lt;/h3&gt;
&lt;p&gt;When you say &amp;ldquo;Core Data&amp;rdquo; and &amp;ldquo;table view&amp;rdquo; in the same sentence, it should also trigger the word &lt;code&gt;NSFetchedResultsController&lt;/code&gt;.  This class is a huuuuge help because it was designed specifically for displaying data from &lt;code&gt;NSManagedObject&lt;/code&gt;s in table or collection views.  If you only return an array of &lt;code&gt;String&lt;/code&gt;s, you&amp;rsquo;ll have to write a bunch of boiler plate code yourself to keep your table view in sync with your persistent store, but you get all of that for free with &lt;code&gt;NSFetchedResultsController&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;NSFetchedResultsController&lt;/code&gt; would change the code a bit.  Instead of returning an array of blog ideas (&lt;code&gt;[BlogIdea]&lt;/code&gt;), you could hold a reference to a &lt;code&gt;NSFetchedResultsController&amp;lt;BlogIdea&amp;gt;&lt;/code&gt; and configure it to fetch:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// &lt;/span&gt;&lt;span class=&#34;cs&#34;&gt;MARK:&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt; - Concept&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// If you give a `Provider` a persistent container, and a fetched results controller delegate to talk back to,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// a `Provider` Type can act as a liaison between the view controller and the pieces of Core Data that are needed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// to initialize a fetched results controller, perform fetches, and other Core Data related actions on behalf of your&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// view controller (instead of you putting all this code in the view controller itself)...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BlogIdeaProvider&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;persistentContainer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSPersistentContainer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;weak&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fetchedResultsControllerDelegate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSFetchedResultsControllerDelegate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// &lt;/span&gt;&lt;span class=&#34;cs&#34;&gt;MARK:&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt; - Initializers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;persistentContainer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSPersistentContainer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;n&#34;&gt;fetchedResultsControllerDelegate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSFetchedResultsControllerDelegate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kc&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;persistentContainer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;persistentContainer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kc&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fetchedResultsControllerDelegate&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fetchedResultsControllerDelegate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// use this in your view controller to display BlogIdea instances&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;ln&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;lazy&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;fetchedResultsController&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSFetchedResultsController&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlogIdea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;// Configure a fetched results controller and perform an initial fetch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;23&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;blogIdeasFetchRequest&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSFetchRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlogIdea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;entityName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;BlogIdea&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;24&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;25&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;controller&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSFetchedResultsController&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BlogIdea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;fetchRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;blogIdeasFetchRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;26&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;                                                                &lt;span class=&#34;n&#34;&gt;managedObjectContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;persistentContainer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;viewContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;27&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;                                                                &lt;span class=&#34;n&#34;&gt;sectionNameKeyPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;28&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;                                                                &lt;span class=&#34;n&#34;&gt;cacheName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;29&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;controller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;delegate&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fetchedResultsControllerDelegate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;31&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;32&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;33&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;controller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;performFetch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;34&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;35&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;bp&#34;&gt;fatalError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;\(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;#function&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;: Failed to performFetch: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;\(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;36&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;37&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;38&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;controller&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;39&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;40&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;concluding-thoughts&#34;&gt;Concluding Thoughts&lt;/h2&gt;
&lt;p&gt;I know I keep going back to it, but I think it&amp;rsquo;s what will help make the decision.&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s the next thing you&amp;rsquo;re expecting to happen after you fetch the objects and display them?&lt;/p&gt;
&lt;p&gt;Let that be your guiding principle for your fetching and displaying strategy.&lt;/p&gt;
&lt;p&gt;With Core Data, it&amp;rsquo;s almost always going to be more convenient to be working with &lt;code&gt;NSManagedObject&lt;/code&gt;s.  Start there, and handle efficiency problems as they arise. 🙌🏻&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Getting Started With NSPersistentCloudKitContainer</title>
      <link>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/getting-started-with-nspersistentcloudkitcontainer/</link>
      <pubDate>Tue, 11 Jun 2019 04:40:54 +0000</pubDate>
      
      <guid>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/getting-started-with-nspersistentcloudkitcontainer/</guid>
      <description>&lt;h2 id=&#34;first-things-first&#34;&gt;First Things First&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;In order to use &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; in your app, you need to be targeting iOS 13+.&lt;/li&gt;
&lt;li&gt;The CloudKit syncing portion only works on physical devices (not in the simulator).  That being the case, you&amp;rsquo;ll need two or more devices running the app and using the same iCloud account to fully test things out and make sure syncing and data merging behavior works as you&amp;rsquo;d expect it to.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal of this walkthrough is to provide you with a fully-working example of performing and synchronizing create, read, update, and delete operations using &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s the project I wish I had for referencing the basics&amp;hellip;something &lt;strong&gt;beyond&lt;/strong&gt; the out-of-the-box, saving a list of timestamps that comes pre-implemented with a Master-Detail app, but something &lt;strong&gt;less complicated&lt;/strong&gt; than &lt;a href=&#34;https://developer.apple.com/documentation/coredata/synchronizing_a_local_store_to_the_cloud&#34; rel=&#34;nofollow&#34;&gt;Apple&amp;rsquo;s example project&lt;/a&gt; which ends up having several relationships involved in the data model, extra features configured on the persistent container, etc.&lt;/p&gt;
&lt;p&gt;I offer it to you as reference as well &amp;ndash; I hope it helps!&lt;/p&gt;
&lt;p&gt;&lt;a name=&#34;resources&#34; class=&#34;jump-target&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;resources&#34;&gt;
&lt;div class=&#34;resources-header&#34;&gt;
Resources
&lt;/div&gt;
&lt;ul class=&#34;resources-content&#34;&gt;
&lt;li&gt;
&lt;i class=&#34;fas fa-file-code&#34;&gt;&lt;/i&gt; &lt;a href=&#34;https://github.com/andrewcbancroft/BlogIdeaList&#34;&gt; Blog Idea List Example Xcode Project&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;i class=&#34;fas fa-link&#34;&gt;&lt;/i&gt; &lt;a href=&#34;https://developer.apple.com/videos/play/wwdc2019/202&#34; rel=&#34;nofollow&#34;&gt;Using Core Data With CloudKit - WWDC 2019 Session 202&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&#34;setup&#34;&gt;Setup&lt;/h2&gt;
&lt;p&gt;The easiest way to get stareted with &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; is to enable Core Data and CloudKit when you start your new project.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;enable-core-data-cloudkit.png&#34; alt=&#34;Enable Core Data and CloudKit&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;the-core-data--cloudkit-stack&#34;&gt;The Core Data + CloudKit Stack&lt;/h3&gt;
&lt;p&gt;Xcode provides the Core Data Stack code you need in the usual location: in the AppDelegate.swift file.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s one notable difference though.  Instead of initializing a normal &lt;code&gt;NSPersistentContainer&lt;/code&gt;, Xcode uses the new &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; (this is why it&amp;rsquo;s important to check the CloudKit box when you create your app).&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;nspersistentcloudkitcontainer-code.png&#34; alt=&#34;NSPersistentCloudKitContainer&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;what-about-existing-apps&#34;&gt;What About Existing Apps?&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;ve got an existing app that&amp;rsquo;s using a &amp;ldquo;regular&amp;rdquo; &lt;code&gt;NSPersistentContainer&lt;/code&gt;, you can change it to &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; and continue on from there!&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re not using &lt;code&gt;NSPersistentContainer&lt;/code&gt; with your app yet, &lt;a href=&#34;https://www.andrewcbancroft.com/2017/07/10/using-an-existing-sqlite-store-with-nspersistentcontainer/&#34;&gt;my guide on how to migrate&lt;/a&gt; may be of help!&lt;/p&gt;
&lt;h3 id=&#34;adding-capabilities&#34;&gt;Adding Capabilities&lt;/h3&gt;
&lt;p&gt;While Xcode auto-generates the Core Data + CloudKit stack for you, it does &lt;em&gt;not&lt;/em&gt; enable iCloud for you.&lt;/p&gt;
&lt;p&gt;To enable full functionality, you need to go to your &lt;strong&gt;Xcode project settings&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Then click on the &lt;strong&gt;Signing &amp;amp; Capabilities&lt;/strong&gt; section and add the &lt;strong&gt;iCloud&lt;/strong&gt; and &lt;strong&gt;Background Modes&lt;/strong&gt; capabilities.&lt;/p&gt;
&lt;p&gt;Check the &lt;strong&gt;CloudKit checkbox&lt;/strong&gt;, and the &lt;strong&gt;Remote Notifications checkbox&lt;/strong&gt;.&lt;/p&gt;
&lt;h4 id=&#34;add-icloud--cloudkit&#34;&gt;Add iCloud + CloudKit&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;add-icloud.gif&#34; alt=&#34;Add iCloud with CloudKit&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;add-background-modes--remote-notifications&#34;&gt;Add Background Modes + Remote Notifications&lt;/h4&gt;
&lt;p&gt;&lt;img src=&#34;add-background-modes.gif&#34; alt=&#34;Add Background Modes with Remote Notifications&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;what-about-registering-for-remote-notifications&#34;&gt;What About Registering for Remote Notifications?&lt;/h3&gt;
&lt;p&gt;The beauty of &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; is that it handles all the work required to listen for and respond to remote notifications.&lt;/p&gt;
&lt;p&gt;This means that data saved locally on &lt;em&gt;one&lt;/em&gt; device gets pushed up to iCloud synced back down to &lt;em&gt;another&lt;/em&gt; device automatically.&lt;/p&gt;
&lt;h3 id=&#34;what-about-my-data-model-in-icloud&#34;&gt;What About My Data Model in iCloud?&lt;/h3&gt;
&lt;p&gt;When you enable the iCloud capability for your app, Xcode automatically creates a container for your app in the CloudKit Dashboard.&lt;/p&gt;
&lt;p&gt;It does &lt;em&gt;not&lt;/em&gt;, however, create a schema that matches your Core Data model&amp;hellip;yet.  This is a setting you can toggle, but the default behavior is to &lt;a href=&#34;#revisiting-the-icloud-schema&#34;&gt;&amp;ldquo;lazily&amp;rdquo; create the schema&lt;/a&gt; as people create objects and save them to your persistent store.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;empty-schema.gif&#34; alt=&#34;Empty Schema&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;walking-through-the-example-project&#34;&gt;Walking Through the Example Project&lt;/h2&gt;
&lt;p&gt;WWDC always gets the blog ideas flowing through my brain, so this little app&amp;rsquo;s theme is &amp;ldquo;saving a list of blog ideas&amp;rdquo;, both locally, and &lt;em&gt;across&lt;/em&gt; my devices using &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;user-interface&#34;&gt;User Interface&lt;/h3&gt;
&lt;p&gt;The user interfacde allows you to perform the essential operations of a data-driven app:  create, read, update, and delete objects.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;user-interface.png&#34; alt=&#34;User Interface&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;data-model&#34;&gt;Data Model&lt;/h3&gt;
&lt;p&gt;The data model for this is basic:  a single &lt;code&gt;BlogIdea&lt;/code&gt; Entity with two &lt;code&gt;String&lt;/code&gt; properties: &lt;code&gt;ideaTitle&lt;/code&gt; and &lt;code&gt;ideaDescription&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;data-model.png&#34; alt=&#34;BlogIdea Data Model&#34;&gt;&lt;/p&gt;
&lt;p&gt;No relationships or extra configuration options&amp;hellip; just one Entity to keep it a basic reference-able project.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;BlogIdea&lt;/code&gt; NSManagedObject subclass is implemented like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BlogIdea&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSManagedObject&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;@NSManaged&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ideaTitle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;@NSManaged&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ideaDescription&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;entityName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;String&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;BlogIdea&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;view-controllers&#34;&gt;View Controllers&lt;/h3&gt;
&lt;p&gt;There are two view controllers that come with this example:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MainViewController&lt;/strong&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;MainViewController&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;   &lt;span class=&#34;n&#34;&gt;UIViewController&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                            &lt;span class=&#34;n&#34;&gt;NSFetchedResultsControllerDelegate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                            &lt;span class=&#34;n&#34;&gt;UITableViewDataSource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                            &lt;span class=&#34;n&#34;&gt;UITableViewDelegate&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Responsible for listing out BlogIdeas in a table view&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Holds a reference to an NSManagedObjectContext instance&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// which gets initialized in the SceneDelegate.swift file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// and passed to this view controller when the scene gets &amp;#34;connected&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Uses NSFetchedResultsController to keep the table view in sync&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// with the Core Data managed object context&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Implements swipe-to-delete with delete confirmation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Navigates to editor when someone taps on a table view row&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// and passes its NSManagedObjectContext instance along&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;strong&gt;BlogIdeaEditorViewController&lt;/strong&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;BlogIdeaEditorViewController&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UIViewController&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Responsible for creating new BlogIdeas&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Holds a reference to an NSManagedObjectContext instance&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// which gets passed along in MainViewController&amp;#39;s prepare for segue method&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Able to edit existing BlogIdeas&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&#34;understanding-the-default-sync-behavior&#34;&gt;Understanding the Default Sync Behavior&lt;/h2&gt;
&lt;p&gt;At this point no additional configuration has happened. The Core Data stack is the unmodified Xcode generated code, and the fetched results controller is hooked up to the managed object context for your app, ready to fetch Blog Ideas and help get them into the table view.&lt;/p&gt;
&lt;p&gt;If you open the project, build and run on two devices, and begin adding Blog Ideas, updating them, deleting them, etc. what happens?&lt;/p&gt;
&lt;p&gt;The first observation is that&amp;hellip;things&amp;hellip;don&amp;rsquo;t&amp;hellip;seem to be working&amp;hellip;&lt;/p&gt;

&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
  &lt;iframe src=&#34;https://www.youtube.com/embed/DLAwrSCl3Cc&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allowfullscreen title=&#34;YouTube Video&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;&amp;hellip;At least not how I thought they would.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;expected&lt;/em&gt; my Blog List view to automatically update in response to changes made on my other device, buuut&amp;hellip; nope.  Thankfully it&amp;rsquo;s an &amp;ldquo;easy&amp;rdquo; fix.&lt;/p&gt;
&lt;h2 id=&#34;reflecting-changes-in-the-ui&#34;&gt;Reflecting Changes in the UI&lt;/h2&gt;
&lt;p&gt;Wherever you access your app&amp;rsquo;s persistent CloudKit container to grab the &lt;code&gt;viewContext&lt;/code&gt;, you need to set the &lt;code&gt;automaticallyMergesChangesFromParent&lt;/code&gt; property to &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I initialize the container in the &lt;code&gt;SceneDelegate&lt;/code&gt;, so check out the code exerpt below to see where that gets set.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SceneDelegate.swift&lt;/strong&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;scene&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;scene&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UIScene&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;willConnectTo&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;session&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UISceneSession&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;options&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;connectionOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UIScene&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ConnectionOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;guard&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;scene&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UIWindowScene&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;navigationController&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;window&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rootViewController&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UINavigationController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mainVC&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;navigationController&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;viewControllers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MainViewController&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;viewContext&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UIApplication&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shared&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;delegate&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;AppDelegate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;persistentContainer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;viewContext&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;viewContext&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;automaticallyMergesChangesFromParent&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;mainVC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;managedObjectContext&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;viewContext&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Making this one-line change will enable the app (which is supported by &lt;code&gt;NSFetchedResultsController&lt;/code&gt;) to update the UI in response to remote data changes&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;eventually&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It can be slow (anywhere from 5 to 15 seconds).  But it will eventually update.&lt;/p&gt;
&lt;h2 id=&#34;revisiting-the-icloud-schema&#34;&gt;Revisiting the iCloud Schema&lt;/h2&gt;
&lt;p&gt;Once you save an object, the schema within the iCloud Dashboard will update to reflect the properties you designed in your Core Data Model.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;revisit-schema.png&#34; alt=&#34;Revisiting the Schema&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;wheres-my-data&#34;&gt;Where&amp;rsquo;s My Data?&lt;/h2&gt;
&lt;p&gt;If you attempt to query for BlogIdea records in any of the iCloud databases provisioned for your app, you won&amp;rsquo;t find any.&lt;/p&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s because Apple fully manages a hidden Zone for your Core Data + CloudKit data. It was veeeery briefly mentioned in the &lt;a href=&#34;https://developer.apple.com/videos/play/wwdc2019/202&#34; rel=&#34;nofollow&#34;&gt;WWDC 2019 presentation&lt;/a&gt; (right about 10:50 if you&amp;rsquo;re watching).&lt;/p&gt;
&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;My hope was to provide you with a fully-working example of performing and synchronizing create, read, update, and delete operations using &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Check out the &lt;a href=&#34;https://github.com/andrewcbancroft/BlogIdeaList&#34;&gt;GitHub repo&lt;/a&gt;, leave a comment, or &lt;a href=&#34;https://twitter.com/andrewcbancroft&#34;&gt;@ me on Twitter&lt;/a&gt; to continue the conversation from here!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>First Impressions of NSPersistentCloudKitContainer</title>
      <link>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/first-impressions-of-nspersistentcloudkitcontainer/</link>
      <pubDate>Thu, 06 Jun 2019 04:40:54 +0000</pubDate>
      
      <guid>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/first-impressions-of-nspersistentcloudkitcontainer/</guid>
      <description>&lt;p&gt;&lt;a name=&#34;resources&#34; class=&#34;jump-target&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;resources&#34;&gt;
&lt;div class=&#34;resources-header&#34;&gt;
Resources
&lt;/div&gt;
&lt;ul class=&#34;resources-content&#34;&gt;
&lt;li&gt;
&lt;i class=&#34;fas fa-link&#34;&gt;&lt;/i&gt; &lt;a href=&#34;https://developer.apple.com/videos/play/wwdc2019/202&#34; rel=&#34;nofollow&#34;&gt;Using Core Data With CloudKit - WWDC 2019 Session 202&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;i class=&#34;fas fa-file-code&#34;&gt;&lt;/i&gt; &lt;a href=&#34;https://developer.apple.com/documentation/coredata/synchronizing_a_local_store_to_the_cloud&#34; rel=&#34;nofollow&#34;&gt;Sample Project from Apple&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&#34;how-nspersistentcloudkitcontainer-helps&#34;&gt;How NSPersistentCloudKitContainer Helps&lt;/h2&gt;
&lt;p&gt;I suppose the first question everyone should ask is, &amp;ldquo;What&amp;rsquo;s the big deal?  How does &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; even help me?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I noted at least &lt;strong&gt;three huge wins&lt;/strong&gt; from the &lt;a href=&#34;https://developer.apple.com/videos/play/wwdc2019/202&#34; rel=&#34;nofollow&#34;&gt;WWDC 2019 session&lt;/a&gt;.  Ask yourself&amp;hellip;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&amp;ldquo;Do I want to figure out how to retrieve data from CloudKit and merge it with my local Core Data persistent store on my own?&amp;rdquo; &amp;ndash; No?  Me either. 😃&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; handles making a local replica of your app&amp;rsquo;s CloudKit data.&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&amp;ldquo;Do I want to implement synchronization schedluing and all the error handling that comes with CloudKit?&amp;rdquo; &amp;ndash; I &lt;em&gt;definitely&lt;/em&gt; don&amp;rsquo;t&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; handles scheduling CloudKit operations, and takes your &lt;code&gt;// handle errors&lt;/code&gt; placeholder code (👀) and actually implements it the right way internally. #sweet&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&amp;ldquo;Do I want to map between &lt;code&gt;NSManagedObjects&lt;/code&gt; and &lt;code&gt;CKRecords&lt;/code&gt; by hand?&amp;rdquo; &amp;ndash; Not if that could be automagic!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; handles transforming your &lt;code&gt;NSManagedObjects&lt;/code&gt; into &lt;code&gt;CKRecords&lt;/code&gt; as well.&lt;/p&gt;
&lt;h2 id=&#34;exciting-times&#34;&gt;Exciting Times&lt;/h2&gt;
&lt;p&gt;Apple did a lot of work to &lt;strong&gt;encapsulate a very common set of code patterns&lt;/strong&gt; that were necessary for implementing an app with Core Data and CloudKit.&lt;/p&gt;
&lt;p&gt;They claim to be able to &lt;strong&gt;save us thousands of lines of code&lt;/strong&gt; (and I believe it!).&lt;/p&gt;
&lt;p&gt;I have an app that uses Core Data locally. I&amp;rsquo;ve been wanting to enable CloudKit on, so that data is synced across my users&amp;rsquo; devices.  Every time I think about what it&amp;rsquo;ll take to get the Core Data pieces talking the on the same wavelength as the CloudKit pieces, I just dread the inevitable headache that would ensue.  So I run away.  😬&lt;/p&gt;
&lt;p&gt;My hope is to see what it&amp;rsquo;s like to enable &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt; with that existing app.  I&amp;rsquo;ll be sure to document the journey!&lt;/p&gt;
&lt;h1 id=&#34;dipping-a-toe-in&#34;&gt;Dipping a Toe In&lt;/h1&gt;
&lt;p&gt;Just a couple of tidbits about the setup process for getting started with this new class&amp;hellip;&lt;/p&gt;
&lt;h2 id=&#34;enabling-core-data--cloudkit&#34;&gt;Enabling Core Data + CloudKit&lt;/h2&gt;
&lt;p&gt;While it&amp;rsquo;s not &lt;em&gt;absolutely&lt;/em&gt; required to check these checkboxes, Xcode will provide you with some of the boilerplate code necessary for working with Core Data and CloudKit &lt;strong&gt;together&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;enable-coredata-cloudkit.png&#34; alt=&#34;Check Use Core Data + CloudKit&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;starting-point&#34;&gt;Starting Point&lt;/h2&gt;
&lt;p&gt;Xcode generates some code in your AppDelegate.swift file to initialize the Core Data Stack, only this time, instead of a standard &lt;code&gt;NSPersistentContainer&lt;/code&gt;, it initializes the new &lt;code&gt;NSPersistentCloudKitContainer&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-swift&#34; data-lang=&#34;swift&#34;&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 1&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;lazy&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;persistentContainer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSPersistentCloudKitContainer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 2&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;container&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSPersistentCloudKitContainer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;NSPersistentCloudKitContainer_First_Steps&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 3&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;container&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loadPersistentStores&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;completionHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;storeDescription&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 4&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;error&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NSError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 5&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;c1&#34;&gt;// Replace this implementation with code to handle the error appropriately.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 6&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;bp&#34;&gt;fatalError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Unresolved error &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;\(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;, &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;\(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;userInfo&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 7&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 8&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt; 9&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;ln&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;not-ready-yet-more-to-enable&#34;&gt;Not Ready Yet (more to enable)&lt;/h2&gt;
&lt;h4 id=&#34;enable-cloudkit-capability&#34;&gt;Enable CloudKit Capability&lt;/h4&gt;
&lt;p&gt;Since you&amp;rsquo;re working with CloudKit in this scenario, you still need to &lt;em&gt;enable&lt;/em&gt; CloudKit so that your app has the appropriate &lt;strong&gt;entitlements&lt;/strong&gt;, and so that your app&amp;rsquo;s &lt;strong&gt;CloudKit container&lt;/strong&gt; gets created in iCloud.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;enable-icloud.gif&#34; alt=&#34;Enable iCloud&#34;&gt;&lt;/p&gt;
&lt;h4 id=&#34;enable-remote-notifications&#34;&gt;Enable Remote Notifications&lt;/h4&gt;
&lt;p&gt;CloudKit also uses Push Notifications to alert your app to data changes coming in from other devices.  To get these notifications, you need to enable the Remote Notifications capability for your app as well.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;enable-remote-notifications.gif&#34; alt=&#34;Enable Remote Notifications&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;When it comes to learning what to do next, &lt;a href=&#34;https://developer.apple.com/documentation/coredata/synchronizing_a_local_store_to_the_cloud&#34; rel=&#34;nofollow&#34;&gt;Apple has provided a sample project&lt;/a&gt; that I hope to examine and take apart.&lt;/p&gt;
&lt;p&gt;More to come!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Resolving Failed to Load Model Named... with Core Data</title>
      <link>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/resolving-core-data-failed-to-load-model-named/</link>
      <pubDate>Thu, 06 Jun 2019 04:40:54 +0000</pubDate>
      
      <guid>https://www.andrewcbancroft.com/blog/ios-development/data-persistence/resolving-core-data-failed-to-load-model-named/</guid>
      <description>&lt;p&gt;You&amp;rsquo;ve done the work to get your Core Data model ready, but right when you hit run, &lt;em&gt;wham&lt;/em&gt;.  Your debug output log shows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Failed to load model named &lt;strong&gt;ModelName&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You you may experience one of these when you attempt to access your persistent container:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What in the world is going on?&lt;/p&gt;
&lt;h2 id=&#34;double-check-target-membership&#34;&gt;Double-check Target Membership&lt;/h2&gt;
&lt;p&gt;This is particularly important if you happend to have copied and pasted and &lt;code&gt;.xcdatamodeld&lt;/code&gt; file between projects.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;target-membership.png&#34; alt=&#34;Check Target Membership&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;double-check-model-name&#34;&gt;Double-check Model Name&lt;/h2&gt;
&lt;p&gt;Your model name needs to match throughout the various places you refer to it.  Things can get out of sync if you ever rename your model.&lt;/p&gt;
&lt;p&gt;Check to make sure that the following all match:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;YourModelName&lt;/strong&gt;.xcdatamodeld&lt;/li&gt;
&lt;li&gt;let container = NSPersistentContainer(name: &amp;ldquo;&lt;strong&gt;YourModelName&lt;/strong&gt;&amp;rdquo;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&#34;match-model-names.png&#34; alt=&#34;Model Names Must Match&#34;&gt;&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>