在 watchOS 2 中读取 NSUserDefaults(我知道 App Groups 不起作用)

Posted

技术标签:

【中文标题】在 watchOS 2 中读取 NSUserDefaults(我知道 App Groups 不起作用)【英文标题】:Reading NSUserDefaults in watchOS 2 (I know App Groups doesn't work) 【发布时间】:2016-03-17 01:30:00 【问题描述】:

Apple 文档说“此外,iOS 会自动将您的 iOS 应用首选项的只读副本转发到 Apple Watch。您的 WatchKit 扩展可以使用 NSUserDefaults 对象读取这些首选项...”。 https://developer.apple.com/library/prerelease/watchos/documentation/General/Conceptual/WatchKitProgrammingGuide/SharingData.html#//apple_ref/doc/uid/TP40014969-CH29-SW1

但我无法读取我的 WatchKit 应用中保存在 iPhone 应用中的默认值,我是不是做错了什么?

在 WatchKit 应用程序中,我什至可以保存到(仅限 WatchKit)默认值,还是根本不起作用?

iPhoneData:

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(dataArray, forKey: "DataSaved"

观看ExtensionDelegate

let defaults = NSUserDefaults.standardUserDefaults()
print(defaults.arrayForKey("DataSaved"))
print(defaults.objectForKey("DataSaved"))

arrayForKeyobjectForKey 用于打印 nil

我一定是做错了什么,你知道会是什么吗?

【问题讨论】:

【参考方案1】:

NSUserDefaults之间的区别

NSUserDefaults是任何设备上的一个内存单位,所以在ios和watchOS,tvOS等中完全不同。

例如,如果您在 iOS 上运行一个代码,将一个名为“key1”的新密钥添加到 NSUserDefaults(假设您使用的是 NSUserDefaults.standardUserDefaults()),当您请求在 watchOS 上读取其数据时,它会给您一个空字典。

这是因为这是第一次,您将字典仅存储在 iOS App Target 中,而不是存储在两个设备之间的共享空间中。当 WatchKit 扩展想要使用NSUserDefaults 时,它会读取保存在 WatchKit Target 中的(空)字典,而不是读取 iOS Target 中的(填充)字典。

共享数据

在 watchOS 和 iOS 之间有一些共享字典的方法:

1- 在 watchOS 2 中使用WatchConnectivity 框架,您可以在两个目标之间传递数据。您可以使用sendMessageWCSession 类中的类似函数来执行此操作。只是不要忘记将WCSessionDelegate 添加到您的InterfaceController(在watchOS 中)或ViewController(在iOS 中)类和应用委托中,以便应用能够从WatchConnectivity 接收数据。

2- 使用在线/云存储,您可以将字典从 iOS App 上传到那里,然后将其下载到 watchOS App。但是,这需要 Internet 连接,并且在很多情况下并不适合,例如如果您的应用不需要连接到 Internet 来执行其他任务,而您强制用户连接到 Internet 只是为了同步一个两个目标之间的简单字典。

3- 使用应用程序组(如果您使用的是 watchOS 1),我不再赘述,因为它已经过时了,您可能不想为 watchOS 1 制作应用程序。

结论

1- NSUserDefaults 在 watchOS 和 iOS 中分别返回两个不同的字典。

2- 要在 watchOS 和 iOS 之间共享数据,您可以使用WatchConnectivity、互联网(不推荐)和应用组(在 watchOS 1 中)。

更多资源

有关WatchConnectivity(您问题的现代答案)的更多详细信息,您应该查看Apple Developer Portal 中的Apple 文档。

您还应该看到 this WWDC session 谈论 watchOS 2 中包含的这个伟大的框架。

【讨论】:

"NSUserDefaults 在 watchOS 和 iOS 中分别返回两个不同的字典。"是我需要的部分谢谢 不客气。很高兴能解决您的问题。 这个答案是缺乏信息。在apple docs:Additionally, iOS automatically forwards a read-only copy of your iOS app’s preferences to Apple Watch. Your WatchKit extension can read those preferences using an NSUserDefaults object, but it cannot make changes directly to the defaults database @transang,你真的见过这种行为吗?我也看到了该文档,但从我使用 watchOS 的经验来看,我看不到任何证据。【参考方案2】:

对不起。您无法在 WatchKit 应用程序中读取任何默认值,因为从 watchOS2 开始,它有自己的内存可供使用。所以你不能在 watchOS 中访问 iOS 的 NSUserDefaults 的值

您必须使用 WatchConnectivity 来共享手表 OS2 的数据。

【讨论】:

我认为您引用了手表操作系统的预发布版本,因此现在可能不准确。 @NicolasS 啊,我明白了。你知道是否有更新的文档,因为我没有看到任何关于 NSUserDefaults 的信息,从那以后我可以找到。谢谢!【参考方案3】:

需要明确的是,NSUserDefaults.standardUserDefaults() 在手表和手机上拨打电话时会给你两个不同的字典。

对于 WatchConnectivity,请查看https://developer.apple.com/videos/play/wwdc2015/713/

苹果文档:

https://developer.apple.com/library/watchos/documentation/WatchConnectivity/Reference/WatchConnectivity_framework/index.html

【讨论】:

哦,哇,我不知道。你有没有引用它的 Apple Doc,或者其他引用它的东西,所以我可以开始思考它是如何工作的? 我在那里没有看到任何关于 NSUserDefaults 的信息? WatchConnectivity 不会让您访问 NSUserDefaults。但是,在您的手机应用程序中,您可以使用 WatchConnectivity 将默认设置的副本发送到您的手表应用程序。手表应用程序可以使用接收到的对象,如果需要进行更改,请将更改发送回手机应用程序。然后手机应用程序可以将这些更改写入它的 NSUserDefaults。 @JoshBuhler 我遇到的问题是我将在 iPhone 上保存并反对 NSUserDefaults,然后无法在 Watch 上读取该对象。当我尝试过时,我无法做到“手表应用程序可以使用接收到的对象”,但能够做到这一点是我希望做的 @victorpulak 您是否尝试过使用 WCSession 和 sendMessage:replyHandler:errorHandler 消息将数据从手机发送到手表?当你这样做时会发生什么?【参考方案4】:

Ns defaults.standard 特定于该目标,通过使用它,您可以访问该目标中的数据,在您的情况下,您需要访问另一个目标中的数据,所以听您需要做两件事 1.使用应用组 2.不要使用用户默认值。标准使用UserDefaults(suiteName:"group.yourgroup") 存储和访问数据 参考this链接可能有用。

【讨论】:

以上是关于在 watchOS 2 中读取 NSUserDefaults(我知道 App Groups 不起作用)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 WatchOS 上通过 HealthKit 访问锻炼?

WatchOS 2.0:WCSessionDelegate 没有被调用(在模拟器中)

NSUbiquitousKeyValueStore 不可用 - watchOS 2

WatchOS 2.2 的 NSURLSession 非常慢

如何从 watchOS 2 唤醒 iPhone 应用程序?

如何在 watchOS 2 应用程序 Xcode 7 beta 5 中使用 Parse