应重新启动应用程序以更新coredata(ios)

时间:2018-01-18 19:13:30

标签: ios swift core-data

我有以下的coredata代码

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

问题是我应该重启应用程序或点击两次更新按钮以查看更新的标签 似乎数据库得到更新但不是ui

我的coreDataStack:

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")  
    }  
}  
}

我的appDelegate:

 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()        
} 

1 个答案:

答案 0 :(得分:0)

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

您需要从数据同步操作的完成处理程序中调用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)  
        }  
    }  
 }