【发布时间】:2020-01-09 23:43:16
【问题描述】:
我的项目中有 CRUD 的以下课程:
class ProjectCoreDataStore: DegreesProtocol, DegreesStoreUtilityProtocol {
// MARK: - Managed object contexts
var mainManagedObjectContext: NSManagedObjectContext
var privateManagedObjectContext: NSManagedObjectContext
// MARK: - Object lifecycle
init()
{
//let fileName: String = "PortalMDBApp.sqlite"
let fileName: String = "MDB.sqlite"
let fileManager:FileManager = FileManager.default
let directory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
let documentUrl = directory.appendingPathComponent(fileName)
let bundleUrl = Bundle.main.resourceURL?.appendingPathComponent(fileName)
// here check if file already exists on simulator
if fileManager.fileExists(atPath: (documentUrl.path)) {
//Document file exists!
//return documentUrl.path
}else if fileManager.fileExists(atPath: (bundleUrl?.path)!) {
//Document file does not exist, copy from bundle!
try! fileManager.copyItem(at:bundleUrl!, to:documentUrl)
}
// MARK: - After pass sqlite to device then run bellow code
// This resource is the same name as your xcdatamodeld contained in your project.
guard let modelURL = Bundle.main.url(forResource: "MDB", withExtension: "momd") else {
fatalError("Error loading model from bundle")
}
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
guard let mom = NSManagedObjectModel(contentsOf: modelURL) else {
fatalError("Error initializing mom from: \(modelURL)")
}
let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
mainManagedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
mainManagedObjectContext.persistentStoreCoordinator = psc
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let docURL = urls[urls.endIndex-1]
/* The directory the application uses to store the Core Data store file.
This code uses a file named "DataModel.sqlite" in the application's documents directory.
*/
let storeURL = docURL.appendingPathComponent("MDB.sqlite")
do {
try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)
} catch {
fatalError("Error migrating store: \(error)")
}
privateManagedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
privateManagedObjectContext.parent = mainManagedObjectContext
}
deinit
{
do {
try self.mainManagedObjectContext.save()
} catch {
fatalError("Error deinitializing main managed object context")
}
}
// MARK: - CRUD operations - Generic enum result type
func updateLanguageDB(idLang: String,
completionHandler: @escaping (() throws -> String) -> Void) {
privateManagedObjectContext.perform {
//MARK: Clear selectedLang
do {
let clears = NSFetchRequest<NSFetchRequestResult>(entityName: "ShortMajorTBL")
let query = NSPredicate(format: "(%K = %@)",
"identifier","L100")
clears.predicate = query
let results = try self.privateManagedObjectContext.fetch(clears)
let resultData = results as! [ShortMajorTBL]
for object in resultData {
object.isSelected = "false"
}
do {
try self.privateManagedObjectContext.save()
}catch{
}
completionHandler{return "SeuccesClear"}
} catch {
completionHandler { throw DegreesStoreError.CannotFetch("Cannot fetch orders") }
}
//MARK: Update selectedLang
do {
let updateRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ShortMajorTBL")
let query = NSPredicate(format: "(%K = %@) AND (%K = %@) AND (%K = %@)",
"isSelected","false",
"langId",idLang.uppercased(),
"identifier","L100")
updateRequest.predicate = query
let results = try self.privateManagedObjectContext.fetch(updateRequest)
let resultData = results as! [ShortMajorTBL]
for object in resultData {
object.isSelected = "true"
}
do {
try self.privateManagedObjectContext.save()
}catch{
}
completionHandler{return "SeuccesUpdate"}
} catch {
completionHandler { throw DegreesStoreError.CannotFetch("Cannot fetch orders") }
}
}
}
func fetchListSelectedLangShortTermDB(completionHandler: @escaping (() throws -> [ShortMajorTBL]) -> Void){
privateManagedObjectContext.perform {
do{
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ShortMajorTBL")
let query = NSPredicate(format: "(%K = %@) AND (%K = %@)",
"isSelected","true",
"identifier","L100")
fetchRequest.predicate = query
let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ShortMajorTBL]
for ss in results{
print("1 >>> \(ss.idLang)")
}
}catch{
}
do{
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ShortMajorTBL")
let query = NSPredicate(format: "(%K = %@) AND (%K = %@)",
"isSelected","true",
"identifier","L100")
fetchRequest.predicate = query
let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ShortMajorTBL]
for ss in results{
print("1 >>> \(ss.idLang)")
print("1 >>> \(ss.id)")
}
}catch{
}
}
}
}
问题:我正在使用func updateLanguageDB 更新记录,当我在func updateLanguageDB 中使用波纹管query 进行测试时,告诉我更新成功:
do{
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ShortMajorTBL")
let query = NSPredicate(format: "(%K = %@) AND (%K = %@)",
"isSelected","true",
"identifier","L100")
fetchRequest.predicate = query
let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ShortMajorTBL]
for ss in results{
print("1 >>> \(ss.id)")
}
}catch{
}
但是当我在其他页面中从上面使用query 时没有得到任何结果??!!
这是我的fun:
func fetchListSelectedLangShortTermDB(completionHandler: @escaping (() throws -> [ShortMajorTBL]) -> Void){
privateManagedObjectContext.perform {
do{
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ShortMajorTBL")
let query = NSPredicate(format: "(%K = %@) AND (%K = %@)",
"isSelected","true",
"identifier","L100")
fetchRequest.predicate = query
let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ShortMajorTBL]
print("1 ++++ \(results.count)")
for ss in results{
print("1 >>> \(ss.idLang)")
print("1 >>> \(ss.id)")
}
}catch{
}
}
}
这是我的xcdatamodeld 和debug sqlite:
通知当我从设备中获取我的sqlite 时,我没有看到任何更新记录。
【问题讨论】:
-
在您的函数中,您在另一个 do/catch 中有一个 do/catch,但只有外部有任何错误处理,因此如果
try self.privateManagedObjectContext.save()抛出错误,它将被忽略,completionHandler{return "SeuccesUpdate"}将错误地处理叫做。因此,在任何地方删除内部的 do/catch 以便在保存失败时实际调用完成处理程序并返回错误。 -
我更新了我的问题,你可以看到。
-
这与我的评论完全无关,你看了吗?查看代码中调用
try self.privateManagedObjectContext.save()的所有位置 -
@乔金丹尼尔森。我在所有 catch 中插入 print 并且没有收到任何错误。
-
好的,那我建议你调试你的代码,试着找出发生了什么,并验证确实有更新的方式。
标签: ios swift core-data nspredicate nsfetchrequest