user2578850
user2578850

Reputation:

Selector for a function with multiple parameters

I need my app extension to open my host app with a parameter. I do so by opening a custom URL with UIApplication.shared.

Now. My last build has been rejected in test flight with a message "Need test for export compliance" or something like that (iTunes connect does not want to run in English). So I think that Require only App-Extension-Safe API set to NO in my extension's Build Settings is a possible reason of the problem.

Setting the flag to YES disables the use of UIApplication.shared. So I've decided to use the old way I found here some time ago (unfortunately, can't find the record):

// 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 arguments
    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];
}

As you can see, this is Objective-C, but I also need to make it Swifty. So here's where I'm stuck:

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) ?? ""
if NSClassFromString(className) != nil
{
    let object = NSClassFromString(className)?.shared()
    let sel = #selector(_:options:completionHandler:)
    let meth = object?.method(for: sel)
    ...

The problem is with sel (expected expression). The method I am trying to reference here is

open(_:options:completionHandler:) 

This thing

#selector(open(_:options:completionHandler:))

does not work either(use of unresolved identifier) since the view controller I am implementing this code in has no such method.

So the question is: how do I create a nameless selector reference with a few parameters to use later with my meth object? Thanks.

Upvotes: 0

Views: 734

Answers (1)

jbouaziz
jbouaziz

Reputation: 1493

You can use the NSSelectorFromString method which allows you to declare Selector instances using a String.

I don't have the full source code but with a few adjustments, the following should work:

NSSelectorFromString("open(_:options:completionHandler:)")

More documentation on the method is available here.

Upvotes: 1

Related Questions