iOS:当我从前台切换到后台时,我丢失了核心数据实体

时间:2015-03-27 11:07:00

标签: ios ipad swift core-data icloud

我正在Swift应用程序中构建一个iPad,当我从前台切换到后台时,我无法弄清楚如何保留我的实体。 如果我关闭应用程序(从任务管理器),则会再次显示所有实体。我正在使用Apple提供的标准Core Data堆栈。 如果我使用iCloud,则不会发生这种情况。

有什么想法吗?我爬了StackOverflow但是找不到任何东西。感谢。

修改

App Delegate

// MARK: - Core Data stack
lazy var applicationDocumentsDirectory: NSURL = {
    // The directory the application uses to store the Core Data store file. This code uses a directory named "it.b3lab.ProjectIceCream" 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("ProjectIceCream", withExtension: "momd")!
    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)
    //Add support to ligtweight migrations, and iCloud persistent storage
    var options = [
        NSMigratePersistentStoresAutomaticallyOption: true,
        NSInferMappingModelAutomaticallyOption: true,
        NSPersistentStoreUbiquitousContentNameKey: "ProjectIceCreamCloudStore"
    ]

    //enabled iCloud notiiccation subscription
    var notification = NSNotificationCenter.defaultCenter()
    notification.addObserver(self, selector: "storeDidChangeNotification:",
        name: NSPersistentStoreCoordinatorStoresDidChangeNotification,
        object:nil)
    notification.addObserver(self, selector: "storeWillChangeNotification:",
        name: NSPersistentStoreCoordinatorStoresWillChangeNotification,
        object:nil)
    notification.addObserver(self, selector: "storeDidImportUbiquitousContent:",
        name: NSPersistentStoreDidImportUbiquitousContentChangesNotification,
        object:nil)

    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("ProjectIceCream.sqlite")
    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:options, 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: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        // 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("Unresolved error \(error), \(error!.userInfo)")
        abort()
    }

    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.persistentStoreCoordinator = coordinator
    return managedObjectContext
}()


//MARK: iCloud notification methods
func storeDidChangeNotification(notification: NSNotification) {
    println("Core Data successfully created and configured an iCloud-enabled persistent store")
    //TODO: controllare che i dati in ingresso siano validi
    //TODO: Implement Refresh your User Interface.
}

func storeWillChangeNotification(notification: NSNotification) {
    println("Called storeWillChangeNotification")
    var moc: NSManagedObjectContext = self.managedObjectContext!
    moc.performBlock { () -> Void in
        if moc.hasChanges {
            var saveError: NSError?
            if moc.save(&saveError) {
                print("iCloud save error \(saveError)")
            }
        }else{
            moc.reset()
        }
    }
    //TODO: Implement Refresh your User Interface.
}

func storeDidImportUbiquitousContent(notification: NSNotification) {
    println("Called storeDidImportUbiquitousContent")
    var moc: NSManagedObjectContext = self.managedObjectContext!
    moc.performBlock { () -> Void in
        moc.mergeChangesFromContextDidSaveNotification(notification)
    }
}

// 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)")
            abort()
        }
    }
}

获取请求的示例

class func getReceipesFormCoreData() -> [Recipes] {
    let managedContext = getManagedObjectContext()
    let request: NSFetchRequest = NSFetchRequest()

    let entity: NSEntityDescription = NSEntityDescription.entityForName("Recipes",
        inManagedObjectContext: managedContext)!

    request.entity = entity
    var error: NSError?

    var results: [Recipes] = managedContext.executeFetchRequest(request, error: &error)
        as [Recipes]
    if (error != nil) {
        println("ERROR: Could not load \(error), \(error?.userInfo)")
    }

    return results
}

1 个答案:

答案 0 :(得分:0)

您是否在触发saveContext()? 如果没有,请尝试拨打func applicationDidEnterBackground(application: UIApplication)上的AppDelegate 此外,您可以在创建CoreData个对象后立即调用它。