Search code examples
iosarraysswiftnsuserdefaultsplist

Saving an array of dictionary coming from plist , with UserDefaults


I need to save my array with UserDefaults because I want users have ability to add or delete rows them selves. I have a plist contains rows of dictionaries. I fill an array name countries with the rows on plist like this

var imageList = ["usaflag","gerflag","franceflag","jpflag","gerflag"]
var countries = [Country]()
override func viewDidLoad() {
    super.viewDidLoad()

    let urlPlist = Bundle.main.url(forResource: "ListinFirstPage", withExtension: "plist")!
    let data = try! Data(contentsOf: urlPlist)
     do
    {
        countries = try PropertyListDecoder().decode([Country].self, from: data)
    }
    catch
    {
        // Handle error
        print(error)
    }

   savePlaces()


  }

Now the Array countries contains my plist rows . (filled with data of rows and works fine). my problem is how to save this array in UserDefaults , as it is an array of dictionaries seems it is a little complicated. I did this like the codes in bottom but it throws a thread in app delegate.

I added this line in viewdidload to call save function

savePlaces()

and then here is my savePlaces function

 func savePlaces(){

    do
    {
        let placesData = try NSKeyedArchiver.archivedData(withRootObject: countries, requiringSecureCoding: false)
    UserDefaults.standard.set(placesData, forKey: "places")
    print("Here is save function")
    }
    catch
    {
    print("SaveError")
    }


}

It seems that problem is because of countries array which it is an array of dictionaries coming from plist, because when I change this line

let placesData = try NSKeyedArchiver.archivedData(withRootObject: countries, requiringSecureCoding: false)

to this

let placesData = try NSKeyedArchiver.archivedData(withRootObject: imageList, requiringSecureCoding: false)

I mean I changed the countries to the imageList which is an array of strings , it works fine. I defined image list in first line

 var imageList = ["usaflag","gerflag","franceflag","jpflag","gerflag"]

so the problem is countries but I do not know why and I will really appreciate for any ideas


Solution

  • You cannot serialize structs with NSKeyedArchiver.

    In Country replace Decodable with Codable and use that to save the array

    func savePlaces() 
    {
        do {
            let placesData = try PropertyListEncoder().encode(countries)                 
            UserDefaults.standard.set(placesData, forKey: "places")
        } catch {
            print(error)
        }
    }