Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expose swift variadic parameter to Objective-C

I am currently working on a swift dynamic framework which will be used for an objective-c application.

I've created this method (signature):

public init(buttons: ActionButton...) {
///code
}

However this method is never accessible (visible) from the objective-c app that is using the framework. When adding

@objc

in front of the method declaration xcode gives the error

"Method cannot be marked @objc because it has a variadic parameter"

So if I understand correctly swift variadic parameters are not exposable to objective c. The question I am therefore asking is: Is there any other way (CVArgList?) to get the same functionality?

I know i can use Arrays but I'd rather not for this function.

Thanks.

like image 372
Guus Avatar asked Jul 01 '16 13:07

Guus


1 Answers

You can bridge variadic functions in C to Swift, but not the other direction. See Using Swift with Cocoa and Objective-C:Interacting with C APIs:Variadic Functions for more on that.

But this isn't that hard to implement by hand. Just create an array version of the method and pass all the variadic forms to it. First in Swift:

public class Test: NSObject {
    convenience public init(buttons: String...) {
        self.init(buttonArray: buttons)
    }

    public init(buttonArray: [String]) {

    }
}

And then expose to ObjC through a category.

@interface Test (ObjC)
- (instancetype) initWithButtons:(NSString *)button, ...;
@end

@implementation Test (ObjC)

- (instancetype) initWithButtons:(NSString *)button, ... {
    NSMutableArray<NSString *> *buttons = [NSMutableArray arrayWithObject:button];
    va_list args;
    va_start(args, button);

    NSString *arg = nil;
    while ((arg = va_arg(args, NSString *))) {
        [buttons addObject:arg];
    }

    va_end(args);
    return [self initWithButtonArray:buttons];
}

@end
like image 195
Rob Napier Avatar answered Oct 11 '22 15:10

Rob Napier