本文介绍了从 Swift 中的“共享扩展"内部访问“UIApplication"的“共享"变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从扩展程序内部执行我的主机应用程序.在 Objective-C 中,我使用了这个:

I need to execute my host app from inside an extension. In Objective-C I've used this:

// Get "UIApplication" class name through ASCII Character codes.
NSString *className = [[NSString alloc] initWithData:[NSData dataWithBytes:(unsigned char []){0x55, 0x49, 0x41, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E} length:13] encoding:NSASCIIStringEncoding];
if (NSClassFromString(className))
{
    //  A different way to call [UIApplication sharedApplication]
    id object = [NSClassFromString(className) performSelector: @selector(sharedApplication)];
    //  These lines invoke selector with 3 arguements
    SEL selector = @selector(openURL:options:completionHandler:);
    id  (*method)(id, SEL, id, id, id) = (void *)[object methodForSelector: selector];
    method(object, selector, myURL, nil, nil);
    //  Close extension
    [self.extensionContext completeRequestReturningItems: @[] completionHandler: nil];
}

但是在 Swift 中我有几个问题:

But in Swift I have a couple of issues:

1) UIApplication 不再有 sharedApplication 方法.相反,它有一个类属性 shared.所以我无法执行选择器来获取共享实例.我试图通过编写扩展来绕过这个

1) UIApplication does not have sharedApplication method anymore. Instead it has a class property shared. So I can not perform a selector to get shared instance. I've tried to bypass this by writing an extension

extension UIApplication
{
    class func shared() -> UIApplication
    {
        return UIApplication.shared
    }
}

但我收到一个错误 Function 生成预期类型 'UIApplication';你的意思是用'()'来调用它吗?.添加这些大括号会给我一个无限循环.

but I get an error Function produces expected type 'UIApplication'; did you mean to call it with '()'?. Adding these braces will give me an infinite loop.

2) 即使我以某种方式获得了实例,我也无法理解如何调用 open 方法.

2) Even if I get the instance somehow, I can't understand how to invoke open method.

let selector = NSSelectorFromString("open(_:options:completionHandler:)")
let method = object?.method(for: selector)
method(destinationURL, [String: Any](), nil)

最后一行给了我Cannot call value of non-function type 'IMP'.按苹果文档中的类型时,没有任何反应.我找不到 IMP 的描述以及如何使用它.

The last line gives me Cannot call value of non-function type 'IMP'. When pressing on the type in apple's documents, nothing happens. I can't find a description of IMP and how to work with it.

您可能会说:只需在您的扩展设置中将 Require only app-extension-safe api 设置为 NO 并调用 UIApplication.shared一般".我会回复说我的构建被 iTunes Connect 拒绝了操作系统为英文).

You might say: "just set Require only app-extension-safe api to NO in your extension's settings and call UIApplication.shared normally". To which I would reply that my builds get rejected by iTunes Connect with a message Compliance with export requirements is required or something along those lines (iTunes Connect is in Russian when my entire OS is in English).

所以这里是问题:

1) 有没有办法在 Swift 中使用 ASCII 代码获取 UIApplication.shared?

1) Is there a way to get UIApplication.shared using ASCII codes in Swift?

顺便说一句,我得到了这样的班级名称

BTW I get class name like so

let codes = [CUnsignedChar](arrayLiteral: 0x55, 0x49, 0x41, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E)
let className = String(data: Data(bytes: UnsafeRawPointer(codes), count: 13), encoding: String.Encoding.ascii) ?? ""

2) 如何调用类型为 IMP 的方法?

2) How do I invoke a method that has type IMP?

非常感谢.

推荐答案

虽然 .shared 属性在扩展中不直接可用,但您可以通过 #keyPath 访问它:

Although .shared property is not available in extensions directly, you can access it via #keyPath:

let application = UIApplication.value(forKeyPath: #keyPath(UIApplication.shared)) as!UIApplication

这篇关于从 Swift 中的“共享扩展"内部访问“UIApplication"的“共享"变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 13:26