简体   繁体   English

无法将NSUserDefaults中的数据检索到今天的扩展名(Swift)

[英]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. 我有一组数组,它​​们都包含我创建的自定义Task对象的许多实例。 I am saving the arrays to NSUserDefaults as follows: 我将数组保存到NSUserDefaults,如下所示:

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. 上述方法适用于从iPhone本身设置和检索数据。 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: 当尝试从今天的扩展名的.swift文件中检索时,我收到以下错误:

  • Failed to inherit CoreMedia permissions from 52550: (null) 无法从52550继承CoreMedia权限:(null)

  • Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '* -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (MyAppName.Task) for key (NS.objects); 因未捕获的异常'NSInvalidUnarchiveOperationException'而终止应用程序,原因:'* - [NSKeyedUnarchiver decodeObjectForKey:]:无法解码类(MyAppName.Task)的对象(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 我可以成功保存一个Integer并通过今天的扩展名检索,但不能通过objectForKey


I have tried various other saving methods including .plist files, but nothing seems to work. 我尝试了各种其他保存方法,包括.plist文件,但似乎没有任何工作。 The same errors keep occurring. 同样的错误不断发生。 Any input would be greatly appreciated! 任何投入将不胜感激!

another way is to fix the name of the class used for NSCoding. 另一种方法是修复用于NSCoding的类的名称。 You simply have to use: 你只需要使用:

  • NSKeyedArchiver.setClassName("Task", forClass: Task.self before serializing 序列化之前的NSKeyedArchiver.setClassName("Task", forClass: Task.self
  • NSKeyedUnarchiver.setClass(Task.self, forClassName: "Task") before deserializing 反序列化之前的NSKeyedUnarchiver.setClass(Task.self, forClassName: "Task")

wherever needed. 在需要的地方。

Looks like iOS extensions prefix the class name with the extension's name. 看起来iOS扩展名在类名前面加上扩展名。

let default = NSUserDefault()
default.objectForKey("key")

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")

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. 因为[Task]的解码导致了问题,所以我决定继续从一个没有对象的数组中检索数据,而只是NSDate()实例。 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. 我不确定问题是什么或者是什么,但从存储在NSUserDefaults的数组中检索简单数据可以NSUserDefaults工作。

Hope all of this nonsense can help someone else out there! 希望所有这些废话可以帮助其他人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM