2017-10-10 2 views
3

J'ai une application qui stocke certaines informations dans coredata et les lit. J'écris une extension de message de cette application et je voudrais avoir cette extension lisant les mêmes données mais j'ai toujours la réponse vide.Impossible de lire les coredata de l'extension

Voici le code que je utilise dans l'application principale:

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

J'utilise exactement le même code dans l'extension, mais il ne lit pas les données. Ce que je me demande, c'est que je n'utilise pas le appGroupIdentifier n'importe où dans le code.

Comment puis-je faire pour y parvenir?

Merci.

Voici le code de fetchImages fonction:

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

Vous n'êtes pas appeler le gestionnaire d'achèvement du tout. En passant, les étiquettes de paramètres dans la fermeture d'achèvement sont sans signification dans Swift 3+ – vadian

+0

J'ai enlevé le gestionnaire 'achèvement 'lors du nettoyage de la fonction. Je modifie la question pour le remettre. – radar

+0

Le contexte est-il «nul»? D'ailleurs, le contexte est censé être non-optionnel. Et pourquoi, pour l'amour du ciel, lancez-vous spécifiquement '[NSManagedObject]' à NSArray' non spécifique. Ne fais pas ça. Utilisez uniquement les types de collection natifs Swift. – vadian

Répondre

2

Activation des groupes d'applications est la première étape, mais maintenant vous avez besoin de dire de base de données pour utiliser le groupe d'applications.

Vous obtenez d'abord l'emplacement du conteneur de groupe partagé, à partir de FileManager. Utilisez containerURL(forSecurityApplicationGroupIdentifier:) pour obtenir une URL de fichier pour le répertoire.

Vous pouvez utiliser cette URL sans modifications si vous le souhaitez. C'est probablement une bonne idée de créer un sous-répertoire pour contenir vos fichiers de données de base. Si vous faites cela, ajoutez un nom de répertoire à l'URL avec la méthode appendingPathComponent() sur URL. Ensuite, utilisez FileManager pour créer le nouveau répertoire avec la méthode createDirectory(at:withIntermediateDirectories:attributes:).

Maintenant que vous avez un répertoire partagé à utiliser, dites NSPersistentContainer pour y mettre ses fichiers. Vous faites cela en utilisant NSPersistentStoreDescription. L'initialiseur peut prendre une URL qui lui indique où stocker ses données.

Votre code sera quelque chose approchant ceci:

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

Merci beaucoup. Cela m'a vraiment aidé. Juste besoin de mentionner que je n'utilise pas sql db et je stocke mes données directement dans le contexte du conteneur. J'ai utilisé 'persistentContainer.persistentStoreDescriptions' pour rendre le conteneur disponible à la fois pour l'application principale et pour l'extension, et cela fonctionne très bien maintenant. Merci encore. – radar

+0

Sauf si vous définissez la propriété 'type' sur' NSPersistentStoreDescription', vous utilisez SQLite via les données de base. Surtout, ça n'a pas d'importance, mais c'est bon à savoir. Il est courant d'utiliser '.sqlite' dans le nom de fichier mais tout nom de fichier valide est OK. –

+0

Bon à savoir. Merci encore pour l'explication claire. – radar