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

Posted

技术标签:

【中文标题】无法从 NSUserDefaults 检索数据到今天的扩展(Swift)【英文标题】:Cannot retrieve data from NSUserDefaults into today extension (Swift) 【发布时间】:2016-02-18 06:08:56 【问题描述】:

我有一组数组,它​​们都包含我创建的自定义任务对象的多个实例。我将数组保存到 NSUserDefaults 如下:

自定义任务对象

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


保存:

let defaults = NSUserDefaults(suiteName: "group.com.myGroupName")

let nowData = NSKeyedArchiver.archivedDataWithRootObject(nowTasks)
defaults!.setObject(nowData, forKey: "nowData")

检索

let nowDataPull = defaults!.objectForKey("nowData") as? NSData
if let nowDataPull2 = nowDataPull
   let nowTasks2 = NSKeyedUnarchiver.unarchiveObjectWithData(nowDataPull2) as? [Task]
   if let nowTasks21 = nowTasks2
      nowTasks = nowTasks21
   

上述方法适用于从 iPhone 本身设置和检索数据。但是,当尝试通过 today 扩展检索数据时,此方法不起作用。

当尝试从今天扩展的 .swift 文件中检索时,我收到以下错误:

无法从 52550 继承 CoreMedia 权限:(null)

由于未捕获的异常“NSInvalidUnarchiveOperationException”而终止应用程序,原因:'* -[NSKeyedUnarchiver decodeObjectForKey:]:无法解码类的对象(MyAppName.Task) 对于键(NS.objects);该类可以在源代码或 未链接的库'


我知道扩展程序可以读取数据,因为当我调用时:

if (defaults?.objectForKey("nowData") != nil)
   print("there is data")

我收到了打印出来的回复..


我可以通过今天的扩展成功保存一个整数并检索,但不是objectForKey


我尝试了各种其他保存方法,包括 .plist 文件,但似乎没有任何效果。同样的错误不断发生。任何投入将不胜感激!

【问题讨论】:

我注意到错误指向MyAppName.Task。在 Today Extension 中编译时,Task 类可能属于不同的模块? @MikePollard 我有一个名为“sharedCode.swift”的文件中的整个任务类声明。此文件已通过 Target Membership 对主应用程序和今天的扩展程序进行“检查”.. 【参考方案1】:

另一种方法是固定用于 NSCoding 的类的名称。您只需使用:

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

任何需要的地方。

看起来 ios 扩展在类名前加上扩展名。

【讨论】:

这是 iOS 扩展最通用的解决方案(应该是公认的答案)。【参考方案2】:

设置对象

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

阅读

let defaults = NSUserDefaults.standardUserDefaults()
let name = defaults.stringForKey("userNameKey")

【讨论】:

我认为standardUserDefaults() 不适用于在应用程序和扩展程序之间共享数据,不是吗?我很确定您必须声明组名..【参考方案3】:

解决方法:

所以我找到了解决我的问题的解决方法(实际上更有效)。因为[Task] 的解码引起了问题,所以我决定继续从其中没有对象的数组中检索数据,而只是NSDate() 实例。因此,我现在可以保存和访问今天扩展所需的数据的重要方面。我敦促任何在自定义类解码方面遇到问题的人尽可能尝试简化您的数据,以便在您的扩展程序中检索和使用它。我不确定问题是什么,但从存储在NSUserDefaults 中的数组中检索简单数据没有问题。

希望所有这些废话都可以帮助其他人!

【讨论】:

我也倾向于做同样的事情。在我的情况下,我知道自定义类与 App 和 Today Extension 相关联,但归档和取消归档仅适用于 iPhone 应用程序本身。我不禁觉得必须有更好的方法来解决这个问题! 我遇到了同样的问题。经过几天的尝试,我最终找到了另一个解决方案。您也可以考虑这样做。

以上是关于无法从 NSUserDefaults 检索数据到今天的扩展(Swift)的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C:无法从 NSUserDefaults 设置 NSMutableDictionary

从 NSUserDefaults 检索数据会使应用程序崩溃

从 NSUserDefaults 检索自定义对象

UIImage 没有从 NSUserDefaults 中检索

如何在我的应用加载之前从 NSUserDefaults 检索值...?

如何从命令行获取 NSUserDefaults