RSS

Core Data in iCloud

03 Apr

Introduction

The aim of this tutorial is to show how to add iCloud support to a project.  The starting point will be the final project from the end of the Core Data Universal / iPad Storyboard tutorial. I would recommend going through that tutorial first so you’re familiar with the Staff Manager project.

Prerequisites

Download the final project from the end of the Core Data Universal / iPad Storyboard tutorial. Extract and open it with Xcode.
Note: iCloud does NOT work in the iOS Simulator. I recommend testing on two devices, such as an iPad and an iPhone at the same time.

Create iCloud Staff Manager App ID

Head over to https://developer.apple.com/membercenter/ then enter the iOS Provisioning Portal.  The link looks like this:

Select App IDs

Select New App ID

Configure the App ID as follows then click Submit:

Click Configure:

Tick Enable for iCloud then click Done:

iCloud is now enabled for Staff Manager:

You will notice that the App ID has a prefix of the Team ID.  You will have a different Team ID prefix to me.  You will need to substitute your own prefix whenever you see my prefix in code:


To use the new App ID you’ll need a new Provisioning Profile so click Provisioning then New Profile:

Configure the Provisioning Profile as follows:

Click Submit then download your new profile.  If you can’t see the Download button refresh the page:

Once you have downloaded the provisioning profile file double click it which will automatically import it into Xcode:

In Xcode, configure the Staff Manager Code Signing Identity to use the new Provisioning Profile:

Enable Staff Manager Entitlements

To use the iCloud App ID we’ve just created we need to enable some Entitlements. Select the Staff Manager Targets:

Scroll to the Entitlements section (down the bottom) then configure it as follows:

Configure Core Data for iCloud

Currently the Persistent Store (StaffManager.sqlite) is stored on the local device. Once configured for iCloud it will still reside locally yet in a special iCloud enabled directory.

After poring through many approaches for enabling iCloud + Core Data I’ve come up with some succinct code used to create the persistent store. For re-usability and clarity the following variables are used:

  • iCloudEnabledAppID is the full App ID (including the Team Prefix). You will need to change this to match the Team Prefix found in your own iOS Provisioning Portal.
  • dataFile is the name of the SQLite database store file.
  • iCloud is the URL to your apps iCloud root path.
  • dataDirectory is the name of the directory the database will be stored in. It should always end with .nosync
  • logsDirectory is the name of the directory the database change logs will be stored in.
  • iCloudData = iCloud + dataDirectory
  • iCloudLogs = iCloud + logsDirectory

The upcoming code is responsible for returning a NSPersistentStoreCoordinator. Most of it is for setting what/where data and logs will be stored. The options NSMutableDictionary is used to set some new important options:

  • NSPersistentStoreUbiquitousContentNameKey will become the iCloud root (based on App ID)
  • NSPersistentStoreUbiquitousContentURLKey will become the change logs area.

Delete everything within the persistentStoreCoordinator method of AppDelegate.m then paste in the following code:

    if((__persistentStoreCoordinator != nil)) {
        return __persistentStoreCoordinator;
    }
 
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];    
    NSPersistentStoreCoordinator *psc = __persistentStoreCoordinator;
 
    // Set up iCloud in another thread:
 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 
        // ** Note: if you adapt this code for your own use, you MUST change this variable:
        NSString *iCloudEnabledAppID = @"5KFJ75859U.Tim-Roadley.Staff-Manager";
 
        // ** Note: if you adapt this code for your own use, you should change this variable:        
        NSString *dataFileName = @"StaffManager.sqlite";
 
        // ** Note: For basic usage you shouldn't need to change anything else
 
        NSString *iCloudDataDirectoryName = @"Data.nosync";
        NSString *iCloudLogsDirectoryName = @"Logs";
        NSFileManager *fileManager = [NSFileManager defaultManager];        
        NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
        NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
 
        if (iCloud) {
 
            NSLog(@"iCloud is working");
 
            NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
 
            NSLog(@"iCloudEnabledAppID = %@",iCloudEnabledAppID);
            NSLog(@"dataFileName = %@", dataFileName); 
            NSLog(@"iCloudDataDirectoryName = %@", iCloudDataDirectoryName);
            NSLog(@"iCloudLogsDirectoryName = %@", iCloudLogsDirectoryName);  
            NSLog(@"iCloud = %@", iCloud);
            NSLog(@"iCloudLogsPath = %@", iCloudLogsPath);
 
            if([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
                NSError *fileSystemError;
                [fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName] 
                       withIntermediateDirectories:YES 
                                        attributes:nil 
                                             error:&fileSystemError];
                if(fileSystemError != nil) {
                    NSLog(@"Error creating database directory %@", fileSystemError);
                }
            }
 
            NSString *iCloudData = [[[iCloud path] 
                                     stringByAppendingPathComponent:iCloudDataDirectoryName] 
                                    stringByAppendingPathComponent:dataFileName];
 
            NSLog(@"iCloudData = %@", iCloudData);
 
            NSMutableDictionary *options = [NSMutableDictionary dictionary];
            [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
            [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
            [options setObject:iCloudEnabledAppID            forKey:NSPersistentStoreUbiquitousContentNameKey];
            [options setObject:iCloudLogsPath                forKey:NSPersistentStoreUbiquitousContentURLKey];
 
            [psc lock];
 
            [psc addPersistentStoreWithType:NSSQLiteStoreType 
                              configuration:nil 
                                        URL:[NSURL fileURLWithPath:iCloudData] 
                                    options:options 
                                      error:nil];
 
            [psc unlock];
        }
        else {
            NSLog(@"iCloud is NOT working - using a local store");
            NSMutableDictionary *options = [NSMutableDictionary dictionary];
            [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
            [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
 
            [psc lock];
 
            [psc addPersistentStoreWithType:NSSQLiteStoreType 
                              configuration:nil 
                                        URL:localStore 
                                    options:options 
                                      error:nil];
            [psc unlock];
 
        }
 
        dispatch_async(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged" object:self userInfo:nil];
        });
    });
 
    return __persistentStoreCoordinator;

Comment out the following code found in the didFinishLaunchingWithOptions method of AppDelegate.m :

    /*
    [self setupFetchedResultsController];
 
    if (![[self.fetchedResultsController fetchedObjects] count] > 0 ) {
        NSLog(@"!!!!! ~~> There's nothing in the database so defaults will be inserted");
        [self importCoreDataDefaultRoles];
    }
    else {
        NSLog(@"There's stuff in the database so skipping the import of default data");
    }
    */

Configure Notifications

When underlying data changes unfortunately the table views have no idea. To fix this we need to get them to watch for stuff changing notifications. First we need to configure the managedObjectContext so replace the managedObjectContext method in AppDelegate.m with the following two methods:

- (NSManagedObjectContext *)managedObjectContext {
 
    if (__managedObjectContext != nil) {
        return __managedObjectContext;
    }
 
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
 
    if (coordinator != nil) {
        NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
 
        [moc performBlockAndWait:^{
            [moc setPersistentStoreCoordinator: coordinator];
            [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(mergeChangesFrom_iCloud:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:coordinator];
        }];
        __managedObjectContext = moc;
    }
 
    return __managedObjectContext;
}
 
- (void)mergeChangesFrom_iCloud:(NSNotification *)notification {
 
	NSLog(@"Merging in changes from iCloud...");
 
    NSManagedObjectContext* moc = [self managedObjectContext];
 
    [moc performBlock:^{
 
        [moc mergeChangesFromContextDidSaveNotification:notification]; 
 
        NSNotification* refreshNotification = [NSNotification notificationWithName:@"SomethingChanged"
                                                                            object:self
                                                                          userInfo:[notification userInfo]];
 
        [[NSNotificationCenter defaultCenter] postNotification:refreshNotification];
    }];
}

That code tells the Managed Object Context to post notifications when iCloud updates data. To use those notifications add the following method to RolesTVC.m and PersonsTVC.m:

- (void)reloadFetchedResults:(NSNotification*)note {
    NSLog(@"Underlying data changed ... refreshing!");
    [self performFetch];
}

Also add the following to the end of the viewDidLoad method of RolesTVC.m and PersonsTVC.m:

    // Refresh this view whenever data changes
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(reloadFetchedResults:)
                                                 name:@"SomethingChanged"
                                               object:[[UIApplication sharedApplication] delegate]];

Finally, add the following method to RolesTVC.m and PersonsTVC.m which cleans up a little:

- (void)viewDidUnload {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

That’s it!

Run the app on the iPad and iPhone at the same time. You should see changes made on one device reflected on the other pretty quickly.

There are a couple of things I’m not entirely happy with just yet and will work to resolve soon. These are:

  • Saving every keystroke for the purpose of updating the master split view isn’t fast.
  • Importing default data.

Hopefully you have enough information to get you started with iCloud anyway.

Here’s the complete source code so far

If you liked this tutorial or found something wrong with it please let me know!

If you want to support my work and have an iPad please consider purchasing iSoccer or making a small donation. I’m saving for a Retina Tutorial iPad!!

-Tim

Go to the Tutorials Index


Be Sociable, Share!
     

    About Tim Roadley

    I'm a senior analytics software consultant at eMite Pty Ltd primarily focused on delivering business intelligence dashboards, currently for one of Australia’s major banks. I'm also working on a revamped version of eMite's iOS App for release under iOS 7. Prior to eMite, I was Infrastructure Manager at Cuscal Pty Ltd where I was heavily involved in designing and implementing a payments switch that drives 1300+ ATM’s Australia wide. I have several apps on the App Store, including Teamwork, iSoccer and now Grocery Dude and Grocery Cloud. In my down time I enjoy spending time with my wonderful wife Tracey and two lovely children Tyler and Taliah.
    114 Comments

    Posted by on April 3, 2012 in iOS Tutorials

     

    114 Responses to Core Data in iCloud

    1. John in Denver

      April 20, 2013 at 11:11 pm

      This is an excellent starting point and we have it working in a production environment successfully with my data driven core data app. However, there is quite a bit of work that needs to be done to have and app that can make it into the store. Even using a device that is network and iCloud enabled there is an almost 100% chance of a crash the first time you run the app and it attempts to setup the iCloud, at best it will time out trying to sync which is also considered a crash. In subsequent attempts it will ultimately function, However the store testers will reject the app after the first crash of course.

      Anyway, as a starting point on initialization you need to check network and iCloud availability and respond accordingly, ask if the user wants to use iCloud the first time and show some sort of a status or progress indicator since it can take several minutes to sync iCloud the first time. These changes will eliminate the crashes and get the app approved. Next you need to consider how you handle keeping multiple devices in sync. Apple enumerates some examples, but provides no solutions.

      When I first got Tim’s code working my thought was, “this is way too easy” and I was correct!

       
      • Tim Roadley

        April 21, 2013 at 8:52 am

        John,

        I agree entirely!

        My book will cover the remaining parts to get iCloud stable, including:

        – Allowing the user to toggle their preference on using iCloud
        – Checking that a user is signed in and wants to use iCloud before loading the iCloud store
        – Handling iCloud account switches by maintaining an iCloud cache store per-user
        – Showing a loading dialogue while iCloud loads
        – Prevention of log file corruption using NSFilePresenter
        – De-duplication
        – Seeding data to iCloud (once)
        – Getting visibility of what’s in iCloud

        ..and a few more things!

        Cheers

         
    2. jc

      April 27, 2013 at 12:08 am

      Hi. I have to say it’s the most detailed tutorial I could find. Could you explain a few moments which are not quite clear?
      1. What is the purpose of lock of the persistentStoreCoordinator before performing ‘addPersistentStoreWithType:configuration:URL:options:error’ method?
      2. You place database store file depending on whether iCloud available or not. But what if user will activate iCloud later? In this case the app creates two different copies of store, right? Can we better place store file in some local store outside of iCloud container (applicationDocumentsDirectory) not relying on whether iCloud available or not, and just set LogsPath (if exists) during PersistentStoreCoordinator’s initialization?
      Thank you for advise.

       
      • Tim Roadley

        May 13, 2013 at 1:24 pm

        Hi JC, sorry for the late reply.

        1. You could get away without using the psc lock if everything is configured on the main thread.
        2. Handling complex scenarios such as a user changing their preference on using iCloud or switching accounts is covered in my book. It’s a quite a deep topic. iCloud is covered in 2 chapters (iCloud & Taming iCloud). The second of the two also covers seeding and deduplication strategies. The book will be released in October and the rough cut of the iCloud chapters will be available soon.

        Cheers

         
    3. m3rLin0

      June 4, 2013 at 7:37 pm

      Hi, where i can buy your book (PDF format) that cover all iCloud integration with CoreData?

      Thank You
      Andrea

       
    4. kshitij godara

      June 18, 2013 at 7:53 pm

      hey can you tell me that , if i want to take backup on button press and load on my will .

       
    5. Mikael Hellqvist

      July 7, 2013 at 5:05 am

      Hi Tim, thanks for a great tutorial! Going to use your solution in my Mac/iOS app.

      Just wondering, how will this work with iOS 7? I know Apple made some changes (saw it on the session videos). Will your solution work in the future?

       
      • eyestach

        September 21, 2013 at 12:51 am

        Mikael, I hope you can find something useful in a thread I found after reading your question. Good luck. https://devforums.apple.com/message/858314#858314
        Mark

         
      • eyestach

        October 28, 2013 at 3:05 am

        Hi Mikael!

        iCloud CoreData iOS7 Syncing OS X app with iOS app: for Mavericks and 10.9 only

        I am hoping you can help me.

        I will begin by outlining my needs and what I believe to be true and then finally ask my questions.

        I studied this year’s great Apple presentation on iCloud CoreData, “iCloud 207.mov” .

        I believe, I understand most of what I will need to do to update the current up when the user upgrades to the new OS versions, including a DB move from Documents to another sandbox Folder.

        I wish to release two apps, one requiring OS X Mavericks and one requiring iOS 7.
        They share the same datamodel and both exist now (without iCloud support) and function under 10.8 and 6.0 respectively.
        The datamodel has not yet changed in the move towards iOS7.

        I want to sync the data between both apps.
        Entitlements list two containers, for the two apps. The two containers are ordered this way
        com.xyz.myMacApp
        and
        com.xyz.myiOSApp
        For the iOS app the order is reversed.

        The new API allows the location of the desired PS’s with:

        [aFileManager URLForUbiquitousContainerIdentifier:@”com.xyz.myMacApp”];

        I believe I understand most of the video including the following changes for iOS 7 found in the following code:

        NSDictionary *options = @{
        NSPersistentStoreUbiquitousContentNameKey: @”Store”,
        NSPersistentStoreUbiquitousContentURLKey: @”Subdir”,
        //case specific: NSPersistentStoreUbiquitousContainerIdentifierKey: @”com.myapp.bundleID”
        };

        Questions:

        How to I get the data from the two stores to join together into a View, namely a TableView, whose data supply is already (iOS6) done by the PSC?

        Do I simply (case 1) add the two persistent stores to a single PSC , and have the necessary merging work done auto-magically with my existing code, starting with the NSPersistentStoreDidImportUbiquitousContentChangesNotification
        handler? Or (case 2) is it two PSC’s each with one PS?
        It seems to me, that the use of two PSCs would definitely result in duplicates in the data display.

        Will I, after choosing the correct case (1 or 2), have to deal with removing duplicates by filtering fetches and by adding a UUID’s to relavent entities in the data model. The two sets of .cdt files are going to be almost identical?

        Many thanks for reading this, Mark

         
        • Tim Roadley

          October 28, 2013 at 9:42 am

          Mark,

          If neither the OSX or iOS apps currently use iCloud, that will make this easier. You _must_ use the same container identifier key for the OSX and iOS apps, for example:

          NSDictionary *options = @{
          NSPersistentStoreUbiquitousContentNameKey: @”Store”,
          NSPersistentStoreUbiquitousContentURLKey: @”Subdir”,
          NSPersistentStoreUbiquitousContainerIdentifierKey: @”com.xyz.myMacANDiOSApp”
          };

          Once you have a common iCloud store, you’ll need to seed the local data from OSX and iOS to iCloud. This will potentially create duplicates, so you will need to handle de-duplication. The seeding and de-duplication process is covered in Chapter 14 and 15 of my upcoming book: http://www.informit.com/store/learning-core-data-for-ios-a-hands-on-guide-to-building-9780321905765. This is quite a complicated topic!

          Cheers,

          Tim

           
        • eyestach

          October 28, 2013 at 12:55 pm

          Tim,

          Thanks so very much for your kind continued help. Congratulations on you upcoming book! I just now preordered your book – totally out of self interest. Considering your track record, expertise, site, family, job and more, I certainly hope that my fellow visitors to your site will consider the benefits they have had from their association with you and all the benefits that your new book has to offer and then buy your book too!

          An admirer wishing you continued success,
          Mark

           
        • Tim Roadley

          October 28, 2013 at 1:36 pm

          You’re most welcome and thank you for your pre-order! I sincerely hope that the book is extremely useful to you! I only wish it were already available, these printing presses take ages :)

          Cheers,

          Tim

           
    6. kshitij godara

      August 7, 2013 at 4:47 pm

      hey Tim , your code helped me lot , but suddenly its started me giving error — This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation. i am striking my head on this from many days. Can you please tell me why is this happening ?

       
      • Pristy

        August 15, 2013 at 4:02 am

        Kshitij godara, Have u got ur problem resolved?

         
    7. Rohit

      September 10, 2013 at 11:54 pm

      Hi Tim, Thanks for the beautiful article. I have integrated the iCloud to my App as you have suggested. The data is able to sync on the iClouds, but my app is not receiving the notification “NSPersistentStoreDidImportUbiquitousContentChangesNotification”. Please suggest.

       
    8. eyestach

      September 11, 2013 at 5:30 am

      Tim,

      I have admired your good and sharing work. Still, I claim that your current iCloud Tutorial app will work only if you connect your devices to the cloud and never disconnect any of them.
      If you connect say three devices and keep them syncing, all will be AOK. Problems arise when you disconnect one and then reconnect it after additions of objects to any of the other devices.
      I believe that you will get crashes then unless you delete your DB on the once joined and now disconnected device, thereby becoming a “new device’. The way around it (for an app with a ‘simple datamodel’) is Drew McCormack’s Sentinel Class and in place data migration.

      Google “Under the Sheets with iCloud and Core Data”. Great Reading.

      What you need, I think, is Drew’s Blog at MentalFaculty. I hope to facilitate your encounter with his thinking, If you have not already done so.

      I have the app up and running on my Mac and in VMWare – once I added the UDID for the VMWare machine.

      Really, I suspect you know all this already, but others may not.

      I can only add to the mix, a bit of text below that serves as the basis of Tool Tips for five of the six buttons on Drew’s Mac app, iCloudCoreDataTester.app’s MainMenu.xib. For me, an iCloud beginner, these Tool Tips are helpful, when working with Drew’s app. This app,IMHO, is a great learning tool, which a beginner must master, before attempting to incorporate Drew’s code and into his own app, to create a commercial app.

      Mark

      16. setupCoreDataStack
      if ( !stackIsSetup && !stackIsLoading ) { makePSC,addStoreToPSC, if(success){ tearDownStack} else{ makeMOC; if(DEF==YES) updateDevList;}

      17. removeLocalFiles
      save
      tearDown (if stackExists)
      setBool:NO forKey:MCUsingCloudStorageDefault
      removeApplicationDirectory i,e, localStore
      18. removeCloudFiles
      save
      tearDown (if stackExists)
      setBool:NO forKey:MCUsingCloudStorageDefault
      removeCloudData i.e,{if(cloudURL) removeCloudURL and subdirs}

      19. startSyncing
      if(cloudAvailable)
      save
      tearDown
      [tempSentinel checkCurrentDeviceRegistration:^(BOOL deviceIsPresent)]
      if(devicePresent) {
      [self migrateStoreToCloud:postMigrationBlock];// rejoin cloud, so must move data to Cloud
      } else { //NEVER synched
      // Can keep either the cloud data, or the local data at this point
      // In a production app, you could ask the user what they want to keep.
      // Here we will just see if there is cloud data present, and if there is,
      // use that. If there is no cloud data, we’ll keep the local data.
      BOOL migrateDataFromCloud = [[NSFileManager defaultManager] fileExistsAtPath:self.cloudStoreURL.path];
      if ( migrateDataFromCloud ) {
      // Already cloud data present, so replace local data with it
      [self migrateStoreFromCloud:postMigrationBlock];
      }
      else {
      // No cloud data, so migrate local data to the cloud
      [self migrateStoreToCloud:postMigrationBlock];
      }
      }

      20. tearDown
      if ( !self.stackIsSetup && !self.stackIsLoading ) return;
      sentinel,psc = nil;
      [self.managedObjectContext reset];

       
      • Tim Roadley

        September 17, 2013 at 6:53 am

        Mark,

        I agree that account changes and the disabling / enabling of iCloud can cause havoc to an iCloud store.

        Fortunately this is all resolved in iOS 7 as per my upcoming book to be released early next month.

        I would honestly prevent pre-iOS 7 devices from using iCloud. Since most people upgrade to the latest iOS (see the Apple WWDC 2013 keynote), this shouldn’t be an issue for long.

        Cheers,

        Tim

         
        • eyestach

          September 17, 2013 at 12:01 pm

          Many Thanks, Tim!

          I had no idea that iOS 7 was the answer to all this. Thanks for taking the time to fill me in. I look forward to reading your book.

          All the best , Mark

           
    9. dave

      September 22, 2013 at 2:02 pm

      This was an awesome tutorial !!! It was very helpful and very easy to follow! Thanks !

       
    10. Nathan Furman

      September 28, 2013 at 8:57 am

      Well, changed credentials, installed your source code. Run it. Found the iCloud files, Ok.
      But then:
      2013-09-28 01:49:43.470 Staff Manager[1282:60b] nested pop animation can result in corrupted navigation bar
      2013-09-28 01:49:43.830 Staff Manager[1282:60b] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

       
    11. Malay

      October 17, 2013 at 5:43 pm

      Core data sqlite file are stored or view in icloud server documents directory building apps on iOS 7 ?

       
    12. eyestach

      December 4, 2013 at 4:28 am

      A link to a site that deals with iCloud problems for an app called iaWriter. I post this
      seeing that it contains general iCloud info that others may find useful.

      http://support.iawriter.com/help/kb/general-questions/icloud-wont-work-whats-wrong

      I am working my way through Tim’s new book. I find it excellent.

      Mark

       
    13. purringpigeon

      February 8, 2014 at 3:30 am

      Hello,

      I want to integrate iCloud into an existing app – my main concern is deduping… How to know what the most recent copy is, in the event the app is used offline on two devices.

      I have an app that allows a single entry on a day. When the day is selected in the calendar it looks for the core data record corresponding to the day and if it’s not there it creates it with blank values. From that point forward it updates it.

      So is there a way to know which record was touched and when – when the notifications are received?

      i.e. if my iPad and iPhone were offline and I selected todays date and both had a record created for today – I would only want to keep the last touched one. If one wasn’t touched it’s easy since all the records would be blank – but if both were updated – who wins? how do I decide?

       
    14. Jitendra

      October 11, 2014 at 3:20 am

      Hi Tim icloud working fine on ios8 but didn’t work on ios6.
      Could you help me.

       
    15. Clive Dancey

      December 2, 2014 at 5:01 pm

      WOW , amazing tutorial , i have waded through APPLES docs on this but you make it so much simpler…all i’m trying to work out now is how to import pre-made sql data into my app…or is there a way of pre-filling the table data in Person as you did with the Roles model..as that may be a lot easier and i have heard APPLE don’t like pre-loaded SQL data.

       
      • Tim Roadley

        December 3, 2014 at 3:55 pm

        Hi Clive, I’m glad the tutorial helped out! FYI I have a chapter on preloading data in my book: http://www.amazon.com/Learning-Core-Data-iOS-Hands-/dp/0321905768/ref=sr_1_1?s=books&ie=UTF8&qid=1417586027&sr=1-1&keywords=learning+core+data+for+ios

        I don’t have time to write a tutorial on it unfortunately as I’m working on a Swift version of that book now!

         
        • Clive Dancey

          December 10, 2014 at 5:52 am

          HI Tim , i have ordered your book and look forward to getting into it…so as i know where i am heading i am trying to import sql data into my app to start off then be able to delete and save if necessary but have this all save back to iCloud…will i be able to do this as i am worried this process won’t work..any pointers to start me off ..i have ordered from the UK so could take a while to get here

           
        • Tim Roadley

          December 10, 2014 at 7:41 am

          Hi Clive,

          There are two chapters on iCloud integration and a chapter on preloading data. There are four preloading techniques in the book (native code, xml import, default sqlite store and deep copy of all managed objects from one persistent store to another, including relationships).

          Can you describe what you mean by ‘from sql’ for me? Do you mean an existing sqlite store that has been created by core data and will be shipped with the application?

          Cheers

           
    16. Clive Dancey

      December 10, 2014 at 7:52 am

      hi TIm , thanks for the quick reply ,
      I have created an sql database in a third party application and want to import its data so that it comes prepackaged within the app. Data can then be deleted or changed then saved back to the iCloud store.
      The database i have used is based on the same entities set up within the original app so should match up..
      The idea is this ‘pre loaded data’ is loaded once the app is started for the first time and from then on can be added to or deleted.
      I have managed to use your iCloud tutorial in my app which works fine but won’t work for ‘pre loading data ‘ , the rest of the app works great based on your staff manager tutorial…as i can save data to iCloud and bring it back even if i delete the app.
      My existing database is saved as .sql , you quote sqlite i am assuming they are the same thing ???

      I did think about pre populating the app using the way you did it for the ‘roles’ table ( which i don’t currently use ) but couldn’t seem to populate the ‘person’ side

      If you have nay other ideas as to how this can be achieved…they are most welcome..and according to amazon my book will be here between 29th dec and 21st Jan..so could be a while
      Clive

       
      • Tim Roadley

        December 12, 2014 at 9:52 am

        Hmmmm what’s the third party app? Generally speaking I’d only use databases that Core Data itself has made. How much data are we talking about, and what type of data is it? (just text & numbers or images/videos too?) Maybe an import from XML might be better if there’s not too much data?

        Sqlite is the database type that (usually) underpins a Core Data managed object context. There’s a full chapter all about pre-loading data so it’s probably just best to wait until that turns up!

        Cheers

        Tim

         
        • Clive

          December 12, 2014 at 7:12 pm

          Hi , I managed to get It going with loading data so it works in the ‘Simulator’ part ( data is only names and emails prob max 100kb ) , all I have to do is work out how to add it to the device. I have looked at Apples Core Data presentation and its far too convoluted so I will wait for the book to arrive..thnx

           
    17. Clive Dancey

      December 18, 2014 at 6:23 am

      When a guy you read about on the web says he has ‘written a book’, and you’ve reached a difficult step in programming which you can’t get passed…you go..ok..here take my money..and hope above all hopes that it is not written on the back of a cereal packet from some ‘wannabe’ programmer and that somehow you can work out your problem….i took that chance..and WOW…this is amazing…professionally written , produced , easy-isn to follow…and actually works…i got the book today and have already solved one of my problems…the book has so much more than you can imagine , not just one way of doing something , sometimes up to 4…i still feel a relative noobie at IOS programming but i may feel at some point soon..hey , i am getting the hang of this…thanks Tim..

       

    Leave a Reply