我有以下的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()
}
答案 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)
}
}
}