正常的跳轉(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
中實(shí)現(xiàn)- application: openURL: options:
方法來(lái)接收。但實(shí)際發(fā)現(xiàn)在鍵盤(pán)擴(kuò)展中,此方法無(wú)效。蘋(píng)果官方 API 明確說(shuō)明了,只有Today Extension
才能跳轉(zhuǎn)主 app,其他均無(wú)法跳轉(zhuǎn)。
自定義鍵盤(pán)擴(kuò)展中無(wú)法使用
[[UIApplication sharedApplication] openURL: options: completionHandler:]
,使用
[self.extensionContext openURL: completionHandler:]
時(shí)也無(wú)法跳轉(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 ? @"成功" : @"失敗");
};
// 獲取方法簽名(注意方法名包含冒號(hào))
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開(kāi)始)
[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];
}
}
}