2017-10-10 4 views
3

私は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から取得します。ディレクトリのファイルURLを取得するにはcontainerURL(forSecurityApplicationGroupIdentifier:)を使用してください。

必要に応じて、変更せずにそのURLを使用できます。おそらく、Core Dataファイルを保持するためにサブディレクトリを作成することをお勧めします。これを行う場合は、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'を使用するのが一般的ですが、有効なファイル名はすべてOKです。 –

+0

お役立ち情報はっきりと説明してくれてありがとう。 – radar

関連する問題