2017-09-02 3 views
1

私は、最初に起動するときにすべてのデータを読み込まなくても、事前入力するコアデータデータベースを用意しています。私はロードを処理し、そのアプリケーションから新しいものにSQLデータベースをコピーする2番目のアプリケーションを作成することでこれをしようとしています。当初、私は単純に二アプリから.sqliteファイルをコピーして、このような最初のアプリにファイルをコピーしようとした:コアデータデータベースをあるアプリケーションから別のアプリケーションに移行する

lazy var persistentContainer: NSPersistentContainer = { 
     let container = NSPersistentContainer(name: "GeoPointDB") 

     let seededData: String = "GeoPointDB" 
     var persistentStoreDescriptions: NSPersistentStoreDescription 

     let storeUrl = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first! 

     if !FileManager.default.fileExists(atPath: (storeUrl.path)) { 
      let seededDataUrl = Bundle.main.url(forResource: seededData, withExtension: "sqlite") 
      try! FileManager.default.copyItem(at: seededDataUrl!, to: storeUrl) 

     } 

     container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeUrl)] 
     container.loadPersistentStores(completionHandler: { (storeDescription, error) in 
      if let error = error { 

       fatalError("Unresolved error \(error),") 
      } 
     }) 

     return container 

    }() 

しかし、これは私に、「データベース・ファイルを開くことができません」というエラーメッセージを与えました。ビットを研究し、私はこの記事を見つけた: https://developer.apple.com/library/content/qa/qa1809/_index.html

私はので、戻って第二のアプリへ行き、このコードを使用して適切にデータベースをエクスポートしようとした:

let documents = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first! 
       do { 
        try context.persistentStoreCoordinator!.migratePersistentStore(context.persistentStoreCoordinator!.persistentStores.first!, to: documents, options: nil, withType: NSSQLiteStoreType) 
        print("Managed to save database file") 
       } catch let error as NSError { 
        print("Failed to save DB: \(error)") 
       } 

しかし、私はこれを行うとき、私は正確な取得します同じエラーのエクスポートの場合、コピーされたDBを最初のアプリケーションにロードしようとすると「データベースファイルを開けません」というエラーが表示されます。私が間違ってやっていることや、iOS 10/11とSwift 3/4を使ってデータベースの移行を行う方法についてのヒント?

役に立つかもしれないいくつかの追加情報:

  • どちらのアプリが最初のアプリでプロジェクト作成上のXcodeの「使用コアデータ」オプションから標準CoreDataコード
  • にCoreDataモデル(.xcdatamodeldファイル)を持っています不整合がないことを保証するために、第2のアプリからコピーされ
  • 、私は何の問題もなく第二のアプリケーションのデータベースからデータを追加してフェッチすることができる午前

答えて

1

結局、私は実行可能な解決法を見つけることができました。私はまだデータベースを正常にエクスポートする方法を見つけ出していませんが、すべてのアプリケーションの更新(またはそれほど頻繁ではない)ごとにこの移行を1回しか実行しないため、手動でデータをコピーして、 App Storeに提出する。データベースのインポートのためのコードについて

が、これは私が使用して終了するものである:

lazy var persistentContainer: NSPersistentContainer = { 
     let databaseName = "GeoPointDB" 

     let container = NSPersistentContainer(name: databaseName) 

     var persistentStoreDescriptions: NSPersistentStoreDescription 

     let storeUrl = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first!.appendingPathComponent(databaseName + ".sqlite") 
     let storeUrlFolder = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first! 

     if !FileManager.default.fileExists(atPath: (storeUrl.path)) { 
      let seededDataUrl = Bundle.main.url(forResource: databaseName, withExtension: "sqlite") 
      let seededDataUrl2 = Bundle.main.url(forResource: databaseName, withExtension: "sqlite-shm") 
      let seededDataUrl3 = Bundle.main.url(forResource: databaseName, withExtension: "sqlite-wal") 

      try! FileManager.default.copyItem(at: seededDataUrl!, to: storeUrl) 
      try! FileManager.default.copyItem(at: seededDataUrl2!, to: storeUrlFolder.appendingPathComponent(databaseName + ".sqlite-shm")) 
      try! FileManager.default.copyItem(at: seededDataUrl3!, to: storeUrlFolder.appendingPathComponent(databaseName + ".sqlite-wal")) 

     } 

     container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeUrl)] 
     container.loadPersistentStores(completionHandler: { (storeDescription, error) in 
      if let error = error { 

       fatalError("Unresolved error \(error),") 
      } 
     }) 

     return container 
    }() 

私は基本的に変わっ二つのことは、(NSPersistantStoreDescriptionは、SQLファイルを直接指していたことを確認しました上記のようなディレクトリではなく)、ドキュメントフォルダに3つのファイル(.sqlite.sqlite-shm.sqlite-wal)をすべてコピーしたことを確認してください。

関連する問題