Userdefault не работает быстро

Поэтому у меня проблемы с сохранением моих текстовых полей в USERDEFAULTS. Мне удалось использовать этот механизм в моих контактах (как вы можете видеть мой код ниже), и когда я пытаюсь сохранить/загрузить текстовые поля, это не сработало. можете ли вы дать мне какой-либо совет. Спасибо

PBProfile.Swift

class PBProfile {

    var firstName: String = ""
    var lastName: String = ""
    var contacts = [String]()

    func loadFromDefaults() {
        let defaults = UserDefaults.standard
        firstName = defaults.string(forKey: "firstName") ?? ""
        lastName = defaults.string(forKey: "lastName") ?? ""
        contacts = defaults.stringArray(forKey: "contacts") ?? [String]()

    }

    func saveToDefaults() {
        let defaults = UserDefaults.standard
        defaults.set(firstName, forKey: "firstName")
        defaults.set(lastName, forKey: "lastName")
        defaults.set(contacts, forKey: "contacts")
        defaults.synchronize()
    }

}

Делегирование приложения

    var profile: PBProfile!
    var location: PBLocation!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        FIRApp.configure()

        profile = PBProfile()
        profile.loadFromDefaults()
        profile.saveToDefaults()

        location = PBLocation()

        return true
   }

}

Settings.swift

import Foundation
import ContactsUI
import Contacts

class Settings: UIViewController, CNContactPickerDelegate, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource {

    //VARIABLES
    var saveButtonSelected: UIButton!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var firstName: UITextField!
    @IBOutlet weak var lastName: UITextField!
    //--- End of Variables --

    // -- ViewDidLoad --
    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.setHidesBackButton(true, animated: false)
        self.hideKeyboardWhenTappedAround()

        firstName.delegate = self
        lastName.delegate = self

        tableView.reloadData()

        firstName.text = app.profile.firstName
        lastName.text = app.profile.lastName

        app.profile.loadFromDefaults()
    }
    //-- End of ViewDidLoad

    //Prepare for segue
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        app.profile.saveToDefaults()

    }


    //MARK -> ADD CONTACTS BUTTON
    @IBAction func addContactsSelected(_ sender: AnyObject) {

        _ = CNContactPickerViewController()
        let contactPicker = CNContactPickerViewController()
        contactPicker.displayedPropertyKeys = [CNContactPhoneNumbersKey]
        contactPicker.delegate = self

        contactPicker.predicateForSelectionOfContact = NSPredicate (value:false)
        contactPicker.predicateForSelectionOfProperty = NSPredicate(value: true)
        self.present(contactPicker, animated: true, completion: nil)
    }

    //MARK -> WHEN A CONTACT IS SELECTED
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {

        let newitem = contactProperty.value as! CNPhoneNumber
        app.profile.contacts.append(newitem.stringValue)
        app.profile.saveToDefaults()
        tableView.reloadData()

    }

    //MARK -> TABLEVIEW
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return  app.profile.contacts.count

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
        cell!.textLabel?.text = app.profile.contacts[indexPath.row]
        return cell!
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            app.profile.contacts.remove(at: indexPath.row)
            app.profile.saveToDefaults()
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {

        }

    }

person Rarii Narida    schedule 07.12.2016    source источник
comment
Как это не работает? Неверные данные, сбой, ...? – Кажется, вы предполагаете, что didFinishLaunchingWithOptions вызывается до viewDidLoad. Это не обязательно верно, см., например, stackoverflow .com/questions/32827625/.   -  person Martin R    schedule 07.12.2016


Ответы (1)


Вы не сохраняете эти значения. Вы установили делегаты для этих текстовых полей и должны реализовать некоторые методы UITextFieldDelegate. Например:

func textFieldDidEndEditing(_ textField: UITextField) {
    if textField == firstName {
        app.profile.firstName = textField.text
    } else if textField == lastName {
        app.profile.lastName = textField.text
    }
}

(https://developer.apple.com/reference/uikit/uitextfielddelegate/1619591-textfielddidendediting)

Обратите внимание, что это значение сохранится только после завершения редактирования текстового поля (например, вы нажмете на другое текстовое поле, и фокус переместится на него). Если вы хотите сохранять значения при каждом изменении значения, вы можете использовать либо textField(_:shouldChangeCharactersIn:replacementString:) функцию делегата, либо UITextFieldTextDidChange уведомление (https://developer.apple.com/reference/uikit/uitextfielddelegate/1619599-textfield и https://developer.apple.com/reference/foundation/nsnotification.name/1619640-uitextfieldtextdidchange соответственно)

person Łukasz Przytuła    schedule 07.12.2016
comment
Спасибо, это действительно помогло! - person Rarii Narida; 07.12.2016