通知WatchKit应用有更新,而手表应用未请求更新 [英] Notify WatchKit app of an update without the watch app requesting it

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

问题描述

我知道Watch应用程序使用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上运行的UI
    • 作为扩展程序在iPhone上运行的代码.
    • app that runs on iPhone (I will refer to it as iPhone app)
    • app that runs on Watch...specifically
      • UI that runs on Watch
      • code that runs on iPhone as Extension.

      第一行和最后一行对我们来说最重要.是的,Extension是随iPhone应用程序一起提供给AppStore的,但是这两件事可以在iOS操作系统中单独运行.因此,Extension和iPhone应用程序是两个不同的过程-在OS中运行的两个不同程序.

      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],因为当您尝试在iPhone上的NSLog() defaultCenter和Extension中的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发送通知以进行来回监视.我们应该做的第一件事就是注册通知.

      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-callBack方法,当对象收到通知时触发. 基本上与NSNotification中的@selector相同

      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或模型中.

      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?

      您可以类似的方式将通知从手表"发送到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天全站免登陆