应该重新启动应用程序以更新核心数据(iOS)



我有以下核心数据代码

在我的视图控制器中,我有一个更新标签的按钮

问题是我应该重新启动应用程序或点击两次更新按钮以查看更新的标签似乎数据库更新了,但 UI 没有更新

我的核心数据堆栈:

import Foundation  
import CoreData  
class CoreDataStack: NSObject {  
static let moduleName = "myModel"     
static let sharedInstance = CoreDataStack()  
/  
lazy var managedObjectModel: NSManagedObjectModel = {  
    let modelURL = Bundle.main.url(forResource: 
CoreDataStack.moduleName, withExtension: "momd")!  
    return NSManagedObjectModel(contentsOf: modelURL)!  
}()  
lazy var applicationDocumentsDirectory: URL = {  
    /  
    return NSPersistentContainer.defaultDirectoryURL()  
}()  
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {  
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: 
self.managedObjectModel)  
    let persistentStoreURL =
self.applicationDocumentsDirectory.appendingPathComponent(CoreDataStack.mo
duleName + ".sqlite")  
    do {  
        /  
        try coordinator.addPersistentStore(ofType: NSSQLiteStoreType,  
                                           configurationName: nil,  
                                           at: persistentStoreURL,  
                                           options: [NSMigratePersistentStoresAutomaticallyOption: true,  
                                                     NSInferMappingModelAutomaticallyOption: false])  
    } catch {  
        fatalError("Persistent store error! (error)")  
    }  
    return coordinator  
}()  
fileprivate lazy var saveManagedObjectContext: NSManagedObjectContext = {  
    let moc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)  
    moc.persistentStoreCoordinator = self.persistentStoreCoordinator  
    return moc  
}()  
lazy var managedObjectContext: NSManagedObjectContext = {  
    let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)  
    managedObjectContext.parent = self.saveManagedObjectContext  
    return managedObjectContext  
}()  
func saveMainContext() {  
    guard managedObjectContext.hasChanges || saveManagedObjectContext.hasChanges else {  
        return  
    }  
    managedObjectContext.performAndWait() {  
        do {  
             print("saved data simple")  
            try self.managedObjectContext.save()  
        } catch {  
            fatalError("Error saving main managed object context! (error)")  
        }  
    }  
    saveManagedObjectContext.perform() {  
        do {  
             print("saved data private context")  
            try self.saveManagedObjectContext.save()  
        } catch {  
            fatalError("Error saving private managed object context! (error)")  
        }  
    }  
}  
func createCoreDataContainerOnFirstLaunch() {  
    /  
    let previouslyLaunched = UserDefaults.standard.bool(forKey: "previouslyLaunchedDb2")  
    if !previouslyLaunched {  
        UserDefaults.standard.set(true, forKey: "previouslyLaunchedDb2")  
        /  
        let directory = NSPersistentContainer.defaultDirectoryURL()  
        let url = directory.appendingPathComponent(CoreDataStack.moduleName + ".sqlite")  
        /  
        /  
        let seededDatabaseURL = Bundle.main.url(forResource: CoreDataStack.moduleName, withExtension: "sqlite")!  
        /  
        _ = try? FileManager.default.removeItem(at: url)  
        do {  
            try FileManager.default.copyItem(at: seededDatabaseURL, to: url)  
        } catch let nserror as NSError {  
            fatalError("Error: (nserror.localizedDescription)")  
        }  
        /  
        let seededSHMURL = Bundle.main.url(forResource: CoreDataStack.moduleName, withExtension: "sqlite-shm")!  
        let shmURL = directory.appendingPathComponent(CoreDataStack.moduleName + ".sqlite-shm")  
        _ = try? FileManager.default.removeItem(at: shmURL)  
        do {  
            try FileManager.default.copyItem(at: seededSHMURL, to: shmURL)  
        } catch let nserror as NSError {  
            fatalError("Error: (nserror.localizedDescription)")  
        }  
        /  
        let seededWALURL = Bundle.main.url(forResource: CoreDataStack.moduleName, withExtension: "sqlite-wal")!  
        let walURL = directory.appendingPathComponent(CoreDataStack.moduleName + ".sqlite-wal")  
        _ = try? FileManager.default.removeItem(at: walURL)  
        do {  
            try FileManager.default.copyItem(at: seededWALURL, to: walURL)  
        } catch let nserror as NSError {  
            fatalError("Error: (nserror.localizedDescription)")  
        }  
        print("Seeded Core Data")  
    }  
}  
}

我的应用委托:

 var coreDataStack = CoreDataStack()  
 coreDataStack.createCoreDataContainerOnFirstLaunch()  
       updateDB.updateDatabase(entityName: "myTable") 

我的视图控制器:

 var coreDataStack = CoreDataStack()  
 var MatchList = [Matches]()  
 override func viewDidLoad() {  
    super.viewDidLoad()  
    refreshMatches()  
}  
@objc func updateMatchDetails() {  
   DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {  
        self.MatchList.removeAll()  
        self.updateDB.updateDatabase(entityName: "Matches")  
    DispatchQueue.main.async {  
     self.refreshMatches()  
        }  
    }  

   func updateDatabase(entityName:String){  
    Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding(destination: .queryString), headers: nil).responseJSON{ response in  
        if let jsonObject = response.result.value, let items = jsonObject as? [[String: Any]] {  
            /  
            /  
            guard let entity = NSEntityDescription.entity(forEntityName: entityName, in:(self.dataStack.mainContext)) else {  
                fatalError(LoaderError.NoEntityDescription.rawValue)  
            }  
            self.dataStack.sync(items, inEntityNamed: entity.name!) { result in  
                print(result ?? "updated (entityName)")  
            }  
        } else if let error = response.error {  
            print(error as NSError)  
        } else {  
            print(LoaderError.UnknownError)  
        }  
    }  
}  

func refreshMatches(){  
    do{  
        let request = NSFetchRequest<Matches>(entityName:"Matches")  
        let result = try 
 self.coreDataStack.managedObjectContext.fetch(request)  
        MatchList = result  
        if result.count >= 1{  
            for item in MatchList {  
                let row = item.display!  
                if row == "True"{  
                    if let index = result.index(of: item) {  
                        print("index:(index)")  
                            self.matchStatus.text = "match status: " +  item.matchStatus!  
                            self.view.setNeedsLayout()  
                    }  
                }  
            }  
        }  
    }catch{  
        print("there was an error")  
    }  
}  

@IBAction func update(_ sender: Any) {  
    updateMatchDetails()        
} 

您的网络操作将以异步方式完成,因此在updateDatabase更新核心数据之前调用refreshMatches。 这意味着您只能获得旧数据。

需要从数据同步操作的完成处理程序调用refreshMatches

func updateDatabase(entityName:String){  
    Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding(destination: .queryString), headers: nil).responseJSON{ response in  
        if let jsonObject = response.result.value, let items = jsonObject as? [[String: Any]] {  
            guard let entity = NSEntityDescription.entity(forEntityName: entityName, in:(self.dataStack.mainContext)) else {  
                fatalError(LoaderError.NoEntityDescription.rawValue)  
            }  
            self.dataStack.sync(items, inEntityNamed: entity.name!) { result in  
                print(result ?? "updated (entityName)") 
                DispatchQueue.main.async {
                    self.refreshMatches()
                } 
            }  
        } else if let error = response.error {  
            print(error as NSError)  
        } else {  
            print(LoaderError.UnknownError)  
        }  
    }  
 }

最新更新