Swift:保存(全部写入)&加载CoreData

问题描述:

首先,让我解释一下我的应用程序及其流程。应用程序打开,用户创建配置文件(通过Core Data存储所有数据)。在用户点击创建之后,它将它们发送到控制台屏幕(其显示用户输入的部分信息,例如通过搜索的名称)。 Theres一个标签,让他们编辑他们的个人资料(姓名,体重,地址等)。当用户编辑他们的信息(改变他们的名字,体重等)时,它也应该更新控制台页面上显示的信息。Swift:保存(全部写入)&加载CoreData

我已经得到的数据保存和加载。我遇到的问题是当试图从编辑配置文件屏幕编辑数据时...用户更改字段中的文本,然后单击保存。出于某种原因,数据不会保存......至少我认为这是问题所在。当按下“保存”按钮时,无论输入什么文本,文本字段都会返回到用户最初在“创建配置文件”屏幕上输入的内容。

下面的代码...

Person.swift

// This struct would to get the data from the user 
struct PInfo { 
var firstName: String? 
var lastName: String? 
var cityState: String? 
var streetAddress: String? 
var gender: String? 
var weight: NSNumber? 
var phoneNumber: String? 
var contactName: String? 
var contactPhone: String?  
} 

func save(withPersonInfo p: PInfo, withContext context: NSManagedObjectContext) { 
    let entityDescription = NSEntityDescription.entity(forEntityName: "Person", in: context) 
    let managedObject = NSManagedObject(entity: entityDescription!, insertInto: context) as! Person 

    managedObject.firstName = p.firstName 
    managedObject.lastName = p.lastName 
    managedObject.cityState = p.cityState 
    managedObject.streetAddress = p.streetAddress 
    managedObject.gender = p.gender 
    managedObject.weight = p.weight as! Int16 
    managedObject.phoneNumber = p.phoneNumber 
    managedObject.contactName = p.contactName 
    managedObject.contactPhone = p.contactPhone 

    do { 
     try context.save() 
     print("Saved Successful") 
    } 
    catch let error as NSError { 
     print("Could not save. \(error), \(error.userInfo)") 
    } 

} 

func fetchSingleUser(withContext context:NSManagedObjectContext) -> PInfo { 

    let request: NSFetchRequest<Person> = Person.fetchRequest() 
    let coreData_items = try? context.fetch(request) 

    guard let items = coreData_items, 
     let firstItem = items.first 
     else { 
      fatalError("Error while querying") } 
    print("Loaded CoreData Items: \(firstItem)") 

    return PInfo(firstName: firstItem.firstName!, lastName:firstItem.lastName!, cityState: firstItem.cityState!, streetAddress: firstItem.streetAddress!, gender: firstItem.gender!, weight: firstItem.weight as NSNumber, phoneNumber: firstItem.phoneNumber!, contactName: firstItem.contactName, contactPhone: firstItem.contactPhone) 
} 

func userDataExists(withContext context: NSManagedObjectContext) -> Bool { 
    let request: NSFetchRequest<Person> = Person.fetchRequest() 
    let coreData_items = try? context.fetch(request) 

    guard let items = coreData_items, 
     let _ = items.first 
     else { 
      return false } 

    return true 
} 

EditProfileViewController.swift

@IBAction func saveButton(_ sender: UIButton) { 
    //Save to CoreData 
    saveUsersInfo() 

    alertPopup(title: "Saved!", message: "Your information has been updated!") 
    updateTextFields() 
} 

    func updateTextFields() { 
     guard let appDelegate = 
      UIApplication.shared.delegate as? AppDelegate else { 
       return 
     } 
     let managedContext = appDelegate.persistentContainer.viewContext 
     let userInformation = fetchSingleUser(withContext: managedContext) 

     //Set UI Text Fields with Users Data 
     firstNameField.text = userInformation.firstName! 
     lastNameField.text = userInformation.lastName! 
     weightInputField.text = String(describing: userInformation.weight!) 
     genderInputField.text = userInformation.gender! 
     phoneNumberField.text = userInformation.phoneNumber! 
     streetAddressField.text = userInformation.streetAddress! 
     cityStateInputField.text = userInformation.cityState! 
     contactNameField.text = userInformation.contactName 
     contactPhoneNumberField.text = userInformation.contactPhone 
     print("Updated User Info Text Fields") 
    } 

     func saveUsersInfo() { 
     //Save to CoreData 
     guard let appDelegate = 
      UIApplication.shared.delegate as? AppDelegate else { 
       return 
     } 
     let managedContext = appDelegate.persistentContainer.viewContext 
     let userInfo = PInfo(firstName: firstNameField.text!, lastName: lastNameField.text!, cityState: cityStateInputField.text!, streetAddress: streetAddressField.text!, gender: genderInputField.text!, weight: Int16(weightInputField.text!)! as NSNumber, phoneNumber: phoneNumberField.text!, contactName: contactNameField.text!, contactPhone: contactPhoneNumberField.text!) 
     save(withPersonInfo: userInfo, withContext: managedContext) 
     print("User Info Saved") 

     updateTextFields() 

    } 
} 

我相信这是与储蓄(由于调试)的问题,但我不太熟悉CoreData确切地知道问题是什么。

任何帮助/信息非常感谢!

+0

你不需要'PInfo'结构 - 核心数据是一个对象持久化系统。使用'Person'(Xcode根据您的Enity自动为您创建)而不是'NSManagedObject' – Paulw11

我怀疑你的数据被保存。但是您每次都创建一个新对象,而不是更新现有对象的值。当你打电话给你save方法,这行:

let managedObject = NSManagedObject(entity: entityDescription!, insertInto: context) as! Person 

创建一个新的Person对象。而当你调用fetchSingleUser方法,您获取所有Person对象:

let coreData_items = try? context.fetch(request) 

但随后只用前这些项目:

let firstItem = items.first 

它发生的第一个项目是原Person对象,与原始值:因此textFields恢复到那些原始值。

如果您的应用程序应该只有一个Person对象,在你save方法改变save方法来获取现有对象,并更新该实例的属性值,例如:

var managedObject : Person 
let request: NSFetchRequest<Person> = Person.fetchRequest() 
let coreData_items = try? context.fetch(request) 
if let items = coreData_items { 
    if items.count > 0 { 
     managedObject = items.first 
    } else { 
     managedObject = NSManagedObject(entity: entityDescription!, insertInto: context) as! Person 
    } 
    managedObject.firstName = p.firstName 
    ... etc 
} else { 
    // coreData_items is nil, so some error handling here 
} 
+0

谢谢!现在一切都说得通了!我感谢帮助! – szady