正常的跳轉(zhuǎn)邏輯是,先添加 URL Schemes,即在主 app 的 info.plist 文件中添加:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>FLKeyboard</string>
</array>
</dict>
</array>
然后,在擴(kuò)展中可以調(diào)用[self.extensionContext openURL: completionHandler:],在主 app 的AppDelegate中實現(xiàn)- application: openURL: options:方法來接收。但實際發(fā)現(xiàn)在鍵盤擴(kuò)展中,此方法無效。蘋果官方 API 明確說明了,只有Today Extension才能跳轉(zhuǎn)主 app,其他均無法跳轉(zhuǎn)。
自定義鍵盤擴(kuò)展中無法使用
[[UIApplication sharedApplication] openURL: options: completionHandler:],使用
[self.extensionContext openURL: completionHandler:]時也無法跳轉(zhuǎn)。
解決方案如下(不知道是否能上架 App Store):
UIResponder* responder = self;
while ((responder = [responder nextResponder]) != nil)
{
if([responder respondsToSelector:@selector(openURL:)] == YES)
{
// 定義參數(shù)
//NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.apple.com/app/id1500423385"];
NSURL *url = [NSURL URLWithString:@"FLKeyboard://"];
NSDictionary *options = @{UIApplicationOpenURLOptionUniversalLinksOnly : @NO};
void (^completionHandler)(BOOL) = ^(BOOL success) {
NSLog(@"Open %@", success ? @"成功" : @"失敗");
};
// 獲取方法簽名(注意方法名包含冒號)
SEL selector = @selector(openURL:options:completionHandler:);
NSMethodSignature *signature = [responder methodSignatureForSelector:selector];
// 創(chuàng)建 NSInvocation 并配置
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:responder];
[invocation setSelector:selector];
// 設(shè)置參數(shù)(索引從2開始)
[invocation setArgument:&url atIndex:2];
[invocation setArgument:&options atIndex:3];
// Block 需要拷貝到堆并傳遞指針
void (^blockCopy)(BOOL) = [completionHandler copy];
[invocation setArgument:&blockCopy atIndex:4];
// 調(diào)用方法
[invocation invoke];
// 獲取返回值
BOOL returnValue = NO;
if (signature.methodReturnLength > 0) {
[invocation getReturnValue:&returnValue];
}
}
}