将 sqlite 预加载到核心数据

时间:2021-05-06 11:51:58

标签: swift core-data swiftui

我试图在第一次运行时使用 sqlite 文件将数据预加载到核心数据。我首先创建了一个xcdatamodeld文件,然后使用python生成了sqlite数据库,它的数据结构与我所说的xcdatamodeld完全相同。

@main
struct ArgosApp: App {
    
    
    static var isFirstLaunch = isAppAlreadyLaunchedOnce()

      // MARK:- Initialise Core Data Stack
    
       var persistentContainer: NSPersistentContainer = {
        
        let container = NSPersistentContainer(name: "Argos")

        // if it is, load data from sql
        if ArgosApp.isFirstLaunch {
            
            guard let seededDataURL = Bundle.main.url(forResource: "karate", withExtension: "sqlite") else {
                fatalError("Fail to find")
            }
            let storeUrl = ArgosApp.getDocumentsDirectory().appendingPathComponent("karate.sqlite")
            
            if !FileManager.default.fileExists(atPath: (storeUrl.path)) {
                try! FileManager.default.copyItem(at: seededDataURL, to: storeUrl)
            }
            
            let description = NSPersistentStoreDescription()
            description.shouldInferMappingModelAutomatically = true
            description.shouldMigrateStoreAutomatically = true
            description.url = storeUrl
            description.type = "sqlite"

            container.persistentStoreDescriptions = [description]
                
            // ERROR came in here: Thread 1: "Unsupported store type."
            container.loadPersistentStores(completionHandler: { (storeDescription, error) in
                if let error = error as NSError? {
                    fatalError("Unresolved error \(error), \(error.userInfo)")
                }
            })
            return container
        }
        
        // else, load from core data
        else {
            container.loadPersistentStores { storeDescription, error in
              if let error = error as NSError? {
                // TODO:- More decent error handling
                fatalError("Unresolved error \(error), \(error.userInfo)")
              }
            }
        }
        return container
    }()

        
    var body: some Scene {
        WindowGroup {
            let context = persistentContainer.viewContext

            let categories = Category.fetchAllCategories(context: context) ?? []
            // Pass the persistent container to the view as environment object
            ChallengeChooser(categories: categories)
                .environment(\.managedObjectContext
                             ,context)
        }
    }
    
    
    // Detect if it's the first-launch
    
    static func isAppAlreadyLaunchedOnce() -> Bool {
        let defaults = UserDefaults.standard
        if let _ = defaults.string(forKey: "isAppAlreadyLaunchedOnce") {
            print("App already launched")
            return false
        } else {
            defaults.set(true, forKey: "isAppAlreadyLaunchedOnce")
            print("App launched first time")
            return true
        }
    }
    
    func saveContext (context: NSManagedObjectContext) {
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }
    
    static func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let documentsDirectory = paths[0]
        return documentsDirectory
    }
}


当我尝试加载数据库时出现错误

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported store type.'

这是我用 sqlite3 运行的代码,我在上面添加了一些测试数据,所以 difficultyexplanation 列都是 NULL。

cur.execute("""
CREATE TABLE category (
  name VARCHAR(40) PRIMARY KEY
  );
 """)
cur.execute("""
CREATE TABLE video (
  url VARCHAR(100) PRIMARY KEY,
  explanation VARCHAR(300),
  difficulty INT,
  category VARCHAR(40),
  FOREIGN KEY(category) REFERENCES category(name)
  ON DELETE CASCADE
  ON UPDATE CASCADE
  );
 """)

这就是我的 xcdatamodeld 的样子,我将 nameurl 设置为非可选。

enter image description here

0 个答案:

没有答案
相关问题