WatchKit Extension 看不到保存在 NSUserDefaults 和 App Group 中的数据
WatchKit Extension is not seeing data saved in NSUserDefaults with App Group
我看过很多 SO 帖子,这曾经有效,但现在停止了。我不确定发生了什么。我用 watchOS 1.0 开发了这个 iPhone+WatchKit 应用程序,一切正常。
我已经将我的应用程序、项目和 Apple Watch 升级到 watchOS 2.0,现在我无法使用我的应用程序组通过 NSUserDefaults 获取任何数据。
应用组在主机应用和 WatchKit 扩展中的 Xcode 中启用。我什至还尝试为 WatchKit 应用程序打开它。
我的组名为"group.com.mycompany.myapp"(带有我真实的公司名称和应用程序名称),并且它在所有目标上都被选中。
我已确认我的主机应用程序和 WatchKit 扩展的构建设置引用了权利文件,并且我已检查这些权利文件是否包含我选择的应用程序组的应用程序组安全选项。
我已确保主机应用程序、watchkit 扩展程序和 watchkit 应用程序的包标识符不同。我分别使用"com.mycompany.myapp"、"com.mycompany.myapp.watchkitextension"和"com.mycompany.myapp.watchkitapp"。
以下是我的 Xcode 主机应用、watchkit 扩展和 watchkit 应用配置的一些屏幕截图,以防万一:
这是我的主机应用程序中能够正确读取数据的代码:
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroupName];
NSLog(@"app defaults: %@", [defaults dictionaryRepresentation]);
这在我的控制台中产生了这个,kKeyEmployeeId
和 kKeyStoreNumber
是我试图在主机和手表之间共享的数据。
2015-12-13 13:51:35.618 MyApp[27516:16126253] app defaults: {
AppleLanguages = (
"en-US",
en
);
INNextHearbeatDate = "472211882.83309";
NSInterfaceStyle = macintosh;
NSLanguages = (
"en-US",
en
);
"com.apple.content-rating.AppRating" = 1000;
"com.apple.content-rating.ExplicitBooksAllowed" = 1;
"com.apple.content-rating.ExplicitMusicPodcastsAllowed" = 1;
"com.apple.content-rating.MovieRating" = 1000;
"com.apple.content-rating.TVShowRating" = 1000;
kKeyEmployeeId = Kenny;
kKeyStoreNumber = 001;
}
在我的 WatchKit 扩展中,我有相同的代码,但它没有提供我需要的两个 key:value 对:
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroupName];
NSLog(@"defaults: %@", [defaults dictionaryRepresentation]);
}
它产生这个,这与上面的非常相似,但是没有我真正需要的两个键:
2015-12-13 13:28:29.840 MyApp WatchKit Extension[720:322804] defaults: {
AppleLanguages = (
en
);
INNextHearbeatDate = "472434306.599217";
NSInterfaceStyle = macintosh;
NSLanguages = (
en
);
"com.apple.content-rating.AppRating" = 1000;
"com.apple.content-rating.ExplicitBooksAllowed" = 1;
"com.apple.content-rating.ExplicitMusicPodcastsAllowed" = 1;
"com.apple.content-rating.MovieRating" = 1000;
"com.apple.content-rating.TVShowRating" = 1000;
}
kAppGroupName
和其他常量定义如下:
NSString * const kAppGroupName = @"group.com.inadaydevelopment.MyApp";
NSString * const kKeyStoreNumber = @"kKeyStoreNumber";
NSString * const kKeyEmployeeId = @"kKeyEmployeeId";
由于在手表上观看 os 2 个应用程序 运行 而不是 iPhone,我认为您无权访问 NSUserDefaults 或应用程序组。您必须使用 WatchConnectivity 框架与手表传输数据。
在 Watch OS1 中这行得通,但在 Watch OS2 中发生了一些变化。您需要使用一种叫做 WatchConnectivity 的东西将您想要保存的数据发送到手表。然后当手表收到你发给它的数据时,保存到Apple watch默认的NSUserDefaults
。
WCSession.defaultSession()
将 return 用于在您的 iOS 和 Watch 应用程序之间传输数据的 WCSession
单例。
Here 是教程和示例。
您可以按照以下步骤操作
1) 设置会话
if ([WCSession isSupported])
{
[[WCSession defaultSession] setDelegate:self];
[[WCSession defaultSession] activateSession];
}
2) 准备数据字典并使用以下方法发送
[WCSession defaultSession] sendMessage:dataDict replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) {
//You task on completion
} errorHandler:^(NSError * _Nonnull error) {
if (error)
{
//Handle the error
}
}];
3) 在手表应用代码中
您可以设置委托方法
- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler
{
//Handle the response
}
我看过很多 SO 帖子,这曾经有效,但现在停止了。我不确定发生了什么。我用 watchOS 1.0 开发了这个 iPhone+WatchKit 应用程序,一切正常。
我已经将我的应用程序、项目和 Apple Watch 升级到 watchOS 2.0,现在我无法使用我的应用程序组通过 NSUserDefaults 获取任何数据。
应用组在主机应用和 WatchKit 扩展中的 Xcode 中启用。我什至还尝试为 WatchKit 应用程序打开它。
我的组名为"group.com.mycompany.myapp"(带有我真实的公司名称和应用程序名称),并且它在所有目标上都被选中。
我已确认我的主机应用程序和 WatchKit 扩展的构建设置引用了权利文件,并且我已检查这些权利文件是否包含我选择的应用程序组的应用程序组安全选项。
我已确保主机应用程序、watchkit 扩展程序和 watchkit 应用程序的包标识符不同。我分别使用"com.mycompany.myapp"、"com.mycompany.myapp.watchkitextension"和"com.mycompany.myapp.watchkitapp"。
以下是我的 Xcode 主机应用、watchkit 扩展和 watchkit 应用配置的一些屏幕截图,以防万一:
这是我的主机应用程序中能够正确读取数据的代码:
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroupName];
NSLog(@"app defaults: %@", [defaults dictionaryRepresentation]);
这在我的控制台中产生了这个,kKeyEmployeeId
和 kKeyStoreNumber
是我试图在主机和手表之间共享的数据。
2015-12-13 13:51:35.618 MyApp[27516:16126253] app defaults: {
AppleLanguages = (
"en-US",
en
);
INNextHearbeatDate = "472211882.83309";
NSInterfaceStyle = macintosh;
NSLanguages = (
"en-US",
en
);
"com.apple.content-rating.AppRating" = 1000;
"com.apple.content-rating.ExplicitBooksAllowed" = 1;
"com.apple.content-rating.ExplicitMusicPodcastsAllowed" = 1;
"com.apple.content-rating.MovieRating" = 1000;
"com.apple.content-rating.TVShowRating" = 1000;
kKeyEmployeeId = Kenny;
kKeyStoreNumber = 001;
}
在我的 WatchKit 扩展中,我有相同的代码,但它没有提供我需要的两个 key:value 对:
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroupName];
NSLog(@"defaults: %@", [defaults dictionaryRepresentation]);
}
它产生这个,这与上面的非常相似,但是没有我真正需要的两个键:
2015-12-13 13:28:29.840 MyApp WatchKit Extension[720:322804] defaults: {
AppleLanguages = (
en
);
INNextHearbeatDate = "472434306.599217";
NSInterfaceStyle = macintosh;
NSLanguages = (
en
);
"com.apple.content-rating.AppRating" = 1000;
"com.apple.content-rating.ExplicitBooksAllowed" = 1;
"com.apple.content-rating.ExplicitMusicPodcastsAllowed" = 1;
"com.apple.content-rating.MovieRating" = 1000;
"com.apple.content-rating.TVShowRating" = 1000;
}
kAppGroupName
和其他常量定义如下:
NSString * const kAppGroupName = @"group.com.inadaydevelopment.MyApp";
NSString * const kKeyStoreNumber = @"kKeyStoreNumber";
NSString * const kKeyEmployeeId = @"kKeyEmployeeId";
由于在手表上观看 os 2 个应用程序 运行 而不是 iPhone,我认为您无权访问 NSUserDefaults 或应用程序组。您必须使用 WatchConnectivity 框架与手表传输数据。
在 Watch OS1 中这行得通,但在 Watch OS2 中发生了一些变化。您需要使用一种叫做 WatchConnectivity 的东西将您想要保存的数据发送到手表。然后当手表收到你发给它的数据时,保存到Apple watch默认的NSUserDefaults
。
WCSession.defaultSession()
将 return 用于在您的 iOS 和 Watch 应用程序之间传输数据的 WCSession
单例。
Here 是教程和示例。
您可以按照以下步骤操作
1) 设置会话
if ([WCSession isSupported])
{
[[WCSession defaultSession] setDelegate:self];
[[WCSession defaultSession] activateSession];
}
2) 准备数据字典并使用以下方法发送
[WCSession defaultSession] sendMessage:dataDict replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) {
//You task on completion
} errorHandler:^(NSError * _Nonnull error) {
if (error)
{
//Handle the error
}
}];
3) 在手表应用代码中 您可以设置委托方法
- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler
{
//Handle the response
}