iOS 自定义键盘如何跳转主 app?

正常的跳转逻辑是,先添加 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];
            }
        }
    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容