Cannot retrieve data from NSUserDefaults into toda

2019-05-14 20:43发布

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!

4条回答
做自己的国王
2楼-- · 2019-05-14 21:02

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 serializing
  • NSKeyedUnarchiver.setClass(Task.self, forClassName: "Task") before deserializing

wherever needed.

Looks like iOS extensions prefix the class name with the extension's name.

查看更多
beautiful°
3楼-- · 2019-05-14 21:08

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 just NSDate() 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 in NSUserDefaults works without problems.

Hope all of this nonsense can help someone else out there!

查看更多
疯言疯语
4楼-- · 2019-05-14 21:09

Set Object

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("iOS", forKey: "userNameKey")

defaults.setInteger(25, forKey: "Age")
defaults.setBool(true, forKey: "UseTouchID")
defaults.setDouble(M_PI, forKey: "Pi")

Reading

let defaults = NSUserDefaults.standardUserDefaults()
let name = defaults.stringForKey("userNameKey")
查看更多
beautiful°
5楼-- · 2019-05-14 21:14
let default = NSUserDefault()
default.objectForKey("key")
查看更多
登录 后发表回答