从两个应用访问共享数据

时间:2015-04-03 13:03:58

标签: ios sqlite swift core-data ios-app-group

您知道如何与两个应用程序(您的所有者)共享Core Data,以允许对同一个.sqlite进行读写操作吗?

我尝试过使用应用组:

1)     Bank.xcdatamodeld     BankInfo.swift     BankDetails.swift

我已将这些文件复制到此应用程序B项目的目录中(从应用程序A项目中检索),然后我将它们拖到Xcode中。

2)我从应用程序组的公共沙箱中检索了sqlite文件

App Delegate:核心数据堆栈[Swift]

lazy var applicationDocumentsDirectory: NSURL = {

    let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    return urls[urls.count-1] as NSURL
    }()

lazy var managedObjectModel: NSManagedObjectModel = {

    let modelURL = NSBundle.mainBundle().URLForResource("shareapps", withExtension: "momd")!
    return NSManagedObjectModel(contentsOfURL: modelURL)!
    }()

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {


    // Create the coordinator and store

    var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)

    let directory = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("com.sd.shareapps");

    let url = directory?.URLByAppendingPathComponent("shareapps.sqlite")

    //Sarting frehs every time
    NSFileManager.defaultManager().removeItemAtURL(url!, error: nil)

    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: nil, 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()
    }
    println("\(coordinator?.persistentStores)")
    return coordinator
    }()     
lazy var managedObjectContext: NSManagedObjectContext? = {

    let coordinator = self.persistentStoreCoordinator
    if coordinator == nil {
        return nil
    }
    var managedObjectContext = NSManagedObjectContext()
    managedObjectContext.persistentStoreCoordinator = coordinator
    return managedObjectContext
}()

我收到此错误消息:

"*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSPersistentStoreCoordinator for searching for entity name 'Entity'"

此致

1 个答案:

答案 0 :(得分:0)

错误消息

"*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSPersistentStoreCoordinator for searching for entity name 'Entity'"

给出了回答这个问题的关键。错误消息与is not a legal NSManagedObjectContext...的措辞非常相似,在类似的问题+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Account''中得到了解答。

因此,虽然在这两种情况下错误消息都很神秘,但在这种情况下,错误消息意味着代码中的某个位置正在为nil传递NSPersistentStoreCoordinator。设置断点应该有助于确定何处。通过对代码进行以下修改,我能够重现相同的错误:

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {  
    // normally we would initialize the persistentStoreCoordinator here
    // but to reproduce an error, just return nil
    return nil;
} 

    lazy var managedObjectContext: NSManagedObjectContext? = {

    let coordinator = self.persistentStoreCoordinator
          // normally, we would return nil right away if there is 
          // no coordinator, but to reproduce the error carry on anyway
//        if coordinator == nil {
//            return nil
//        }
    var managedObjectContext = NSManagedObjectContext()
    managedObjectContext.persistentStoreCoordinator = coordinator
    return managedObjectContext
}()

对于阅读此答案的其他人,请注意永远不会使用Core Data堆栈(懒惰变量不会被初始化),除非我们对Core Data做了一些有用的事情。在我创建的示例应用程序中重现此错误消息,我刚刚将核心数据堆栈保留在原位(Xcode模板将其放入App Delegate中),然后我尝试在didFinishLaunchingWithOptions中创建一个实体:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.

        var context : NSManagedObjectContext? = self.managedObjectContext

        // the line below will cause an exception when the
        // NSPersistentStoreCoordinator is nil
        var entity : NSEntityDescription? = NSEntityDescription.entityForName("Entity", 
           inManagedObjectContext:context!)

        return true
    } 

请注意,原始帖子中提供的代码不会导致任何错误。可能发布的问题中的代码与项目中使用的实际代码不匹配,或者可能在应用程序的其他地方存在使用nil持久性存储协调器创建的托管对象上下文。无论如何,这个神秘的错误信息已被破译。

您可能希望确保已正确设置共享的应用组。请参阅此文章(http://jasoncross-ios-development.blogspot.com/2015/04/accessing-shared-data-between-ios.html),其中涉及使用权利设置共享应用组。