繁体   English   中英

在Swift中将CoreData保存/同步到iCloud

[英]Saving/Syncing CoreData to iCloud in Swift

我在将CoreData同步到iCloud时遇到问题,我在控制台中不断收到一条错误消息,说2015-02-22 23:09:31.229 Newstron[1711:233218] -[PFUbiquitySetupAssistant finishSetupWithRetry:](826): CoreData: Ubiquity: <PFUbiquitySetupAssistant: 0x7fbc6357e580>: Retrying after delay: 60 Error Domain=NSCocoaErrorDomain Code=134080 "The operation couldn't be completed. (Cocoa error 134080.)" UserInfo=0x7fbc637794f0 {Reason=Didn't get a container URL back from URLForUbiquityContainerIdentifier:, giving up now. Please ensure the application is signed with the proper entitlements to read from the container., NSPersistentStoreUbiquitousContainerIdentifierKey=null} 2015-02-22 23:09:31.229 Newstron[1711:233218] -[PFUbiquitySetupAssistant finishSetupWithRetry:](826): CoreData: Ubiquity: <PFUbiquitySetupAssistant: 0x7fbc6357e580>: Retrying after delay: 60 Error Domain=NSCocoaErrorDomain Code=134080 "The operation couldn't be completed. (Cocoa error 134080.)" UserInfo=0x7fbc637794f0 {Reason=Didn't get a container URL back from URLForUbiquityContainerIdentifier:, giving up now. Please ensure the application is signed with the proper entitlements to read from the container., NSPersistentStoreUbiquitousContainerIdentifierKey=null}

我已经在AppDelegate.swift中获得了代码

// MARK: - Core Data stack
func observeCloudActions(persistentStoreCoordinator psc: NSPersistentStoreCoordinator?) {
    // iCloud notification subscriptions
    let nc = NSNotificationCenter.defaultCenter();
    nc.addObserver(
        self,
        selector: "storesWillChange:",
        name: NSPersistentStoreCoordinatorStoresWillChangeNotification,
        object: psc);

    nc.addObserver(
        self,
        selector: "storesDidChange:",
        name: NSPersistentStoreCoordinatorStoresDidChangeNotification,
        object: psc);

    nc.addObserver(
        self,
        selector: "persistentStoreDidImportUbiquitousContentChanges:",
        name: NSPersistentStoreDidImportUbiquitousContentChangesNotification,
        object: psc);

    nc.addObserver(
        self,
        selector: "mergeChanges:",
        name: NSManagedObjectContextDidSaveNotification,
        object: psc);
}

func mergeChanges(notification: NSNotification) {
    NSLog("mergeChanges notif:\(notification)")
    if let moc = managedObjectContext {
        moc.performBlock {
            moc.mergeChangesFromContextDidSaveNotification(notification)
            self.postRefetchDatabaseNotification()
        }
    }
}

func persistentStoreDidImportUbiquitousContentChanges(notification: NSNotification) {
    self.mergeChanges(notification);
}

// Subscribe to NSPersistentStoreCoordinatorStoresWillChangeNotification
// most likely to be called if the user enables / disables iCloud
// (either globally, or just for your app) or if the user changes
// iCloud accounts.
func storesWillChange(notification: NSNotification) {
    NSLog("storesWillChange notif:\(notification)");
    if let moc = self.managedObjectContext {
        moc.performBlockAndWait {
            var error: NSError? = nil;
            if moc.hasChanges && !moc.save(&error) {
                NSLog("Save error: \(error)");
            } else {
                // drop any managed objects
            }

            // Reset context anyway, as suggested by Apple Support
            // The reason is that when storesWillChange notification occurs, Core Data is going to switch the stores. During and after that switch (happening in background), your currently fetched objects will become invalid.

            moc.reset();
        }

        // now reset your UI to be prepared for a totally different
        // set of data (eg, popToRootViewControllerAnimated:)
        // BUT don't load any new data yet.
    }
}

// Subscribe to NSPersistentStoreCoordinatorStoresDidChangeNotification
func storesDidChange(notification: NSNotification) {
    // here is when you can refresh your UI and
    // load new data from the new store
    NSLog("storesDidChange posting notif");
    self.postRefetchDatabaseNotification();
}

func postRefetchDatabaseNotification() {
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        NSNotificationCenter.defaultCenter().postNotificationName(
            "kRefetchDatabaseNotification", // Replace with your constant of the refetch name, and add observer in the proper place - e.g. RootViewController
            object: nil);
    })
}

lazy var applicationDocumentsDirectory: NSURL = {
    // The directory the application uses to store the Core Data store file. This code uses a directory named "hyouuu.pendo" in the application's documents Application Support directory.
    let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    return urls[urls.count-1] as! NSURL
    }()

lazy var managedObjectModel: NSManagedObjectModel = {
    // The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
    let modelURL = NSBundle.mainBundle().URLForResource("MyAppData", withExtension: "momd")!
    NSLog("modelURL:\(modelURL)")
    return NSManagedObjectModel(contentsOfURL: modelURL)!
    }()

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
    // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
    // Create the coordinator and store
    var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("MyAppData.sqlite")
    NSLog("storeURL:\(url)")
    var error: NSError? = nil
    var failureReason = "There was an error creating or loading the application's saved data."
    if coordinator!.addPersistentStoreWithType(
        NSSQLiteStoreType,
        configuration: nil,
        URL: url,
        options: [NSPersistentStoreUbiquitousContentNameKey : "MyAppName"],
        error: &error) == nil
    {
        coordinator = nil
        // Report any error we got.
        let dict = NSMutableDictionary()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
        dict[NSLocalizedFailureReasonErrorKey] = failureReason
        dict[NSUnderlyingErrorKey] = error
        //error = NSError(domain: "Pendo_Error_Domain", code: 9999, userInfo: dict as! [NSObject : AnyObject])
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog("AddPersistentStore error \(error), \(error!.userInfo)")
    }

    self.observeCloudActions(persistentStoreCoordinator: coordinator)

    return coordinator
    }()

lazy var managedObjectContext: NSManagedObjectContext? = {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
    let coordinator = self.persistentStoreCoordinator
    if coordinator == nil {
        return nil
    }
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    managedObjectContext.persistentStoreCoordinator = coordinator
    return managedObjectContext
    }()

// MARK: - Core Data Saving support

func saveContext () {
    if let moc = self.managedObjectContext {
        var error: NSError? = nil
        if moc.hasChanges && !moc.save(&error) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog("Unresolved error \(error), \(error!.userInfo)")
        }
    }
}

我不知道问题出在哪里,代码签名看起来都可以正确无误,但我一直收到此错误,我一直在Apple Developer Forms上找不到答案,在溢出和google上都找不到我的问题的答案。 关于该错误,我没有太多的文档。 因此,是否有更好的方法通过iCloud Integration来实现CoreData,或者是否有针对此问题的修复程序。 AppDelegate.swift中的代码是我实施iCloud代码的唯一位置。

我也有这个问题。
通过转到“目标/功能”并打开iCloud并单击“ iCloud文档”复选框来解决此问题。 由于我的声誉太低,无法发布屏幕截图。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM