Reputation: 8516
I am trying to save NSIndexPath
at NSUserDefaults
, but got the following exception:-
Attempt to set a non-property-list object {length = 2, path = 0 - 12} as an NSUserDefaults/CFPreferences value for key LastSelectedIndeX
My code:-
let selectedIndexPath = tableView.indexPathForSelectedRow
NSUserDefaults.standardUserDefaults().setObject(selectedIndexPath, forKey: "lastSelectedIndex")
NSUserDefaults.standardUserDefaults().synchronize()
So how can I save NSIndexPath
so that I can use it later on at another view controller.
Upvotes: 5
Views: 2055
Reputation: 285200
As mentioned by the others (NS)IndexPath
is not property list compliant.
A solution is to use this simple extension of UserDefaults
to save the IndexPath
as an array of two integers
extension UserDefaults {
func indexPath(forKey key : String) -> IndexPath?
{
guard let indexArray = array(forKey: key) as? [Int] else { return nil }
return IndexPath(row: indexArray[0], section: indexArray[1])
}
func set(_ indexPath : IndexPath, forKey key: String)
{
set([indexPath.row, indexPath.section], forKey: key)
}
}
You can find the syntax for an older Swift version in the edit history.
Upvotes: 3
Reputation: 11
This Swift code would work for any depth of IndexPath
extension UserDefaults {
func indexPath(forKey key: String) -> IndexPath? {
if let data = data(forKey: key), let indexPath = try? JSONDecoder().decode(IndexPath.self, from: data) {
return indexPath
}
return nil
}
func set(_ indexPath: IndexPath, forKey key: String) {
if let data = try? JSONEncoder().encode(indexPath) {
set(data, forKey: key)
}
}
}
Upvotes: 1
Reputation: 27448
You can do something like this,
Save like,
var myDefaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
var indexPath: NSIndexPath = self.myTableView.indexPathForSelectedRow
var data: NSData = NSKeyedArchiver.archivedDataWithRootObject(indexPath)
myDefaults["lastSelectedIndex"] = myDefaults
Retrieve like,
var data2: NSData = myDefaults.dataForKey("lastSelectedIndex")
var indexPath2: NSIndexPath = NSKeyedUnarchiver.unarchiveObjectWithData(data2)
You have to convert indexpath to data then you can save and retrieve.
Hope this will help :)
Upvotes: 0
Reputation: 23407
You can't save directly indexPath in NSUserDefault. You can Store NSArray , NSDictionary , NSNumber , NSString and NSDictionary in NSUserDefault.
Store IndexPath using NSKeyedArchiver
:
let data = NSKeyedArchiver.archivedDataWithRootObject(selectedIndexPath)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "indexKey")
Get IndexPath using NSKeyedArchiver
:
let data1 = NSUserDefaults.standardUserDefaults().objectForKey("indexKey") as? NSData
let indexP1 = NSKeyedUnarchiver.unarchiveObjectWithData(data1!) as! NSIndexPath
Upvotes: 13