gpt4 book ai didi

ios - 如何使核心数据 ManagedObjectContext.ExecuteFetchRequest 同步而不是异步

转载 作者:行者123 更新时间:2023-11-28 21:30:37 24 4
gpt4 key购买 nike

附件是我的代码。

给我问题的那一行是 let fetchRequest = try moc.executeFetchRequest(fetchRequest) as! [AppSettings] 似乎异步加载,但我希望它同步加载,以便我可以确保它正确检查用户名记录。

我该怎么做?

我知道它是异步加载的,因为当我不断地启动和停止程序时,它会在大约 80% 的时间内找到实体,而在随机的 20% 的时间内找不到实体。由于没有其他东西在改变实体(因为我只是不断地启动和停止程序),所以当我使用命令

时,代码正在异步运行是有意义的
guard let appSettingsArrayItem = fetchRequest.first where fetchRequest.count>0 else {
print ("no entities found...")
return false
}

有时找不到任何实体。

检查登录功能

func checkIfLoggedInAlready() -> Bool{
let fetchRequest = NSFetchRequest(entityName: "AppSettings")
//let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest) //Deletes ALL appsettings entities

do {

let fetchRequest = try moc.executeFetchRequest(fetchRequest) as! [AppSettings]

guard let appSettingsArrayItem = fetchRequest.first where fetchRequest.count>0 else {
print ("no entities found...")
return false
}

guard let username = (appSettingsArrayItem as AppSettings).username else{
print ("username not found")
return false
}

print("number Of AppSetting Entities =\(fetchRequest.count)")
print(username)

//The following code deletes ALL the entities!
//try moc.persistentStoreCoordinator!.executeRequest(deleteRequest, withContext: moc)

//To delete just '1' entry use the code below.

//moc.deleteObject(appSettingsArrayItem)
//try moc.save()//save deletion change.

//print("deleted particular entity item")

return true
} catch{
fatalError("bad things happened \(error)")
}


}

整个 LoginViewController 包括检查登录功能

import UIKit
import CoreData

class LoginViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var usernameField: UITextField!
@IBOutlet weak var passwordField: UITextField!

var isLoggedIn = false

let moc = DataController().managedObjectContext

@IBAction func SignUpButtonPressed(sender: UIButton) {
print("sign up")
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}

func textFieldShouldEndEditing(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}


override func viewDidLoad() {
super.viewDidLoad()

let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
view.addGestureRecognizer(tap)

print("view loaded, check if already signed in here")

let loggedIn = checkIfLoggedInAlready() //checks database to see

if(loggedIn){
print("was logged in!")
isLoggedIn = true

self.performSegueWithIdentifier("loginSegue", sender: self)
}
}

func checkIfLoggedInAlready() -> Bool{
let fetchRequest = NSFetchRequest(entityName: "AppSettings")
//let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest) //Deletes ALL appsettings entities

do {

let fetchRequest = try moc.executeFetchRequest(fetchRequest) as! [AppSettings]

guard let appSettingsArrayItem = fetchRequest.first where fetchRequest.count>0 else {
print ("no entities found...")
return false
}

guard let username = (appSettingsArrayItem as AppSettings).username else{
print ("username not found")
return false
}

print("number Of AppSetting Entities =\(fetchRequest.count)")
print(username)

//The following code deletes ALL the entities!
//try moc.persistentStoreCoordinator!.executeRequest(deleteRequest, withContext: moc)

//To delete just '1' entry use the code below.

//moc.deleteObject(appSettingsArrayItem)
//try moc.save()//save deletion change.

//print("deleted particular entity item")

return true
} catch{
fatalError("bad things happened \(error)")
}


}

func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
print("prepare seque")
}

func displayErrorMessage(errorMessage: String){
print("show error console with Error:"+errorMessage)
let alert = UIAlertController(title: "Error", message: errorMessage, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}

override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
switch(identifier){
case "loginSegue":
print("Is the user already logged in?")
if(isLoggedIn){
print("Detected as YES")
return true
}
print("Detected as NO, so checking username and password fields next...")

guard let password = passwordField.text!.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet()) where !password.isEmpty else {
displayErrorMessage("Password can not be empty!")
return false
}

guard let username = usernameField.text!.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet()) where !username.isEmpty else{
displayErrorMessage("Username can not be empty!")
return false
}

let url = "http://distribution.tech/restapi/v1/userlogin?email="+username+"&password="+password
print(url)

let json = JSON(url:url)
print(json)

if(json["status"].asInt==1){

let entity = NSEntityDescription.insertNewObjectForEntityForName("AppSettings", inManagedObjectContext: moc) as! AppSettings

entity.setValue(username, forKey: "username")
entity.setValue(password, forKey: "password")
entity.setValue(json["tokenid"].asString, forKey: "token")
entity.setValue(json["roleid"].asInt, forKey: "roleid")
entity.setValue(json["role"].asString, forKey: "role")
entity.setValue(json["companyid"].asInt , forKey: "companyid")
entity.setValue(json["isdev"].asInt, forKey: "isdev")

//save token and other details to database.
do {
try moc.save()
print("saved to entity")
}catch{
fatalError("Failure to save context: \(error)")
}

// token
// roleid int
// role
// companyid int
//
// {
// "companyid": 3,
// "userid": 2,
// "tokenid": "804febae26ddbd0292b3d2c66b30afd5028d5ba9",
// "status": 1,
// "roleId": 1,
// "role": "super_admin",
// "isdev": 0
// }

//Save to disk using our own method, as COREDATA is unreliable!

return true //login succesfull
}else{
displayErrorMessage("Incorrect Username or Email")
return false//failed
}

default:
displayErrorMessage("Unknown Error Related To Segue Not Found")
}
return false //if it gets to this point assume false
}


}

托管对象在 DataController 中创建,其文件位于下方。

import UIKit
import CoreData

class DataController: NSObject {
var managedObjectContext: NSManagedObjectContext
override init() {
// This resource is the same name as your xcdatamodeld contained in your project.
guard let modelURL = NSBundle.mainBundle().URLForResource("AppSettings", 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(contentsOfURL: modelURL) else {
fatalError("Error initializing mom from: \(modelURL)")
}
let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
self.managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
self.managedObjectContext.persistentStoreCoordinator = psc
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .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.URLByAppendingPathComponent("AppSettings.sqlite")
do {
try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
} catch {
fatalError("Error migrating store: \(error)")
}
}
}
}

有时会发生的实体和控制台错误的图像引用

enter image description here

实体和控制台在大多数情况下找到实体时的图像引用

enter image description here

最佳答案

ManagedObjectContext.ExecuteFetchRequest 已经同步运行,但看起来您正在后台优先线程中异步设置持久存储协调器。

如果此获取请求在应用启动时立即发生,并且您一遍又一遍地执行此操作,则有时可能无法完成设置。

关于ios - 如何使核心数据 ManagedObjectContext.ExecuteFetchRequest 同步而不是异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36223656/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com