2017-10-10 35 views
3

我有一个应用程序,它将一些信息存储在coredata中并读取它们。 我正在写这个应用程序的消息扩展,我希望这个扩展读取相同的数据,但我总是有空的响应。无法从分机读取coredata

这里是我使用的主要应用程序的代码:我使用完全相同的扩展相同的代码

context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 
fetchImages(Date()){ (array, arrayData) in 
    for image in array{ 
     imagesArray.insert(image, at:0) 
    } 
} 

但它不会读取数据。 我想知道的是我没有在代码中的任何地方使用appGroupIdentifier

我该如何做到这一点?

谢谢。

这里是fetchImages函数的代码:

func fetchImages(_ predicate:Date, completion:(_ array:[Image], _ arrayData:NSArray)->()){ 
    var arrData = [NSManagedObject]() 
    var existingImages = [Image]() 
    let request :NSFetchrequest<NSFetchrequestResult> = NSFetchrequest(entityName: "Photo") 

    do { 
     let results = try context?.fetch(request) 
     var myImage = Image() 
     if ((results?.count) != nil) { 
      for result in results! { 
       myImage.imageUrl = (resultat as! NSManagedObject).value(forKey:"url") as! String 
       myImage.imageFileName = (resultat as! NSManagedObject).value(forKey:"imageFileName") as! String  
       existingImages.append(myImage) 
       arrData.append(result as! NSManagedObject) 
      } 
     } else{ 
      print ("No photo.") 
     } 
     completion(existingImages, arrData as NSArray) 

    } catch{ 
     print ("Error during CoreData request") 
    } 
} 
+0

你是不是调用完成处理程序可言。顺便说一句,完成闭包中的参数标签在Swift 3+ – vadian

+0

中毫无意义,我在清除函数时删除了'completion'处理程序。我编辑这个问题把它放回去。 – radar

+0

上下文是否为'nil'?顺便说一下,上下文应该是非可选的。为什么天啊,你把特定的[NSManagedObject]放在非特定的'NSArray'中。不要这样做。只使用Swift原生集合类型。 – vadian

回答

2

打开的应用程序组是第一步,但现在你需要告诉核心数据使用的应用程序组。

首先,您从FileManager获取共享组容器的位置。使用containerURL(forSecurityApplicationGroupIdentifier:)获取目录的文件URL。

如果需要,您可以在不更改的情况下使用该URL。在其中创建一个子目录来保存核心数据文件可能是一个好主意。如果这样做,请在URL上使用appendingPathComponent()方法向URL添加目录名称。然后使用FileManager通过createDirectory(at:withIntermediateDirectories:attributes:)方法创建新目录。

既然你有一个共享的目录来使用,告诉NSPersistentContainer把它的文件放在那里。你使用NSPersistentStoreDescription来做到这一点。初始化程序可以通过一个URL告诉它在哪里存储数据。

您的代码将是接近的东西这样的:

let directory: URL = // URL for your shared directory as described above 
let containerName: String = // Your persistent container name 

let persistentContainer = NSPersistentContainer(name: containerName) 
let persistentStoreDirectoryUrl = directory.appendingPathComponent(containerName) 

guard let _ = try? FileManager.default.createDirectory(at: persistentStoreDirectoryUrl, withIntermediateDirectories: true, attributes: nil) else { 
    fatalError() 
} 

let persistentStoreUrl = persistentStoreDirectoryUrl.appendingPathComponent("\(containerName).sqlite") 

let persistentStoreDescription = NSPersistentStoreDescription(url: persistentStoreUrl) 
persistentContainer.persistentStoreDescriptions = [ persistentStoreDescription ] 

persistentContainer.loadPersistentStores { 
    ... 
} 
+0

非常感谢。这真的很有帮助。只需要提一下,我没有使用任何的SQL数据库,我直接在容器的上下文中存储我的数据。我使用'persistentContainer.persistentStoreDescriptions'来使容器可用于主应用程序和扩展,现在它工作得很好。再次感谢。 – radar

+0

除非您在'NSPersistentStoreDescription'上设置'type'属性,否则您通过核心数据使用SQLite。大多数情况并不重要,但知道的很好。通常在文件名中使用'.sqlite',但任何有效的文件名都可以。 –

+0

很高兴知道。再次感谢您的明确解释。 – radar