美文网首页
IOS如何在Host App 与 App Extension 之

IOS如何在Host App 与 App Extension 之

作者: 倒着游的鱼 | 来源:发表于2023-02-20 09:46 被阅读0次

    如何从你的一个App发送通知给另一个App? (例:搜狗输入法下载皮肤完成后使用皮肤) 注:搜狗输入法是App、而键盘是Extension
    当你为你的App 添加 App Extension时,如果想在App 发送通知给 Extension或许这篇文章可以帮助你。https://www.jianshu.com/p/cd4e87b545c7

    //  Extension内 发送通知
    - (void)postNotificaiton {
         CFNotificationCenterRef notification = CFNotificationCenterGetDarwinNotifyCenter ();
        CFNotificationCenterPostNotification(notification, CFSTR("<notificaiton name>"),  NULL,NULL, YES);
    } 
    
    // Host App接收通知
    - (void)receiveNotification {
          CFNotificationCenterRef notification = CFNotificationCenterGetDarwinNotifyCenter (); 
          CFNotificationCenterAddObserver(notification, (__bridge const void *)(self), 
          observerMethod,CFSTR("<notificaiton name>"), NULL, 
          CFNotificationSuspensionBehaviorDeliverImmediately); 
    }
    
    其中NotificationCallback为接到通知后使用此方法取值  <observerMethod>
    void observerMethod (CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { 
    
        NSString *identifier = (__bridge NSString *)name;
        NSObject *sender = (__bridge NSObject *)observer;
        //NSDictionary *info = (__bridge NSDictionary *)userInfo;
    //    NSDictionary *info = CFBridgingRelease(userInfo);
        NSDictionary *notiUserInfo = @{@"identifier":identifier};
        [[NSNotificationCenter defaultCenter] postNotificationName:NotificationName
                                                            object:sender
                                                          userInfo:notiUserInfo];
    } 
    // Host App 移除通知
    - (void)removeNotification {
           CFNotificationCenterRef notification = CFNotificationCenterGetDarwinNotifyCenter ();
           CFNotificationCenterRemoveObserver(notification, (__bridge const void *)(self), CFSTR("<notificaiton name>"), NULL);
    }
    

    以上内容给大家简单介绍了IOS如何在Host App 与 App Extension 之间发送通知的相关内容,(CFNotification不支持传输数据流)希望对大家有所帮助!

    后续:以上方式虽然实现了数据通过Group 的方式在Extension和容器App间进行共享与打开宿主APP,然后,Extension在其生命周期内和宿主App进行交互的时候,容器App很可能并没有启动, 我们需要唤醒容器App并且进行进程间的通信,此时还是需要通过 调起APP传参:开发常使用 [UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"observerMethod://"]

    从iOS 14.5或14.6开始,在共享扩展中访问UIApplication.shared.open或UIApplication.shared.openURL会产生"APPLICATION_EXTENSION_API_ONLY“

    在iOS 14.5或14.6之前,我们可以通过将Require Only App-Extension-Safe API设置为NO并使用:

    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"XyKeyboardApp://"]]) {
                                
                                NSDictionary *options = @{UIApplicationOpenURLOptionUniversalLinksOnly:@NO};
                                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"XyKeyboardApp://openSetting"] options:options completionHandler:nil];
                            }
    

    但是从iOS 14.5或14.6开始,我们在构建时会遇到这样的错误:
    Application extensions and any libraries they link to must be built with the ‘APPLICATION_EXTENSION_API_ONLY’ build setting set to YES.

    ##解决办法从iOS 14.5/14.6中的Keyboard扩展启动主应用程序:
    解决方案,可以让你在启动主应用的同时保持Require Only App-Extension-Safe API为YES。
    
    按照苹果的要求,将Require Only App-Extension-Safe API设置为YES。
    
    然后在扩展中使用以下代码:
    
    class GlobalHelper: NSObject {
        
        
      //按照苹果的要求,将Require Only App-Extension-Safe API设置为YES。
      //依然在扩展中使用以下代码
      @objc class func openSharedApplicationWithApp(identifier: String) -> Void {
            
          let sharedSelector = NSSelectorFromString("sharedApplication")
          let openSelector = NSSelectorFromString("openURL:")
    
          if let urlToOpen = URL(string: identifier as String), UIApplication.responds(to: sharedSelector),
                let shared = UIApplication.perform(sharedSelector)?.takeRetainedValue() as? UIApplication, shared.responds(to: openSelector) {
    
              shared.perform(openSelector, with: urlToOpen)
    
          }
          //do the rest of extension completion stuff....
         // self.extensionContext?.completeRequest(returningItems: [], completionHandler:nil)
            
        }
    
    }
    
    

    iOS两个独立的App之间的跳转实现:

    URL
    一个完整的URL组成包括:协议类型、服务地址、资源路径、请求参数,如果不是通过第三方平台的SDK来进行应用间的跳转,就需要开发者自己在链接中拼接对应需要传递的参数。一个NSURL封装的一个完整地址包括:协议、域名、路径、参数。

    跳转原理
    UIApplication类有一个方法:
    ————————————————

    - (void)openURL:(NSURL*)url options:(NSDictionary<NSString *, id> *)options completionHandler:(void (^ __nullable)(BOOL success))completion NS_AVAILABLE_IOS(10_0) NS_EXTENSION_UNAVAILABLE_IOS("")
    被跳转app实现具体逻辑:
    
     // 通过url的host判断需要跳转的页面进行处理
        if ([url.host isEqualToString:@"one"]) {
     
        }
        if ([url.host isEqualToString:@"two"]) {
     
        }
    
    

    相关文章

      网友评论

          本文标题:IOS如何在Host App 与 App Extension 之

          本文链接:https://www.haomeiwen.com/subject/ctzwkdtx.html