(iOS Swift) 从 Core Data 获取记录返回致命错误或 nil

Posted

技术标签:

【中文标题】(iOS Swift) 从 Core Data 获取记录返回致命错误或 nil【英文标题】:(iOS Swift) Fetching record from Core Data return fatal error or nil 【发布时间】:2016-07-10 04:27:07 【问题描述】:

我开始使用 Swift 为 iPhone 应用程序编写代码,我正面临这个相当令人困惑的障碍,对你们中的一些人来说这可能是微不足道的。我不断收到错误消息,记录是fatal error: unexpectedly found nil while unwrapping an Optional valuenil,但是当我检查.sqlite 时记录在那里

让我带你过去

我的.xcdatamodeld的名字是ReviewerApp.xcdatamodeld,和我的app名字ReviewApp一样 ReviewerApp.xcdatamodeld

我的班级名称是Users,我的实体名称是User

Class: Users, Entity: User

我的属性(用户名、邮箱、密码)都是type: String,有properties: optional

Users.swift

import Foundation

import CoreData

@objc(Users)

class Users: NSManagedObject 

    // Insert code here to add functionality to your managed object subclass

   @NSManaged var username: String?

   @NSManaged var email: String?

   @NSManaged var password: String?



signUpController.swift中的saveUser()函数

func saveUser() 

    // create an instance of our managedObjectContext
    let moc = DataController().managedObjectContext

    // we set up our entity by selecting the entity and context that we're targeting
    let entity = NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: moc) as! Users

    // add our data
    entity.setValue(usernameTxtFld.text, forKey: "username")
    entity.setValue(emailTxtFld.text, forKey: "email")
    entity.setValue(passwordTxtFld.text, forKey: "password")

    // we save our entity
    do 
        try moc.save()
        //user.append(entity)
        print("saved")
     catch 
        fatalError("Failure to save context: \(error)")
    


SignInController.swift 中的fetch() 函数

let moc = DataController().managedObjectContext    
let userFetch = NSFetchRequest(entityName: "User")           
do     
    let fetchedUser = try moc.executeFetchRequest(userFetch) as! [Users]    
    print(fetchedUser.first!.username!)               
  catch 
    fatalError("Failed to fetch person: \(error)")  
 

每次我保存用户注册过程,记录都保存在核心数据中。但每次我试图获取它时:

    by: print(fetchedUser.first!.username!) ,控制台中的消息是fatal error: unexpectedly found nil while unwrapping an Optional value

    by: print(fetchedUser.first?.username) ,控制台中的消息是nil

非常感谢您的帮助,提前

【问题讨论】:

【参考方案1】:

首先我强烈建议您不要使用 '!'代码中的任何位置,因为它会使您的应用程序崩溃(仅适用于静态资源)。你可以使用'if let XXX = YYY as? [...]' 以安全地施放你想要的任何东西...

那么您可能没有在数据库中保存任何内容。你的模型怎么样?您的用户类必须足以满足您构建的模型,否则它将无法工作(这很痛苦),同样在您的模型中,您必须为您的实体提供其类(在“父实体”下方的“类”字段中) .

此外,您不必使用 'entity.setValue(usernameTxtFld.text, forKey: "username")',因为您事先已投射实体。你可以只是'entity.username =usernameTxtFld.text'。

如果我没有提供帮助,请尝试添加 xcdatamodel。

【讨论】:

谢谢你的回复,其实系统提示我加'!'。保存过程很好,我打开 .sqlite 并且数据在那里。我的Class name is set Users'` and Entity 设置为 User``。我用一些细节和图片更新了我的问题 好吧,我猜它们可能是某个地方的拼写错误……也许是 managedContext? (你有几个吗?)否则我觉得一切都是正确的。 是的,正是我的想法。一切对我来说似乎也是正确的,遗憾的是我们没有开发工具来引导我们,就像我们开发 web 时使用的 firefox 或 chrome 一样。这对我来说是新事物,而且令人困惑......【参考方案2】:

我认为你错过了

 let entityDescription = NSEntityDescription.entityForName("User", inManagedObjectContext: moc)

fetchRequest.entity = entityDescription

do 
    let fetchedUser = try moc.executeFetchRequest(fetchRequest)
      print(fetchedUser.first!.username!)
 catch 
    let fetchError = error as NSError
    print(fetchError)

如果获取请求成功,该方法将返回一个结果数组。请注意,如果 fetch 请求成功,Core Data 总是返回一个数组,即使我们期望一个结果或者 Core Data 没有找到任何匹配的记录。

有关更多信息和说明,请访问 -

http://code.tutsplus.com/tutorials/core-data-and-swift-managed-objects-and-fetch-requests--cms-25068

【讨论】:

感谢您的回复,实际上我在问这个问题之前已经阅读了链接。我添加了let fetchRequest = NSFetchRequest() 来声明fetchRequest 变量。但是当我尝试打印 fetchedUser.first!.username! 时,错误消息是 Value of type 'AnyObject' has no member 'username'【参考方案3】:

案件已结案。 DataController.swift 有一些问题。它被调用来保存数据,但是当它被调用来获取数据时,它以某种方式指向不同的地方。所以,我所做的是

    不再使用 DataController.swift

    为我的 AppDelegate.swift 配备 // MARK: - Core Data Saving 支持以保存上下文,因为我没有设置我的应用在开始时包含核心数据

    func saveContext()

        if managedObjectContext.hasChanges 
            do 
                try managedObjectContext.save()
             catch 
                // Replace this implementation with code to handle the error appropriately.
                // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nserror = error as NSError
                NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
                abort()
            
        
    
    

    我将保存功能改为

    func saveUser()

        let appDelegate =
            UIApplication.sharedApplication().delegate as! AppDelegate
    
        let managedContext = appDelegate.managedObjectContext
    
        //2
        let entity = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: managedContext) as! Users
    
    
        //3
        entity.setValue(usernameTxtFld.text, forKey: "username")
        entity.setValue(emailTxtFld.text, forKey: "email")
        entity.setValue(passwordTxtFld.text, forKey: "password")
    
        //4
        do 
            try managedContext.save()
            //5
            message = "Signing up is successful"
            alertMessage(message)
    
         catch let error as NSError  
            print("Could not save \(error), \(error.userInfo)")
        
    
    
    
    

    并将我的获取功能更改为

    func fetch()

        let appDelegate =
            UIApplication.sharedApplication().delegate as! AppDelegate
    
        let managedContext = appDelegate.managedObjectContext
    
        //2
        let fetchRequest = NSFetchRequest(entityName: "Users")
    
        let predicate = NSPredicate(format: "email == %@ AND password == %@", emailTxtFld.text!, passwordTxtFld.text!)
        fetchRequest.predicate = predicate
        //3
        do 
            let results =
                try managedContext.executeFetchRequest(fetchRequest)
            user = results as! [Users]
    
            let row = user.count
    
            if row > 0 
    
                message = "You're signed in"
                //self.performSegueWithIdentifier("signInIdentifier", sender: self)
            else
    
                message = "Email & password combination is incorrect!"
            
    
            alertMessage(message)
    
         catch let error as NSError 
            print("Could not fetch \(error), \(error.userInfo)")
        
    
    
    
    

【讨论】:

以上是关于(iOS Swift) 从 Core Data 获取记录返回致命错误或 nil的主要内容,如果未能解决你的问题,请参考以下文章

iOS:Swift:Core Data:值不使用 Private ManagedObjectContext 存储

Swift - 如何检查现有的 Core Data Store iOS

iOS Swift Core Data 生成带有项目命名空间的 NSManagedObject

iOS swift应用程序中Core Data的奇怪行为

如何在 Core Data iOS Swift 中删除和更新结构类型数组?

Swift 3.0 使用Core Data