CoreData the pits that meet icloud

Source: Internet
Author: User

Despite Apple's hype about the perfect fit between icloud and CoreData, it's a nightmare to sync coredata data with icloud before IOS7, and Apple itself admits a lot of bugs and instabilities, This has forced Apple to come back and say that their engineers have fixed bugs in iOS7, enhanced the experience, and Balabala, the key is that for programmers, integrating icloud into CoreData is incredibly easy.

In Apple's official documentation, the configuration has been described very clearly, in short, can be summed up as three steps:

    • Create an app ID in itunes Connect, find the item's Capabilities tab in Xcode, and turn on the icloud option. This will create a default icloud container for you, with the name format "com." Xxx.yourappid "

    • When you add Nspersistentstore, you pass in a persistent store name to the options parameter, one on your own, and the sample code is as follows:

1234567 NSDictionary *storeOptions =    @{NSPersistentStoreUbiquitousContentNameKey: @"MyAppCloudStore"};NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType                                                     configuration:nil                                                               URL:storeURL                                                           options:storeOptions                                                             error:&error];
    • For Nspersistentstorecoordinatorstoreswillchangenotification, Nspersistentstorecoordinatorstoresdidchangenotification and Nspersistentstoredidimportubiquitouscontentchangesnotification these three The notification is registered to receive the notification after the data is processed. It is best to use Nsnotificationcenter's AddObserverForName:object:queue:usingBlock: method to make the logic clearer and the code more compact.

Finally, put the code for swift to implement Persistentstorecoordinator:

12345678910111213141516171819202122232425262728293031323334353637383940414243 varpersistentStoreCoordinator: NSPersistentStoreCoordinator! {   if_persistentStoreCoordinator == nil {       let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("HardChoice.sqlite")       varerror: NSError? = nil       _persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)              // iCloud notification subscriptions       let dc = NSNotificationCenter.defaultCenter()       dc.addObserverForName(NSPersistentStoreCoordinatorStoresWillChangeNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in           self.managedObjectContext.performBlock({ () -> Void in               varerror: NSError? = nil               ifself.managedObjectContext.hasChanges {                   if!self.managedObjectContext.save(&error) {                       println(error?.description)                   }               }               self.managedObjectContext.reset()           })       })       dc.addObserverForName(NSPersistentStoreCoordinatorStoresDidChangeNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in           self.managedObjectContext.performBlock({ () -> Void in               var error: NSError? = nil               ifself.managedObjectContext.hasChanges {                   if!self.managedObjectContext.save(&error) {                       println(error?.description)                   }               }           })       })       dc.addObserverForName(NSPersistentStoreDidImportUbiquitousContentChangesNotification, object: self.persistentStoreCoordinator, queue: NSOperationQueue.mainQueue(), usingBlock: { (note) -> Void in           self.managedObjectContext.performBlock({ () -> Void in               self.managedObjectContext.mergeChangesFromContextDidSaveNotification(note)           })       })              if_persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSPersistentStoreUbiquitousContentNameKey:"MyAppCloudStore"], error: &error) == nil {           println("Unresolved error \(error), \(error?.userInfo)")           abort()       }   }   return_persistentStoreCoordinator!}var_persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil

Of course you can also use the Lazy keyword to implement the lazy loading of the Persistentstorecoordinator property.

Someone has abstracted the entire set of CoreData integrated icloud logic, such as Icloudcoredatastack. There's no need to re-use a third-party library that claims to make coredata and icloud easier to match, because Apple does make it simple in iOS7.

However, when Xcode6 and IOS8 hit, a pit scrambling to appear.

The first is icloud drive, which conflicts with previous icloud. If you upgrade, complete the test machine to upgrade icloud drive.

Then, after the Icloud tab in Xcode6 that opens the Capabilities tab, the following scene is simply a horizontal slot:

How to choose how to choose AH?! I can only say that this is the right choice. By the way, iCloud default container name format has become "ICloud.com.yourname.yourAppID", in fact, this is not very accurate, officially known as "icloud.$ (Cfbundleidentifier)", The variables referred to in the following dollar numbers are the "Bundle Identifier" values in the identity column of the general. In addition, "Key-value storage" and "CloudKit" options are optional, but "ICloud Documents" must be checked, otherwise it is not possible to synchronize CoreData data.

Ps:cloudkit is Apple's latest icloud-based cloud data storage service, offering low-cost cloud storage and the ability to share its app data as a backend service through the user's icloud account.

Now it's time to check if we've successfully added the icloud container, and we can try to get the container's URL in the Applicationdidfinishlaunchingwithoptions method to determine:

1234567 let containerurl = nsfilemanager.defaultmanager (). Urlforubiquitycontaineridentifier ( Code class= "JS plain" > if  containerurl ! = nil {    println ( "success:\ (containerurl)" ) } else {    println ( "Url=nil" ) }

The Urlforubiquitycontaineridentifier method always returns nil if icloud Documents is not previously checked in icloud in the capabilities label. Take a look at the discussion on this topic at the Apple Developer Forum.

PS: Official documentation does not recommend using the Urlforubiquitycontaineridentifier method on the main thread, because it may take a long time to return the URL and block the main thread. This is just for testing use.

But judging whether ICloud really works with CoreData, Apple's official documentation is written in detail: Using the icloud debugging Tools

When I was in the mood to dash Debug Navigator in Xcode, click on the left side of icloud to view the status, stunned by everything in front of you:

ICloud usage tells me that the status is not available, but the using local storage in the lower-right corner of the log has changed from 1 to 0, which proves that my app (Hardchoice) has been transferred from CoreData to use the local persistent repository. Icloud-enabled "Persistent warehouse. The histogram in "Transfer Activity" shows the data downloaded from icloud. And this should actually be a bug in Xcode6, someone has already discussed it in the Apple Developer Forum.

According to my test, ICloud Usage does not appear when you check only "Key-value storage" or when you debug on the emulator. Even if ICloud Usage appears, the status is always disabled, and the Transfer Activity is not very sensitive. Only can believe CoreData's log.

But we can view the icloud usage for My Mac instead of the iphone's icloud usage:

As you can see in the "Documents" section, I've synced the data between the two devices, followed by my device number, "mobile". Expand the data to see more detailed synchronization records:

Although "My Mac" can see the data synchronization between icloud and CoreData Records, but in Xcode6.1.1 "documents" display is not very normal, in the latest version of Xcode6.2beta, although fixed "documents" Display problem, but the "ICloud Usage" bug still exists.

Finally, make sure that the network is usually. I was in the middle of the soft training one months, the network odd, or blocked icloud, has not been able to debug successfully.

Paste a hardchoice synchronous successful test diagram, because I wrote this demo with Swift, so like to use Swift can directly put my part of the source glue past use:

Reference:

Http://stackoverflow.com/questions/26195612/icloud-debug-gauge-status-disabled

Http://stackoverflow.com/questions/25971816/xcode-6-ios-8-icloud-core-data-setup

CoreData the pits that meet icloud

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.