如何从你的一个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"]) {
}
网友评论