Почему мой одноэлементный класс не сохраняет информацию при перестройке, несмотря на использование пользовательских значений по умолчанию? - PullRequest
1 голос
/ 25 мая 2020

Мне нужно создать структуру MyPerson, которая хранит свойства firstName и lastName, которые мне нужно сохранить и получить к ним глобальный доступ. У меня есть только один "человек" в любой момент времени.

Теперь, хотя мне удалось сделать так, чтобы мой личный экземпляр был доступен глобально, это все еще не сохраняется в сборках. Что я делаю не так?

Кроме того, я был бы очень благодарен, если бы кто-нибудь мог раскритиковать мой код ниже с точки зрения эффективности и точности, я пытаюсь изучить Swift и SwiftUI, не пытаясь использовать обходные пути для всего!

struct MyPerson {
    var firstName: String {
        didSet {
            UserDefaults.standard.set(firstName, forKey: "fn")
        }
    }
    var lastName: String {
        didSet {
            UserDefaults.standard.set(lastName, forKey: "ln")
        }
    }

    init(first: String, last: String) {
        self.firstName = first
        self.lastName = last
    }
}

class Global {

    static let global = Global()

    var person: MyPerson?

    private init() { }
}



struct Home: View {

var body: some View {
Button(action: {

            Global.global.person = MyPerson(first: "John", last: "Doe")                
        }) {
            Text("BUTTON")
        }
   }
   }


struct Home2: View {

var body: some View {
Button(action: {

            guard let user = Global.global.person else {return}
            print(user.firstName)

        }) {
            Text("BUTTON")
        }
   }
   }

Ответы [ 2 ]

0 голосов
/ 25 мая 2020

Вы не загружаете сохраненные данные. Измените структуру MyPerson на это, чтобы сделать его правильным:

struct MyPerson {

    var firstName: String {
        set {
            UserDefaults.standard.set(newValue, forKey: "fn")
        }
        get {
            UserDefaults.standard.string(forKey: "fn") ?? ""
        }
    }

    var lastName: String {
        set {
            UserDefaults.standard.set(newValue, forKey: "ln")
        }
        get {
            UserDefaults.standard.string(forKey: "ln") ?? ""
        }
    }

    init(first: String, last: String) {
        firstName = first
        lastName = last
    }
}
0 голосов
/ 25 мая 2020

Вы пишете в UserDefaults, но никогда не читаете из них. Чтобы сохранить человека в разных сборках, вам нужно проверить, было ли ранее сохранено имя.

Изменить: Наблюдатель didSet не вызывается из инициализатора, поэтому поля должны быть записаны отдельно при инициализации значений. Поскольку вы используете структуру для хранения данных MyPerson, я бы рекомендовал изменить их на свойства let.

Возможно, что-то вроде этого:

struct MyPerson {

    let firstName: String
    let lastName: String

    init(first: String, last: String) {
        self.firstName = first
        self.lastName = last

        UserDefaults.standard.set(firstName, forKey: "fn")
        UserDefaults.standard.set(lastName, forKey: "ln")
    }

    /// Failable initializer that checks for a previously-saved MyPerson
    init?() {
        guard let first = UserDefaults.standard.string(forKey: "fn"),
            let last = UserDefaults.standard.string(forKey: "ln") else {
                return nil
        }

        self.init(first: first, last: last)
    }
}


class Global {

    ...

    private init() {
        if let person = MyPerson() {
            self.person = person
        }
    }
}

Итак, теперь после того, как вы один раз установили глобальное лицо на John Doe в вашем представлении Home, при следующем запуске приложения вы должны увидеть этого человека в Home2.

...