通知 WatchKit 应用程序更新,而无需手表应用程序请求它 [英] Notify WatchKit app of an update without the watch app requesting it

查看:20
本文介绍了通知 WatchKit 应用程序更新,而无需手表应用程序请求它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 WKInterfaceController openParentApplicationhandleWatchKitExtensionRequest 方法的功能,用于手表应用程序打开父应用程序和发送/接收数据.

I'm aware of the capabilities of WKInterfaceController openParentApplication and handleWatchKitExtensionRequest methods for the watch app to open the parent app and send/receive data.

但是这怎么样...在用户使用父应用程序并在父应用程序中执行操作(即更改背景颜色)的情况下,我将如何立即通知手表应用程序并执行手表上也有相关操作吗?

But how about this... In the instance where the user is using the parent app and performs an action in the parent app (ie changes the color of the background), how would I notify the watch app immediately and perform the relevant action on the watch also?

我相信 MMWormhole 在这个例子中就足够了,这是我应该采取的最佳方法还是还有其他选择吗?

I believe MMWormhole would suffice in this example, is this is the best approach I should take or is there an alternative?

推荐答案

背景

首先让我们总结一下我们所知道的.我们有

Background

First off all let's sum up what we know. We have

  • 在 iPhone 上运行的应用程序(我将其称为 iPhone 应用程序)
  • 在 Watch 上运行的应用......特别是
    • 在 Watch 上运行的用户界面
    • 作为扩展在 iPhone 上运行的代码.

    第一行和最后一行对我们来说是最重要的.是的,扩展随您的 iPhone 应用程序一起发送到 AppStore,但是这两个东西可以在 iOS 操作系统中单独运行.因此,扩展程序和 iPhone 应用程序是两个不同的进程 - 两个在操作系统中运行的不同程序.

    First and last lines are most important to us. Yes, Extension is shipped to AppStore with your iPhone app, however this two things can run separately in iOS operating system. Hence, Extension and iPhone app are two different processes - two different programs that runs in OS.

    因为这个事实,我们不能使用 [NSNotificationCenter defaultCenter] 因为当你尝试 NSLog() iPhone 上的 defaultCenter 和扩展中的 defaultCenter 时,它们会有不同的内存地址.

    Because of that fact, we can't use [NSNotificationCenter defaultCenter] because when you try to NSLog() defaultCenter on iPhone and defaultCenter in Extension they will have different memory address.

    正如您想象的那样,这种问题对开发人员来说并不陌生,它的专有术语是进程间通信.所以在 OS X 和 iOS 中有...达尔文通知机制.最简单的使用方法是从 CFNotificationCenter 类中实现几个方法.

    As you might imagine, this kind of problem is not new to developers, it's proper term is Interprocess Communication. So in OS X and iOS there is...Darwin Notification mechanism. And the easiest way to use it is to implement few methods from CFNotificationCenter class.

    当使用 CFNotificationCenter 时,您会看到它看起来与 NSNotificationCenter 非常相似.我的猜测是 NSNotif.. 是围绕 CFNotif.. 建立的,但我没有证实这个假设.现在,切入正题.

    When using CFNotificationCenter you will see it looks very similar to NSNotificationCenter. My guess is NSNotif.. was built around CFNotif.. but I did't confirmed that hypothesis. Now, to the point.

    假设您想从 iPhone 向 Watch 来回发送通知.我们应该做的第一件事是注册通知.

    So lets assume you want to send notification from iPhone to Watch back and forth. First thing we should do is to register to notifications.

    - (void)registerToNotification
    {    
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceivedNSNotification) name:@"com.example.MyAwesomeApp" object:nil];
    
        CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)(self), didReceivedDarwinNotification, CFSTR("NOTIFICATION_TO_WATCH"), NULL, CFNotificationSuspensionBehaviorDrop);
    }
    

    你可能想知道为什么我为 NSNotificationCenter 添加了观察者?为了完成我们的任务,我们需要创建一些循环,稍后您就会看到.

    You probably wondering why I added observer for NSNotificationCenter? In order to accomplish our task we need to create some loop, you will see it in a moment.

    至于第二种方法.

    CFNotificationCenterGetDarwinNotifyCenter() - 获取达尔文通知中心

    CFNotificationCenterGetDarwinNotifyCenter() - get Darwin Notify Centre

    (__bridge const void *)(self) - 通知观察者

    didReceivedDarwinNotification - 回调方法,当对象收到通知时触发.基本上和 NSNotification

    didReceivedDarwinNotification - callBack method, fired when object receives notification. Basically it's the same as @selector in NSNotification

    CFSTR("NOTIFICATION_TO_WATCH") - 通知的名称,与 NSNotification 中的故事相同,但这里我们需要 CFSTR 方法将字符串转换为 CFStringRef

    CFSTR("NOTIFICATION_TO_WATCH") - name of the notification, same story in NSNotification, but here we need CFSTR method to convert string into CFStringRef

    最后两个参数 objectsuspensionBehaviour - 当我们使用 DarwinNotifyCenter 时,这两个参数都被忽略了.

    And finally last two parameters object and suspensionBehaviour - both ignored when we are using DarwinNotifyCenter.

    很酷,所以我们注册为观察员.所以让我们实现我们的回调方法(有两个,一个用于 CFNotificationCenter,一个用于 NSNotificationCenter).

    Cool, so we registered as an observer. So lets implement our callback methods (there are two of them, one for CFNotificationCenter, and one for NSNotificationCenter).

    void didReceivedDarwinNotification()
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"com.example.MyAwesomeApp" object:nil];
    }
    

    现在,如您所见,此方法不以 - (void)Name... 开头.为什么?因为它是C方法.你明白为什么我们需要 NSNotificationCenter 吗?从 C 方法中,我们无法访问 self.一种选择是声明指向自己的静态指针,如下所示: static id staticSelf 分配它 staticSelf = self 然后从 didReceivedDarwinNotification 使用它: ((YourClass*)staticSelf)->_yourProperty 但我认为 NSNotificationCenter 是更好的方法.

    Now, as you see, this method doesn't starts with - (void)Name.... Why? Because it's C method. Do you see why we need NSNotificationCenter here? From C method we don't have access to self. One option is to declare static pointer to yourself, like this: static id staticSelf assign it staticSelf = self and then use it from didReceivedDarwinNotification: ((YourClass*)staticSelf)->_yourProperty but I think NSNotificationCenter is better approach.

    然后在响应您的 NSNotification 的选择器中:

    So then in selector that responds to your NSNotification:

    - (void)didReceivedNSNotification
    {
        // you can do what you want, Obj-C method
    }
    

    当我们最终注册为观察者时,我们可以从 iPhone 应用程序发送一些内容.

    When we are, finally, registered as observer we can send something from iPhone app.

    为此,我们只需要一行代码.

    For this we need only one line of code.

    CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), CFSTR("NOTIFICATION_TO_WATCH"), (__bridge const void *)(self), nil, TRUE);
    

    可以在您的 ViewController 或 Model 中.

    which can be in your ViewController, or Model.

    再次,我们要获取CFNotificationCenterGetDarwinNotifyCenter(),然后我们指定通知的名称、发布通知的对象、字典对象(使用 DarwinNotifyCenter 时被忽略,最后一个参数是问题的答案:立即交付?

    Again, we want to get CFNotificationCenterGetDarwinNotifyCenter(), then we specify name for notification, object that is posting notification, dictionary object (ignored when using DarwinNotifyCenter and last parameters is answer to question: deliver immediately?

    以类似的方式,您可以将通知从 Watch 发送到 iPhone.出于显而易见的原因,我建议使用不同的通知名称,例如 CFSTR("NOTIFICATION_TO_IPHONE") 以避免出现例如 iPhone 向 Watch 和自身发送通知的情况.

    In similar fashion you can send notification from Watch to iPhone. From obvious reason I suggest using different notification name, like CFSTR("NOTIFICATION_TO_IPHONE") to avoid situation where, for example, iPhone sends notification to Watch and to itself.

    MMWormhole 非常好,编写得很好,即使测试涵盖了大部分(如果不是全部)代码.它易于使用,只需记住之前设置您的 AppGroups.但是,如果您不想将第三方代码导入到您的项目中,或者由于其他原因不想使用它,则可以使用此答案中提供的实现.特别是如果您不想/不需要在 iPhone 和 Watch 之间交换数据.

    MMWormhole is perfectly fine and well written class, even with tests that covers most, if not all, code. It's easy to use, just remember to setup your AppGroups before. However, if you don't want to import third-party code to your project or you don't want to use it for some other reason, you can use implementation provided in this answer. Especially if you don't want to/need to exchange data between iPhone and Watch.

    还有第二个不错的项目LLBSDMessaging.它基于伯克利套接字.更复杂,基于更底层的代码.这里是冗长但写得很好的博客文章的链接,你会在那里找到 Github 的链接.http://ddeville.me/2015/02/interprocess-communication-on-ios-with-berkeley-sockets/.

    There is also second good project LLBSDMessaging. It's based on Berkeley sockets. More sophisticated and based on more low-level code. Here is link to lengthy but well written blog post, you will find link to Github there. http://ddeville.me/2015/02/interprocess-communication-on-ios-with-berkeley-sockets/.

    希望对您有所帮助.

    这篇关于通知 WatchKit 应用程序更新,而无需手表应用程序请求它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆