如何从自定义键盘扩展启动包含应用程序?

Posted

技术标签:

【中文标题】如何从自定义键盘扩展启动包含应用程序?【英文标题】:How to launch containing app from custom keyboard extension? 【发布时间】:2014-10-08 09:08:28 【问题描述】:

我看到了一些关于这个问题的帖子,但还是不明白。

我为包含应用程序 - KbrdApp 设置了 URLidentifier。如果我的包含应用程序启动它会返回标志“1”,这意味着“准备好”。

这是来自viewDidLoad 调用的自定义键盘扩展的代码:

UIWebView * webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
NSString *customURL = @"KbrdApp://";
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:customURL]];
[webView loadRequest:request];

我读到NSExtensionContext 只适用于今天的扩展,所以我尝试了UIWebView。但它不起作用。

怎么了?

【问题讨论】:

如果您得到答案,请发布您的代码...我遇到了同样的问题...谢谢 【参考方案1】:

问题中提到的方法在 ios 8.0 中停止工作。

目前(iOS 9.2)您可以使用多种方式访问​​共享的UIApplication 实例及其隐藏的openURL 方法。

就个人而言,我更喜欢我开发的这种方法:

// Usage:
// UIApplication.?sharedApplication().?openURL(NSURL(string: "your-app-scheme://")!)

extension UIApplication 

    public static func ?sharedApplication() -> UIApplication 
        guard UIApplication.respondsToSelector("sharedApplication") else 
            fatalError("UIApplication.sharedKeyboardApplication(): `UIApplication` does not respond to selector `sharedApplication`.")
        

        guard let unmanagedSharedApplication = UIApplication.performSelector("sharedApplication") else 
            fatalError("UIApplication.sharedKeyboardApplication(): `UIApplication.sharedApplication()` returned `nil`.")
        

        guard let sharedApplication = unmanagedSharedApplication.takeUnretainedValue() as? UIApplication else 
            fatalError("UIApplication.sharedKeyboardApplication(): `UIApplication.sharedApplication()` returned not `UIApplication` instance.")
        

        return sharedApplication
    

    public func ?openURL(url: NSURL) -> Bool 
        return self.performSelector("openURL:", withObject: url) != nil
    


【讨论】:

? 符号很重要。我的代码根本不调用sharedApplication。刚才的代码引入了函数UIApplication.?sharedApplication().?openURL(url) 就可以了。【参考方案2】:

这是我的 obj c 语言版本。适用于 IOS 11.4.1、XCode 9.4.1

UIApplication 类的类别:

// UIApplication+UpenURL.h file
@interface UIApplication (OpenUrlHelper)

+ (UIApplication *)sharedApp;
- (void)openUrl:(NSURL *)url withOptions:(NSDictionary *)options andComplition:(void(^)(BOOL))complition;

@end

// UIApplication+UpenURL.m file
#import "UIApplication+UpenURL.h"
@implementation UIApplication (OpenUrlHelper)

+ (UIApplication *)sharedApp 
    __weak UIApplication *sharedApp = [UIApplication performSelector:@selector(sharedApplication)];
    return sharedApp;


- (void)openUrl:(NSURL *)url withOptions:(NSDictionary *)options andComplition:(void(^)(BOOL))complition 
    if (@available (iOS 10, *)) 
        [self performSelector:@selector(openURL:options:completionHandler:)
                   withObject:url
                   withObject:options
                   withObject:complition];
     else 
        [self performSelector:@selector(openURL:) withObject:url];
    


- (id)performSelector:(SEL)selector withObject:(id)obj1 withObject:(id)obj2 withObject:(id)obj3 
    NSMethodSignature *signature = [self methodSignatureForSelector:selector];
    if (!signature)
        return nil;

    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setTarget:self];
    [invocation setSelector:selector];
    [invocation setArgument:&obj1 atIndex:2];
    [invocation setArgument:&obj2 atIndex:3];
    [invocation setArgument:&obj3 atIndex:4];
    [invocation invoke];
    if (signature.methodReturnLength) 
        id anObject;
        [invocation getReturnValue:&anObject];
        return anObject;
    
    return nil;


@end

然后在你需要的文件中,你应该

#import "UIApplication+UpenURL.h"

并使用如下代码:

NSURL *url = [NSURL URLWithString:@"yourapp://"];
[[UIApplication sharedApp] openUrl:url withOptions:@ andComplition:nil];

【讨论】:

感谢 Alex,在浪费了我 3 小时的时间后,这对我帮助很大

以上是关于如何从自定义键盘扩展启动包含应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式从自定义 android 键盘更改键盘

包含自定义键盘扩展的应用程序必须具有隐私政策 URL

如何判断 UITabBar 是不是从自定义视图打开?

如何检查我的ios8自定义键盘扩展是否具有开放访问权限?

如何检查我的 ios8 自定义键盘扩展是不是具有开放访问权限?

自定义键盘应用程序扩展 iOS 8 上的 Siri