斯威夫特:拯救(过度写作)&加载CoreData

时间:2017-05-05 03:09:28

标签: ios swift core-data

首先,让我解释一下我的应用及其流程。该应用程序打开,用户创建一个配置文件(通过Core Data存储所有数据)。在用户单击create之后,它会将它们发送到控制台屏幕(它显示用户输入的部分信息,例如通过segue的名称)。这是一个标签,让他们编辑他们的个人资料(姓名,体重,地址等)。当用户编辑他们的信息(更改他们的姓名,体重等)时,它还应该更新控制台页面上显示的信息。

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

以下代码......

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不够熟悉,无法确切知道问题所在。

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

1 个答案:

答案 0 :(得分:1)

我怀疑您的数据已被保存。但是每次都要创建一个新对象,而不是更新现有对象的值。每当您拨打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
}