繁体   English   中英

如何在核心数据Swift 3中使用persistentStore(for:url)

[英]How to use persistentStore(for: url) in core data Swift 3

我正在尝试执行以下操作:

轻按的小区UITableView细胞然后segue到下一个UIViewController和显示数据库的结果。 但是有多个持久性存储,因此指定的存储由单元标签文本指定。

问题是:如何使用方法persistentStore(for: url) 还是有其他方法为fetchRequest指定持久存储?

这是我的代码不起作用:

func wordFetchRequest() -> NSFetchRequest<Word> {
    let fr = NSFetchRequest<Word>(entityName: "Word")
    fr.fetchBatchSize = 100

    // Assigning sort descriptors
    let firstLetterSort = NSSortDescriptor(key: #keyPath(Word.firstLetter), ascending: true)
    let spellSort = NSSortDescriptor(key: #keyPath(Word.spell), ascending: true)
    fr.sortDescriptors = [firstLetterSort, spellSort]

    // Get URL of the designated store to fetch
    let libname = (AppDelegate.nameDict as NSDictionary).allKeys(for: nameToFetch).first!

// I'm not sure the following line: which file should I use? I've tried
//.sqlite, .sqlite-shm and .sqlite-wal but none worked.
    let url = AppDelegate.coreDataStack.storeDirectory.appendingPathComponent("\(libname).sqlite-wal")

    // Specify affected store for the fetch request
    var pss = [NSPersistentStore]()
    print(url)

// The following line fails:
    if let ps = coreDataStack.psc.persistentStore(for: url) {
        pss.append(ps)
    } else {

    }

    fr.affectedStores = pss
    print(fr.affectedStores ?? "No stores available.")
    return fr
}

任何帮助都感激不尽。

我不得不处理类似的情况,即我拥有不同的持久性存储(具体来说,一种类型为NSInMemoryStoreType,而另一种类型为NSSQLiteStoreType

我发现为每个商店创建单独的持久性存储协调器和使用这些持久性存储(如父存储)创建单独的管理对象上下文更容易:

这是用iOS 9 swift 3编写的代码,因此具有较旧的核心数据堆栈操作,我已经看到了iOS 10 Swift 3 Core数据堆栈,我相信这些方法仍然可以使您了解这里所说的内容:)

这就是你将默认在Coredata堆栈看到,getter方法persistentStoreCoordinator

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
        // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
        // Create the coordinator and store
        let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
        let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
        var failureReason = "There was an error creating or loading the application's saved data."
        do {
            try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
            log.debug(url)
        } catch let error as NSError {
            // Report any error we got.
            var dict = [String: AnyObject]()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
            dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?

            dict[NSUnderlyingErrorKey] = error
            let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
            // Replace this with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
            abort()
        }
        catch{

        }
        return coordinator
    }()

重要的声明是

try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)

如您所见,它将持久性存储类型指定为Sqlite并将configurationName指定为nil,这意味着默认配置:)

您可以在Coredata中创建多个配置,并在此语句中指定名称,以便为每个配置创建单独的持久性存储协调器:)

您可以在我的博客中查看是否可以使用敏感信息信任核心数据,以了解如何创建多个配置和存储:)

因此,假设您创建了另一个配置并向其中添加了实体,并将其称为“ Test1”配置,您将为此创建一个单独的持久性存储协调器,

lazy var test1PersistentStoreCoordinator: NSPersistentStoreCoordinator = {
    // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
    // Create the coordinator and store
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try coordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: "Test1", at: url, options: nil)
        log.debug(url)
    } catch let error as NSError {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
        dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?

        dict[NSUnderlyingErrorKey] = error
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }
    catch{

    }
    return coordinator
}()

现在,您有两个与两种不同配置关联的持久性存储协调器,只需使用这些持久性存储协调器作为其父存储创建两个托管对象上下文:)

   lazy var managedObjectContext: NSManagedObjectContext = {
        // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
        let coordinator = self.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }()


    lazy var managedObjectContextForBackTracking : NSManagedObjectContext = {
        let coordinator = self.test1PersistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }()

而已 :)

现在,在相应的ManagedObject上下文上运行获取请求:),确保没有混乱您的核心数据:)

希望能帮助到你 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM