Reputation: 2061
I am trying to save data to NSUserDefaults for later use with a Share Extension. However, the data is never saved when I re-open the app. Likewise my extension is not able to retrieve any data
I have a singleton class called AppUser that has a username property. If I set
AppUser.username = "Bob"
and then run saveAppData()
class func saveAppData() {
let data = NSKeyedArchiver.archivedDataWithRootObject(AppUser.singleton)
var sharedDefaults = NSUserDefaults(suiteName: "group.ca.mycompany.myapp")
sharedDefaults!.setObject(data, forKey: "AppUser")
sharedDefaults!.synchronize()
}
Close App & Re-open
class func loadAppData() {
var sharedDefaults = NSUserDefaults(suiteName: "group.ca.mycompany.myapp")
if let data = sharedDefaults!.objectForKey("AppUser") as? NSData {
println("Unarchived file succesfully")
NSKeyedUnarchiver.unarchiveObjectWithData(data) //should throw all the data into the AppUser.singleton class
println("Username is: \(AppUser.singleton.username)")
}
}
When I run loadAppData() after the app has been reopened I get the following lines in the console:
Unarchived file succesfully
Username is nil
Why is the username being returned as nil even though I ran setObject and sychronize?
Note : I have my "suitName" set correctly in my app as "group.ca.mycompany.myapp". I have the appgroups enabled for both my app and my extension as "group.ca.mycompany.myapp".
Upvotes: 1
Views: 323
Reputation: 4646
So, it doesn't look like you are saving the unarchived "data" contents to an object, here's your example with me saving the unacrhived data contents to an array of strings:
let data = NSKeyedArchiver.archivedDataWithRootObject(["asdf", "asdf"])
var sharedDefaults = NSUserDefaults(suiteName: "group.ca.mycompany.myapp")
sharedDefaults!.setObject(data, forKey: "AppUser")
sharedDefaults!.synchronize()
println(sharedDefaults!.valueForKey("AppUser"))
var sharedDefaults1 = NSUserDefaults(suiteName: "group.ca.mycompany.myapp")
if let data = sharedDefaults1!.objectForKey("AppUser") as? NSData {
println("Unarchived file succesfully")
let something = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [String] //should throw all the data into the AppUser.singleton class
println("Username is: \(something)")
}
and this gives the following information:
Optional(<62706c69 73743030 d4010203 0405081a 1b542474 6f705824 6f626a65 63747358 24766572 73696f6e 59246172 63686976 6572d106 0754726f 6f748001 a5090a11 12135524 6e756c6c d20b0c0d 0e562463 6c617373 5a4e532e 6f626a65 63747380 04a20f10 80028003 54617364 66546173 6466d214 15161958 24636c61 73736573 5a24636c 6173736e 616d65a2 1718574e 53417272 6179584e 534f626a 65637457 4e534172 72617912 000186a0 5f100f4e 534b6579 65644172 63686976 65720811 161f2832 353a3c42 484d545f 61646668 6d727780 8b8e969f a7ac0000 00000000 01010000 00000000 001c0000 00000000 00000000 00000000 00be>)
Unarchived file succesfully Username is: Optional(["asdf", "asdf"])
The difference here is that I'm saving the unarchived contents to "something":
let something = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? [String]
And as such, the "something" is like a proxy for your singleton class.
To make this useful to you, here's another implmentation:
let data = NSKeyedArchiver.archivedDataWithRootObject(["asdf", "asdf"])
var sharedDefaults = NSUserDefaults(suiteName: "group.ca.mycompany.myapp")
sharedDefaults!.setObject(data, forKey: "AppUser")
sharedDefaults!.synchronize()
var sharedDefaults1 = NSUserDefaults(suiteName: "group.ca.mycompany.myapp")
if let data = sharedDefaults1!.objectForKey("AppUser") as? NSData {
println("Unarchived file succesfully")
let something = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! [String] //should throw all the data into the AppUser.singleton class
println(something[0])
}
This new implementation prints out this:
asdf
This means that you can save this unarchived data to an object and then store this object to your AppUser.singleton with ease, as long as you set up the AppUser model class correctly.
Upvotes: 1