正常的跳转逻辑是,先添加 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>
然后,在扩展中可以调用[self.extensionContext openURL: completionHandler:]
,在主 app 的AppDelegate
中实现- application: openURL: options:
方法来接收。但实际发现在键盘扩展中,此方法无效。苹果官方 API 明确说明了,只有Today Extension
才能跳转主 app,其他均无法跳转。
自定义键盘扩展中无法使用
[[UIApplication sharedApplication] openURL: options: completionHandler:]
,使用
[self.extensionContext openURL: completionHandler:]
时也无法跳转。
解决方案如下(不知道是否能上架 App Store):
UIResponder* responder = self;
while ((responder = [responder nextResponder]) != nil)
{
if([responder respondsToSelector:@selector(openURL:)] == YES)
{
// 定义参数
//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];
// 创建 NSInvocation 并配置
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:responder];
[invocation setSelector:selector];
// 设置参数(索引从2开始)
[invocation setArgument:&url atIndex:2];
[invocation setArgument:&options atIndex:3];
// Block 需要拷贝到堆并传递指针
void (^blockCopy)(BOOL) = [completionHandler copy];
[invocation setArgument:&blockCopy atIndex:4];
// 调用方法
[invocation invoke];
// 获取返回值
BOOL returnValue = NO;
if (signature.methodReturnLength > 0) {
[invocation getReturnValue:&returnValue];
}
}
}