Get "Does Not Implement Methodsignatureforselector" When Try to Store Array in Nsuserdefaults,Swift

Error while adding array of own objects to UserDefaults in Swift 3.1

Ok, I hope that this time I wont't make any mistake - the problem was solved by rmaddy in other "topic", but vadian was very, but very close - to implement NSCoding I need to inherit from NSObject as he wrote but also from... NSCoding! Isn't it obvious? For me it wasn't... In the other hand maybe he tried to tell me that I should inherit from both but my english was to bad to get it. Anyway I found an answer so thank You very much Vadian, Rmaddy and sorry one more time for breaking some kinds of SOF rules... It was first and last time! Oh and there is a thread when I finally find the answer, and yeap I was blind that I missed it earlier - encodeWithCoder: unrecognized selector sent to instance

Storing Set CustomObject to UserDefaults

You can set the model to UserDefaults like this:

  • Firstly you should create an instance of your model

  • And then you can save your model to UserDefaults:

    let encoder = JSONEncoder()
    if let encoded = try? encoder.encode(listItemInstance) {
    let defaults = UserDefaults.standard
    defaults.set(encoded, forKey: "ListItemObject")
    }

    You can get model from UserDefaults like this

    if let savedItem = defaults.object(forKey: "ListItemObject") as? Data {
    let decoder = JSONDecoder()
    if let loadedItem = try? decoder.decode(ListItem.self, from: savedItem) {
    print(loadedItem)
    }
    }

Saving dictionary into NSUserDefaults

From the NSUserDefaults documentation:

The value parameter can be only property list objects: NSData,
NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and
NSDictionary objects, their contents must be property list objects.
See “What is a Property List?” in Property List Programming Guide.

You cannot store a dictionary with elements of Element in the dictionary.

One option is to make sure Element implements the NSCoding protocol and then use NSKeyedArchiver to convert your dictionary into NSData:

// Storing the dictionary
var data = NSKeyedArchiver.archivedDataWithRootObject(theDict)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: tableViewData)

// Retrieving the dictionary
var outData = NSUserDefaults.standardUserDefaults().dataForKey(tableViewData)
var dict = NSKeyedUnarchiver.unarchiveObjectWithData(outData)

Your protocol implementation would look like something like this:

init(coder aDecoder: NSCoder!) {
self.state = State.fromRaw(aDecoder.decodeObjectForKey("state") as String)
}

func encodeWithCoder(aCoder: NSCoder!) {
aCoder.encodeObject(self.state.toRaw(), forKey: "state")
}

You cannot store an Enum, but you can store the raw representation of it which is a string.

Trying to save custom object in UserDefaults using NSKeyedArchiver

Use JSONEncoder to save data to UserDefaults. Dummy code:

class YourClassName: Codable {
//Your properties here

func saveInPreference() {
do {
let jsonEncoder = JSONEncoder()
UserDefaults.standard.set(try jsonEncoder.encode(Your object here), forKey: "Write UserDefaultKey here")
UserDefaults.standard.synchronize()
}
catch {
print(error.localizedDescription)
}
}
}

Hope that helps!

@Faraz A. Khan comment if you have any questions in the above piece of code.

How to archive and unarchive custom objects in Swift? Or how to save custom object to NSUserDefaults in Swift?

NSKeyedArchiver will only work with Objective-C classes, not pure Swift classes. You can bridge your class to Objective-C by marking it with the @objc attribute or by inheriting from an Objective-C class such as NSObject.

See Using Swift with Cocoa and Objective-C for more information.



Related Topics



Leave a reply



Submit