I have a group of arrays that all contain a number of instances of a custom Task object that I have created. I am saving the arrays to NSUserDefaults as follows:
Custom Task Object
class Task:NSObject, NSCoding {
var name:String
var notes:String
var date:NSDate
var dateUse:Bool
var taskCompleted:Bool
init(name:String, notes:String, date:NSDate, dateUse:Bool, taskCompleted:Bool){
self.name = name
self.notes = notes
self.date = date
self.dateUse = dateUse
self.taskCompleted = taskCompleted
}
required init(coder decoder: NSCoder){
self.name = decoder.decodeObjectForKey("name") as! String
self.notes = decoder.decodeObjectForKey("notes") as! String
self.date = decoder.decodeObjectForKey("date") as! NSDate
self.dateUse = decoder.decodeObjectForKey("dateUse") as! Bool
self.taskCompleted = decoder.decodeObjectForKey("taskCompleted") as! Bool
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.name, forKey: "name")
coder.encodeObject(self.notes, forKey: "notes")
coder.encodeObject(self.date, forKey: "date")
coder.encodeObject(self.dateUse, forKey: "dateUse")
coder.encodeObject(self.taskCompleted, forKey: "taskCompleted")
}
}
Saving:
let defaults = NSUserDefaults(suiteName: "group.com.myGroupName")
let nowData = NSKeyedArchiver.archivedDataWithRootObject(nowTasks)
defaults!.setObject(nowData, forKey: "nowData")
Retrieving
let nowDataPull = defaults!.objectForKey("nowData") as? NSData
if let nowDataPull2 = nowDataPull{
let nowTasks2 = NSKeyedUnarchiver.unarchiveObjectWithData(nowDataPull2) as? [Task]
if let nowTasks21 = nowTasks2{
nowTasks = nowTasks21
}
}
The above method works fine for setting and retrieving data from the iPhone itself. However, this method does not work when trying to retrieve the data via the today extension.
When trying to retrieve from the today extension's .swift file I get the following errors:
Failed to inherit CoreMedia permissions from 52550: (null)
Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '* -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (MyAppName.Task) for key (NS.objects); the class may be defined in source code or a library that is not linked'
I know that the extension can read the data because when I call:
if (defaults?.objectForKey("nowData") != nil){
print("there is data")
}
I get the printed response..
I can successfully save an Integer and retrieve via the today extension, but not objectForKey
I have tried various other saving methods including .plist files, but nothing seems to work. The same errors keep occurring. Any input would be greatly appreciated!
another way is to fix the name of the class used for NSCoding. You simply have to use:
NSKeyedArchiver.setClassName("Task", forClass: Task.self
before serializingNSKeyedUnarchiver.setClass(Task.self, forClassName: "Task")
before deserializingwherever needed.
Looks like iOS extensions prefix the class name with the extension's name.
Workaround:
So I have found a workaround (which is actually more efficient) for my problem. Because the decoding of
[Task]
was causing problems, I decided to go ahead and retrieve the data from an array that did not have objects inside of it, but rather justNSDate()
instances. Because of this I can now save and access the important aspects of data that the today extension needs. I urge anyone else who is having issues with custom class decoding to try and simplify your data if at all possible in order to retrieve and use it in your extension. I am not exactly sure what the problem was or is, but retrieving simple data from an array stored inNSUserDefaults
works without problems.Hope all of this nonsense can help someone else out there!
Set Object
Reading