【问题标题】:(iOS Swift) Fetching record from Core Data return fatal error or nil(iOS Swift) 从 Core Data 获取记录返回致命错误或 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)")  
 }

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

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

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

非常感谢您的帮助,提前

【问题讨论】:

    标签: ios iphone swift core-data


    【解决方案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 有一些问题。它被调用来保存数据,但是当它被调用来获取数据时,它以某种方式指向不同的地方。所以,我所做的是

    1. 不再使用 DataController.swift
    2. 为我的 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()
              }
          }
      }
      
    3. 我将保存功能改为

      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)")
          }
      
      
      }
      
    4. 并将我的获取功能更改为

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

    【讨论】:

      猜你喜欢
      • 2016-06-06
      • 1970-01-01
      • 2012-12-14
      • 1970-01-01
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      相关资源
      最近更新 更多