Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attempt to insert non-property list object when trying to save a custom object in Swift 3

I have a simple object which conforms to the NSCoding protocol.

import Foundation  class JobCategory: NSObject, NSCoding {     var id: Int     var name: String     var URLString: String      init(id: Int, name: String, URLString: String) {         self.id = id         self.name = name         self.URLString = URLString     }      // MARK: - NSCoding     required init(coder aDecoder: NSCoder) {         id = aDecoder.decodeObject(forKey: "id") as? Int ?? aDecoder.decodeInteger(forKey: "id")         name = aDecoder.decodeObject(forKey: "name") as! String         URLString = aDecoder.decodeObject(forKey: "URLString") as! String     }      func encode(with aCoder: NSCoder) {         aCoder.encode(id, forKey: "id")         aCoder.encode(name, forKey: "name")         aCoder.encode(URLString, forKey: "URLString")     } } 

I'm trying to save an instance of it in UserDefaults but it keeps failing with the following error.

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object for key jobCategory'

This is the code where I'm saving in UserDefaults.

enum UserDefaultsKeys: String {     case jobCategory }  class ViewController: UIViewController {      @IBAction func didTapSaveButton(_ sender: UIButton) {         let category = JobCategory(id: 1, name: "Test Category", URLString: "http://www.example-job.com")          let userDefaults = UserDefaults.standard         userDefaults.set(category, forKey: UserDefaultsKeys.jobCategory.rawValue)         userDefaults.synchronize()     } } 

I replaced the enum value to key with a normal string but the same error still occurs. Any idea what's causing this?

like image 972
Isuru Avatar asked Dec 28 '16 04:12

Isuru


People also ask

How do you save an array of objects in userDefaults in Swift?

You'll need to convert the object to and from an NSData instance using NSKeyedArchiver and NSKeyedUnarchiver . For example: func savePlaces(){ let placesArray = [Place(lat: 123, lng: 123, name: "hi")] let placesData = NSKeyedArchiver. archivedDataWithRootObject(placesArray) NSUserDefaults.

What is NSUserDefaults in Swift?

Overview. The NSUserDefaults class provides a programmatic interface for interacting with the defaults system. The defaults system allows an app to customize its behavior to match a user's preferences. For example, you can allow users to specify their preferred units of measurement or media playback speed.


1 Answers

You need to create Data instance from your JobCategory instance using archivedData(withRootObject:) and store that Data instance in UserDefaults and later unarchive using unarchiveTopLevelObjectWithData(_:), So try like this.

For Storing data in UserDefaults

let category = JobCategory(id: 1, name: "Test Category", URLString: "http://www.example-job.com") let encodedData = NSKeyedArchiver.archivedData(withRootObject: category, requiringSecureCoding: false) let userDefaults = UserDefaults.standard userDefaults.set(encodedData, forKey: UserDefaultsKeys.jobCategory.rawValue) 

For retrieving data from UserDefaults

let decoded  = UserDefaults.standard.object(forKey: UserDefaultsKeys.jobCategory.rawValue) as! Data let decodedTeams = NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(decoded) as! JobCategory print(decodedTeams.name) 
like image 194
Nirav D Avatar answered Sep 25 '22 06:09

Nirav D