问题描述
我需要从扩展程序内部执行我的主机应用程序.在 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"的“共享"变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!