Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot retrieve data from NSUserDefaults into today extension (Swift)

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!

like image 316
Matt Butler Avatar asked Mar 14 '23 06:03

Matt Butler


2 Answers

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.

like image 129
teriiehina Avatar answered Apr 24 '23 23:04

teriiehina


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")
like image 29
Waruna Avatar answered Apr 24 '23 23:04

Waruna