将我的用户保存到CoreData似乎正在保存,因为do catch
保存块不会引发任何错误,实际上我确实获得了成功打印,但是在加载已保存的用户时找不到。
我注意到了这一点,因为当我启动该应用程序时,每次登录时都会从firebase下载用户。
基本上,整个逻辑是:
登录调用User.findUser()
,它将在CoreData中寻找用户
如果找到,它将仅加载用户详细信息并继续,否则将调用Firebase.downloadUserDetails()
,它将在Firebase中寻找用户(在这种情况下,这是用户首次在设备上启动应用程序)。如果找到,它将下载用户的详细信息并调用User.saveUserDetails()
,将用户保存到CoreData。因此,在下次登录时应该找到它。好吧,如果我在此之后重新运行应用程序,User.findUser()
仍然找不到任何用户,然后重新启动整个过程。
我以前没有意识到这一点,因为User.saveUserDetails()
在保存时不显示任何错误,但是我在CoreData中添加了对任何User
记录的检查,并且始终显示0
您能看到发生了什么吗?如何检查是否在AppDelegate中正确设置了CoreData?
这是保存功能:
static func saveUserDetails(completed: @escaping(Bool) -> (),userId: String, fcmToken: String, email: String, fullName: String, familyName: String, givenName: String, profileImage: UIImage, address: String, city: String, zipCode: String, region: String, country: String, phoneNumber: String) {
let context = AppDelegate.viewContext
//check if user is already in database
let request: NSFetchRequest<User> = User.fetchRequest()
// check for any existing records in CoreData
print("check for any existing records in CoreData")
do {
let fetchPre = try context.fetch(request)
print("saveUserDetails: Users saved in CoreData are: \(fetchPre.count)")
for user in fetchPre {
print("User id is : \(String(describing: user.userId))")
print("User name is : \(String(describing: user.fullName))")
}
} catch {
print(" Error fetching user during saving : \(error)")
}
request.predicate = NSPredicate(format: "userId == %@", userId)
// request.fetchLimit = 1
do {
let fetch = try context.fetch(request)
print("saveUserDetails: fetch is \(fetch.count)")
for value in fetch {
print(" User/saveUserDetails: checking for existing user")
if userId == value.userId {
print(" user is already saved ")
// save changes in database
// value.setValue(userId, forKey: "userId")
value.setValue(fcmToken, forKey: "fcmToken")
value.setValue(fullName, forKey: "fullName")
value.setValue(familyName, forKey: "familyName")
value.setValue(givenName, forKey: "givenName")
value.setValue(address, forKey: "address")
value.setValue(city, forKey: "city")
value.setValue(region, forKey: "region")
value.setValue(zipCode, forKey: "zipCode")
value.setValue(country, forKey: "country")
value.setValue(phoneNumber, forKey: "phoneNumber")
value.setValue(email, forKey: "email")
// return
} else {
print(" User/saveUserDetails: user is new")
//create user in database
let user = User(context: context)
user.userId = userId
user.fcmToken = fcmToken
user.fullName = fullName
user.familyName = familyName
user.givenName = givenName
user.address = address
user.zipCode = zipCode
user.city = city
user.region = region
user.country = country
user.phoneNumber = phoneNumber
user.profilePicture = UIImageJPEGRepresentation(profileImage, 1.0)! as NSData
}
do {
// save changes in database
try context.save()
print(" User/saveUserDetails: user is saved")
completed(true)
} catch {
print("Error saving user details : \(error)")
}
}
} catch {
print(" Error fetching user during saving : \(error)")
}
}
答案 0 :(得分:1)
您的代码中存在一个逻辑错误,现在您要做
let fetch = try context.fetch(request)
for value in fetch {
if userId == value.userId {
...
} else {
...
}
由于您的请求谓词为“ userId ==%@”(即userId),因此只有在找到具有给定ID的用户时,才进入for
循环,这意味着else
部件永远无法执行,也无法创建新用户。
一世
因此,我建议不要使用for
循环
if let user = fetch.first { //I assume the predicate means we get one or zero users back
//Handle user update
} else {
//Handle new user
}