Загрузка базы данных Core Data, созданной приложением iOS, в другое приложение Xcode - PullRequest
0 голосов
/ 16 марта 2020

Ранее я создал приложение iOS, которое сохраняет данные в базе данных. Я скопировал данные из приложения и теперь у меня есть три файла:

MyData.sqlite, MyData.sqlite-shm и MyData.sqlite-wal

Я пытаюсь создать командную строку Утилита в Xcode, которая будет получать доступ к данным из этих баз данных. Я добавил CoreData в проект служебной программы командной строки и смог создать новую базу данных. Однако я хочу загрузить базу данных, которую я экспортировал из приложения.

Я нашел от кого-то предыдущий вопрос: Перенос базы данных Core Data из одного приложения в другое

Однако их ответ не работает для меня. Эта строка:

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

выдает эту ошибку:

expression produced error: error: /var/folders/cc/r_54b90515v_m6t41vg9lg000000gp/T/expr14-6084fa..swift:1:65: error: use of undeclared type 'Foundation'
Swift._DebuggerSupport.stringForPrintObject(Swift.UnsafePointer<Foundation.URL>(bitPattern: 0x1004fc2f0)!.pointee)

Мне кажется, что мне не хватает простого ответа на эту проблему. Есть ли простой способ перенести информацию из базы данных Core Data из одного приложения в другое?

РЕДАКТИРОВАТЬ: Благодаря Лу Франко ниже, я добился определенного прогресса. Теперь у меня есть:

var persistentContainer: NSPersistentContainer = {

    let container = NSPersistentContainer(name: "MyData")
    let storeUrl = URL(fileURLWithPath: "/Path/To/Data/MyData.sqlite")
    container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeUrl)]
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {

            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

Однако теперь я получаю целую кучу выходных данных, суммированных к "Persistent store migration failed, missing mapping model."

Я надеялся, установив контейнер с текущими Базовыми данными изначально, я мог как-то позволить программа знает, чего ожидать от того, что она загружает (модель данных та же самая), но, похоже, что-то не получается. Я заметил в сообщениях об ошибках:

NSInferMappingModelAutomaticallyOption = 1;
NSMigratePersistentStoresAutomaticallyOption = 1;

Есть ли способ заставить программу знать, что загружаемые данные соответствуют модели Core Data, которую я уже установил? Просто нужно загрузить данные из файла.

Ответы [ 2 ]

1 голос
/ 16 марта 2020

Эта строка:

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

Не работает для утилит командной строки. Это для приложений.

Вам нужно будет найти путь другим способом (аргумент командной строки, жесткий код, относительно утилиты и т. Д. c)

Например:

 URL(fileURLWithPath: FileManager.default.currentDirectoryPath).appendingPathComponent("YOURFILE"))
0 голосов
/ 16 марта 2020

Благодаря некоторым рекомендациям Лу Франко я нашел свой путь к рабочему решению. Я взял файл .momd из исходного приложения, заархивировав его и изучив экспортированный файл .app в .xcarchive. Вот минимальный пример, который загружает данные из существующей базы данных sqlite в «/Path/To/Data/MyData.sqlite» с использованием модели данных из «/Path/To/Data/MyData.momd». Он просто захватывает все уникальные идентификаторы сессии:

import Foundation
import CoreData

let storePath = "/Path/To/Data/MyData.sqlite"
let storeURL = URL(fileURLWithPath: storePath)

let modelPath =  "/Path/To/Data/MyData.momd"
let modelUrl = URL(fileURLWithPath: modelPath)
let mom = NSManagedObjectModel(contentsOf: modelUrl)!

let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)

let managedObjectContext = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = psc

try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)

let request: NSFetchRequest<Session> = Session.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "uniqueSessionID", ascending: true)]
let context = managedObjectContext
do {
    let dbReturn = try context.fetch(request)
    print(dbReturn)
}
...