LgSus97
LgSus97

Reputation: 93

Delete item from UserDefaults

I saved an array of structs to userDefaults but when I have two items with the same id I should have to delete the old and set the new, what it the best way to do that? My idea was get the item with the same id an delete it, then set the new because the id is the same but date its different or the other way could be get the element with the same id and just update the date

struct ListQR: Codable {
    var resultQR:String?,
        name:String?,
        amout:String?,
        id:String?,
        date:String?
}
private var listaQR:[ListQR] = []

override func viewDidLoad() {
        super.viewDidLoad()
        updateData()
}
func updateData(){
         let a =  ListQR(resultQR: "1234567",
                         name: "YISUS",
                         amount: "9.99",
                         id: "00000001",
                         date: "09-05-2021")
         var s:[ListQR] = []
         let f = load()
         s = f
         s.append(a)
         save(s)
}
func save(_ qr: [ListQR]){
     let data = qr.map{
         try? JSONEncoder().encode($0)
     }
     defaults.setValue(data, forKey:"isPosponerQR" )
 }
func load() -> [ListQR] {
      guard let encodedData = UserDefaults.standard.array(forKey: "isPosponerQR") as? [Data] else {
            return []
      }
      return encodedData.map { try! JSONDecoder().decode(ListQR, from: $0) }
}
// In this function I evaluate if the I have two items with the same id
func checkRepeat(){
     let id = "00000001"
      for x in load(){
        if id == x.id{   
            var j:[ListQR] = []
            var f = load()
            j = f
// In this line I want to delete the item with the same id
// I got this : Referencing operator function '==' on 'StringProtocol' requires that 'ListQR' conform to 'StringProtocol'
            j.removeAll(where: {$0 == id})

        }
}

For example: I have this item stored in UserDefaults

ListQR(resultQR: "1234567",
       name: "YISUS",
       amount: "9.99",
       id: "00000001",
       date: "09-05-2021")

I want to save this but have the same id and different date, so I want to delete the item that I saved in UserDefaults or update the date

ListQR(resultQR: "1234567",
       name: "YISUS",
       amount: "9.99",
       id: "00000001",
       date: "10-01-2021")

Upvotes: 0

Views: 212

Answers (1)

vadian
vadian

Reputation: 285082

Most likely your load method doesn't work because you save Data, not[Data].

func load() -> [ListQR] {
      guard let encodedData = UserDefaults.standard.data(forKey: "isPosponerQR") else { return [] }
      return try? JSONDecoder().decode([ListQR].self, from: encodedData) ?? []
}

To update the data look for the index of the new id, if there is one replace it, if not append the record.

func updateData(){
     let newListQR = ListQR(resultQR: "1234567",
                     name: "YISUS",
                     amount: "9.99",
                     id: "00000001",
                     date: "09-05-2021")
     var currentData = load()
     if let index = currentData.firstIndex(where: {$0.id == "00000001"}) {
        currentData[index] = newListQR
     } else {
        currentData.append(newListQR)
     }
     save(currentData)
}

And don't use value(forKey unless you mean KVC (you don't)

defaults.set(data, forKey:"isPosponerQR" )

Note: It seems that all struct members have values, if so, it's pointless to declare everything as optional.

Upvotes: 1

Related Questions