Search code examples
iosarraysswiftdictionarynsarray

Swift Array append not appending values but replacing it


I am trying to add some dictionaries into an array and save it using UserDefaults, but the problem is the array doesn't append new dictionary but only replaces the dictionary. How can I fix this issue?

here is the code:

class Bookmark: NSObject {

     var bookmark: [[String:Any]] = []

    override init() {
        super.init()
    }



    func setBookmark(imageURL:String, title:String, description:String, summary:String, date:String, link:String)  {
        bookmark.append(["imageURL":imageURL , "title":title , "description":description, "summary":summary , "date":date, "link":link])
        UserDefaults.standard.set(bookmark, forKey: "bookmark")

    }


    func getBookrmark() -> [Any] {
        let loadedBookmark = UserDefaults.standard.array(forKey: "bookmark")
        return (loadedBookmark)!
    }

}

Using Bookmark class:

class ReadViewController: UIViewController  {

    var bookmark = Bookmark()


       func save() {
            bookmark.setBookmark(imageURL: nImageURL.absoluteString, title: ntitle!, description: nDescription.htmlToString , summary: nSummary!, date: nDate!, link: nLink.absoluteString)
        }

Solution

  • There is not enough information but I can guess you where you have made mistake.

    Your class Bookmark is not singleton class so,every time Bookmark() create new instance every time. that means it will create new bookmark object for every instance.

    What I suggest you is inside func func setBookmark(imageURL:String, title:String, description:String, summary:String, date:String, link:String)

    Method 1 : Fetch the latest bookmarks in separate variable and append new object inside it and write to User Default as well as update the global object

    Method 2 Or you can make it singleton and use shared instance for every time you perform operation.

    Method 3 Another solution can be create global object of Bookmark in AppDelegate or Your singleton class and then use that object

    However

    func setBookmark(imageURL:String, title:String, description:String, summary:String, date:String, link:String)  {
            bookmark.append(["imageURL":imageURL , "title":title , "description":description, "summary":summary , "date":date, "link":link])
            UserDefaults.standard.set(bookmark, forKey: "bookmark")
    
      }
    

    This is the bad practice to follow. You are directly replacing User default with new value however your intension is to append new element not replace existing data in userdefault.

    You should always fetch latest and update it Like method 1 show as well as If you wanted to fetch the data in userdefault there is no use of your global object var bookmark: [[String:Any]] = [] because you have already getBookrmark method there

    Hope it is clear to you