I'm having a news ViewController
and a TeamViewController
. The TeamViewController
contain a tableView of teamObjects which when selected is added into array. I want to add this array into NSUserDefaults
so i can access them from the NewsController
which contain a url request where the teamObjects is needed. However i keep getting:
'Attempt to insert non-property list object ( "" ) for key teams'
I'm open for other suggestions if there is better ways than storing it in NSUserDefaults
didSelectRowAtIndexPath
method
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { tableView.deselectRowAtIndexPath(indexPath, animated: true) let team = self.teamArray[indexPath.row] as Team var removed = false for (index, value) in enumerate(self.teamSelected) { if (value == team) { self.teamSelected.removeAtIndex(index) removed = true } } if (!removed) { self.teamSelected.append(team) } var userDefaults = NSUserDefaults.standardUserDefaults() userDefaults.setValue(self.teamSelected, forKey: "teams") userDefaults.synchronize() tableView.reloadData() }
My object
class Team: NSObject{ var id: Int! var name: NSString! var shortname: NSString! init(id: Int, name:NSString, shortname: NSString) { self.id = id self.name = name self.shortname = shortname } }
Let's take a look at an example. We access the shared defaults object through the standard class property of the UserDefaults class. We then create an array of strings and store the array in the user's defaults database by invoking the set(_:forKey:) method of the UserDefaults database.
It appears the limit is the maximum file size for iOS (logically), which is currently 4GB: https://discussions.apple.com/thread/1763096?tstart=0. The precise size of the data is circumscribed by the compiler types (NSData, NSString, etc.) or the files in your asset bundle.
Storing Default Objects The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Boolean values, and URLs.
Actually, you will need to archive the custom object into NSData
then save it to user defaults and retrieve it from user defaults and unarchive it again. You can archive it like this
let teams = [Team(id: 1, name: "team1", shortname: "t1"), Team(id: 2, name: "team2", shortname: "t2")] var userDefaults = UserDefaults.standard let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: teams) userDefaults.set(encodedData, forKey: "teams") userDefaults.synchronize()
and unarchive it like this
let decoded = userDefaults.data(forKey: "teams") let decodedTeams = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Team]
But if you just did that you will get
.Team encodeWithCoder:]: unrecognized selector sent to instance
You will have to make Team conform to NSCoding just like this
class Team: NSObject, NSCoding { var id: Int var name: String var shortname: String init(id: Int, name: String, shortname: String) { self.id = id self.name = name self.shortname = shortname } required convenience init(coder aDecoder: NSCoder) { let id = aDecoder.decodeInteger(forKey: "id") let name = aDecoder.decodeObject(forKey: "name") as! String let shortname = aDecoder.decodeObject(forKey: "shortname") as! String self.init(id: id, name: name, shortname: shortname) } func encode(with aCoder: NSCoder) { aCoder.encode(id, forKey: "id") aCoder.encode(name, forKey: "name") aCoder.encode(shortname, forKey: "shortname") } }
You can try NSKeyedUnarchiver, like below
Here i stored UIColor Object in UserDefault You can change it with your object
NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color]; [[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];
and to retrive that
NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"]; UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];
Note : This is Objective C but I hope you can covert this in Swift
Hope this solve your problem
Update : Swift 5
Archive in Swift
do{ let colorAsData = try NSKeyedArchiver.archivedData(withRootObject: UIColor.red, requiringSecureCoding: true) UserDefaults.standard.set(colorAsData, forKey: "myColor") UserDefaults.standard.synchronize() }catch (let error){ #if DEBUG print("Failed to convert UIColor to Data : \(error.localizedDescription)") #endif }
Unarchive in Swift
do{ if let colorAsData = UserDefaults.standard.object(forKey: "myColor") as? Data{ if let color = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [UIColor.self], from: colorAsData){ // Use Color } } }catch (let error){ #if DEBUG print("Failed to convert UIColor to Data : \(error.localizedDescription)") #endif }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With