从两个应用程序访问共享数据

Posted

技术标签:

【中文标题】从两个应用程序访问共享数据【英文标题】:Accessing Shared Data from Two Apps 【发布时间】:2015-04-03 13:03:57 【问题描述】:

您知道如何与两个允许读取和写入同一个 .sqlite 的应用程序(您的所有者)共享核心数据吗?

我尝试过使用应用组:

1) 银行.xcdatamodeld 银行信息.swift BankDetails.swift

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

2) 我已经从应用组的公共沙箱中检索到 sqlite 文件

应用代理:核心数据堆栈 [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'"

问候

【问题讨论】:

当您创建托管对象上下文时,您是否为其分配了一个有效的持久存储协调器? (该代码是什么样的?) lazy var managedObjectContext: NSManagedObjectContext? = let coordinator = self.persistentStoreCoordinator if coordinator == nil return nil var managedObjectContext = NSManagedObjectContext() managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext ()应用程序崩溃,没有传递到我在核心数据堆栈中的断点。我不确定要走好路。 【参考方案1】:

错误信息

"*** 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 堆栈(不会初始化惰性变量)。在我为重现此错误消息而创建的示例应用程序中,我只是将 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),其中介绍了如何使用权利设置共享应用程序组。

【讨论】:

以上是关于从两个应用程序访问共享数据的主要内容,如果未能解决你的问题,请参考以下文章

在应用程序之间共享核心数据存储

在两个域之间共享共享 html 内容时出错

访问共享内存时出现分段错误

如何更快地访问 System V 共享内存?

未设置访问组时共享的钥匙串项目

如何在两个 iOS 应用之间共享应用内购买数据?