【问题标题】:Easy way to update app content via apple watch通过 Apple Watch 更新应用内容的简单方法
【发布时间】:2014-11-20 20:26:31
【问题描述】:

当我按下 AppleWatch 应用程序上的按钮时,我还没有找到一种简单的方法来更新我的 iPhone 应用程序中的视图。

我用 NSUserDefaults Observer 尝试过这样的:

iPhone App Viewcontroller(在 ViewDidLoad() 内):

 // Create and share access to an NSUserDefaults object.
 mySharedDefaults = NSUserDefaults(suiteName: "group.sharedTest")

//Add Observer    
NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "test", options: NSKeyValueObservingOptions.New, context: nil)

在 Watchkit Extensions InterfaceController 中,我使用以下代码添加了一个带有按钮的 IBAction:

mySharedDefaults!.setObject("testValue", forKey: "test")
mySharedDefaults!.synchronize()

但是当我按下按钮时,什么也没有发生! 如果我在我的 iPhone ViewController 中设置一个对象,它可以工作,但如果它是通过应用程序更新的! 有人可以帮我吗?

【问题讨论】:

    标签: ios nsuserdefaults addobserver watchkit


    【解决方案1】:

    您并不幸运,因为当您编写问题时,iOS SDK 中没有用于此的 API。三天前,即 2014 年 12 月 10 日,Apple 发布了 iOS 8.2 beta 2 SDK,其中包含两个对这项任务很重要的方法。

    在 WatchKit 框架中,WKInterfaceController

    // Obj-C
    + (BOOL)openParentApplication:(NSDictionary *)userInfo
                            reply:(void (^)(NSDictionary *replyInfo,
                                            NSError *error))reply
    

    通过调用此方法,iOS 将在后台运行您的应用,应用的 AppDelegate 将收到此消息

    - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply. 
    

    这是在 UIKit 框架 UIApplicationDelegate 类的 iOS SDK Beta 2(就这个问题而言)中添加的第二种方法。

    您可以使用 NSDictionary 和回复块来沟通 Watch 应用和 iOS 应用。

    示例

    在您的 WKInterfaceController 子类中

    - (IBAction)callPhoneAppButtonTapped
    {
        NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"text to display", @"key", nil];
    
        [InterfaceController openParentApplication:dictionary reply:^(NSDictionary *replyInfo, NSError *error) {
            NSLog(@"Reply received by Watch app: %@", replyInfo);
        }];
    }
    

    然后在你的 iOS AppDelegate 类中

    - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *))reply
    {
        NSLog(@"Request received by iOS app");
        NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"your value to return to Apple Watch", @"key", nil];
    
        reply(dictionary);
    }
    

    当您点击 Apple Watch 模拟器上的按钮时,您的 iOS 应用程序将在 iOS 模拟器中启动,您应该能够在适当的位置看到 NSLog。

    注意

    此解决方案适用于在 Watch 和 iOS 应用之间传输对象。 但如果您打算传输更多数据、访问图像、文件等,您应该使用Shared app group。您在 Xcode 项目文件的 Capabilities 中设置共享应用程序组。 使用containerURLForSecurityApplicationGroupIdentifierNSFileManager 类)获取共享组中文件的 URL。

    如果您想从NSUserDefaults 共享首选项initWithSuiteName 就是您要找的。​​p>

    【讨论】:

    • 非常感谢您提供非常有趣的更新信息!!我会尽快试试这个!不幸的是,我还没有足够的声誉来支持您的答案!对不起!
    • 我还没来得及测试呢!我一有时间就会告诉你;)
    • 这可行,但唯一的问题是我无法从 iPhone 应用程序中看到 NSLog(iPhone 应用程序正在做它被要求做的事情,只是我看不到它的日志)。
    • @SumitNathany 不幸的是,我在 NSLog 上遇到了同样的问题,看起来像 Xcode 问题。
    • 只有当您在调试部分将 iOS 应用程序附加为进程时,NSLog 才会出现。通常,我会看到扩展中的所有 NSLog,但将 Iphone 应用程序附加为进程,Xcode 会显示调试日志。
    【解决方案2】:

    我猜 WatchKit 扩展应用程序和您的 iPhone 应用程序是独立运行的应用程序实例,而通知是针对同一实例的。

    作为替代方案,也许您可​​以在 iPhone 应用程序的单独线程中进行新操作,定期检查特定键的更改,并在检测到更改时自行生成通知。

    【讨论】:

    • 我认为您不需要进行手术。为什么不从扩展应用发布本地通知。 iPhone 应用程序可以接收通知并让您继续工作。请记住在收到通知后从 NotificationCenter 中删除通知,否则用户可能会在 NotificationCenter 中看到它。
    • 如果 iPhone 应用程序和扩展程序之间的通知有效,那么这会更容易。我曾想过,因为共享默认通知不能跨应用程序工作,所以通知通常不会。但如果他们这样做了,你的建议肯定会更容易。
    • @sahara108 这不起作用,因为扩展和宿主应用程序是两个不同的进程,因此它们具有不同的内存池,因此它们的 NSNotificationCenter defaultCenter 是不同的。
    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 2016-11-23
    • 2015-03-03
    • 2013-06-05
    • 1970-01-01
    相关资源
    最近更新 更多