更新符号可识别的值的值,并且仅使用UserDefault缓存此值

发布于 2025-01-25 08:15:14 字数 2508 浏览 5 评论 0原文

我有2个结构可编码: student adress (与学生链接)

在我的应用程序上,我从firebase rtdb获取数据,然后我将其存储在UserDefault上 假设学生更改了他的电子邮件,我只想通过更新的电子邮件更新存储的UserDefault。

当我要存储它时,我需要指定所有其他数据(名称,adress,dob ...),或者我只能在不指定其他数据的情况下更新/存储电子邮件?

struct Adress : Codable, Identifiable {
    var id: String { Student_UID }
    var Student_UID: String
    var Student_Street: String
    var Student_Country: String
    var Student_City: String
    
    enum CodingKeys: String, CodingKey  {
        case Student_UID = "Adress_Student_UID"
        case Student_Street = "Student_Street"
        case Student_Country = "Student_Country"
        case Student_City = "Student_City"
        
    }
 
}

struct Student_Profile_Data:Codable, Identifiable   {
    var id: String { Student_UID }
    
    var Student_UID: String
    var Student_firstName: String?
    var Student_username : String?
    var Student_Email : String?
    var Student_lastName: String
    var Student_Address: Adress?
    var Student_DOB: String?
    var Student_Studentpoints : Int?
 
    
    enum CodingKeys: String, CodingKey {
        case Student_UID = "Student_UID"
        case Student_firstName = "Student_firstName"
        case Student_username = "Student_username"
        case Student_Email = "Student_Email"
        case Student_lastName = "Student_lastName"
        case Student_Address = "Student_Address"
        case Student_DOB = "Student_DOB"
        case Student_Studentpoints = "Student_Studentpoints"
     
       
 
    }
    
     
}


The USERDEfault part:

 
 
 //READ
 NSLog("userdefault TEST READ")
 let defaults = UserDefaults.standard
 if let savedStudent = defaults.object(forKey: "SavedStudent") as? Data {
     let decoder = JSONDecoder()
 if let loadedStudent = try? decoder.decode(Student_Profile_Data.self, from: savedStudent) {
     NSLog("TEST PROFILE- username : \(loadedStudent.Student_username)")

 }}
 

//WRITE
let add1 = Adress(Student_UID: "", Student_Street: "", Student_Country: "", Student_City: "")
let stud = Student_Profile_Data(Student_firstName: "", Student_username: "Martin", Student_Email: "", Student_lastName: "", Student_Address: add1, Student_DOB: "", Student_Studentpoints: 0, Student_UID: "")
 let encoder = JSONEncoder()
 if let encoded = try? encoder.encode(stud) {
     let defaults = UserDefaults.standard
     defaults.set(encoded, forKey: "SavedStudent")
     NSLog("WRITE OK »)
 }


//UPDATE ONE (OR TWO) VALUES ?


 

I have 2 structs codable : Student and Adress (which is linked to Student)

On my app, I fetch data from Firebase RTDB and then I store it with userdefault
Let's say a student changes his email and I just want to update the stored userdefault only with that updated email.

Do I need to specify all other data when I want to store it(name,adress,dob...) or can I just only update/store the email on my userdefault without specifying the other data ?

struct Adress : Codable, Identifiable {
    var id: String { Student_UID }
    var Student_UID: String
    var Student_Street: String
    var Student_Country: String
    var Student_City: String
    
    enum CodingKeys: String, CodingKey  {
        case Student_UID = "Adress_Student_UID"
        case Student_Street = "Student_Street"
        case Student_Country = "Student_Country"
        case Student_City = "Student_City"
        
    }
 
}

struct Student_Profile_Data:Codable, Identifiable   {
    var id: String { Student_UID }
    
    var Student_UID: String
    var Student_firstName: String?
    var Student_username : String?
    var Student_Email : String?
    var Student_lastName: String
    var Student_Address: Adress?
    var Student_DOB: String?
    var Student_Studentpoints : Int?
 
    
    enum CodingKeys: String, CodingKey {
        case Student_UID = "Student_UID"
        case Student_firstName = "Student_firstName"
        case Student_username = "Student_username"
        case Student_Email = "Student_Email"
        case Student_lastName = "Student_lastName"
        case Student_Address = "Student_Address"
        case Student_DOB = "Student_DOB"
        case Student_Studentpoints = "Student_Studentpoints"
     
       
 
    }
    
     
}


The USERDEfault part:

 
 
 //READ
 NSLog("userdefault TEST READ")
 let defaults = UserDefaults.standard
 if let savedStudent = defaults.object(forKey: "SavedStudent") as? Data {
     let decoder = JSONDecoder()
 if let loadedStudent = try? decoder.decode(Student_Profile_Data.self, from: savedStudent) {
     NSLog("TEST PROFILE- username : \(loadedStudent.Student_username)")

 }}
 

//WRITE
let add1 = Adress(Student_UID: "", Student_Street: "", Student_Country: "", Student_City: "")
let stud = Student_Profile_Data(Student_firstName: "", Student_username: "Martin", Student_Email: "", Student_lastName: "", Student_Address: add1, Student_DOB: "", Student_Studentpoints: 0, Student_UID: "")
 let encoder = JSONEncoder()
 if let encoded = try? encoder.encode(stud) {
     let defaults = UserDefaults.standard
     defaults.set(encoded, forKey: "SavedStudent")
     NSLog("WRITE OK »)
 }


//UPDATE ONE (OR TWO) VALUES ?


 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

始于初秋 2025-02-01 08:15:14

如果您以这种方式将学生存储在userDefault中,那么更新它将涉及读取学生的三步过程,更新其值,然后将其写回。

// read
let defaults = UserDefaults.standard
let decoder = JSONDecoder()
var savedStudent = defaults.data(forKey: "SavedStudent").flatMap {
    try? decoder.decode(StudentProfileData.self, from: $0)
} ?? StudentProfileData(...) // some "empty" student to use when there is no previously saved student

// update
savedStudent.firstName = "John"

// write
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(savedStudent) {
    defaults.set(encoded, forKey: "SavedStudent")
}

为了使其更加方便,您可以将其提取为一个函数:

func updateSavedStudent(updateBlock: (inout StudentProfileData) -> Void) {
    // read
    let defaults = UserDefaults.standard
    let decoder = JSONDecoder()
    var savedStudent = defaults.data(forKey: "SavedStudent").flatMap {
        try? decoder.decode(StudentProfileData.self, from: $0)
    } ?? StudentProfileData(...) // some "empty" student to use when there is no previously saved student

    // update
    updateBlock(&savedStudent)

    // write
    let encoder = JSONEncoder()
    if let encoded = try? encoder.encode(savedStudent) {
        defaults.set(encoded, forKey: "SavedStudent")
    }
}

// usage:
updateSavedStudent {
    $0.firstName = "John"
    $0.lastName = "Smith"
}

或者,为此保存的学生制作计算的属性,并将其放在某个地方的公用事业类中。请注意,这将对您更新的每个属性进行编码并解码学生一次。

static var savedStudent: StudentProfileData {
    get {
        let defaults = UserDefaults.standard
        let decoder = JSONDecoder()
        return defaults.data(forKey: "SavedStudent").flatMap {
            try? decoder.decode(StudentProfileData.self, from: $0)
        } ?? StudentProfileData(...) // some "empty" student to use when there is no previously saved student
    }
    set {
        let encoder = JSONEncoder()
        if let encoded = try? encoder.encode(newValue) {
            defaults.set(encoded, forKey: "SavedStudent")
        }
    }
}

// usage
savedStudent.firstName = "John"

If you are storing the student in UserDefault in this way, then updating it would involve the three-step process of reading the student, updating its value, then writing it back.

// read
let defaults = UserDefaults.standard
let decoder = JSONDecoder()
var savedStudent = defaults.data(forKey: "SavedStudent").flatMap {
    try? decoder.decode(StudentProfileData.self, from: $0)
} ?? StudentProfileData(...) // some "empty" student to use when there is no previously saved student

// update
savedStudent.firstName = "John"

// write
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(savedStudent) {
    defaults.set(encoded, forKey: "SavedStudent")
}

To make this more convenient, you can extract this as a function:

func updateSavedStudent(updateBlock: (inout StudentProfileData) -> Void) {
    // read
    let defaults = UserDefaults.standard
    let decoder = JSONDecoder()
    var savedStudent = defaults.data(forKey: "SavedStudent").flatMap {
        try? decoder.decode(StudentProfileData.self, from: $0)
    } ?? StudentProfileData(...) // some "empty" student to use when there is no previously saved student

    // update
    updateBlock(&savedStudent)

    // write
    let encoder = JSONEncoder()
    if let encoded = try? encoder.encode(savedStudent) {
        defaults.set(encoded, forKey: "SavedStudent")
    }
}

// usage:
updateSavedStudent {
    $0.firstName = "John"
    $0.lastName = "Smith"
}

Alternatively, make a computed property for this saved student and put it in a utility class somewhere. Do note that this will encode and decode the student once for every property you update though.

static var savedStudent: StudentProfileData {
    get {
        let defaults = UserDefaults.standard
        let decoder = JSONDecoder()
        return defaults.data(forKey: "SavedStudent").flatMap {
            try? decoder.decode(StudentProfileData.self, from: $0)
        } ?? StudentProfileData(...) // some "empty" student to use when there is no previously saved student
    }
    set {
        let encoder = JSONEncoder()
        if let encoded = try? encoder.encode(newValue) {
            defaults.set(encoded, forKey: "SavedStudent")
        }
    }
}

// usage
savedStudent.firstName = "John"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文