1

I have an ObjC class with an init method

-(instancetype) initWithApiKey: (NSString *) key order: (NSNumber *) order

In ObjC I dynamically create it with the following code:

id classAllocation = [NSClassFromString(@"MyClass") alloc];
NSObject * classInstance = [classAllocation performSelector:@selector(initWithApiKey:order:) 
withObject:@"mykey" withObject:@1];

But how would I do the same in Swift?

TpoM6oH
  • 8,385
  • 3
  • 40
  • 72
  • Out of curiosity - why do you do it this way? Why not simply call the initializer? Or is rhis just a simplified example for the question? – Losiowaty Jul 09 '20 at 12:04
  • Can't you just call it from Swift? https://developer.apple.com/documentation/foundation/1395135-nsclassfromstring You need to show what exactly did you try in Swift and how it didn't work. – H. Al-Amri Jul 09 '20 at 21:30
  • You don't need to use performSelector in ObjC, BTW. You can just call ```[[NSClassFromString(@"MyClass") alloc] initWithApiKey:@"mykey" order:@1]```. You can dynamically create objects with the empty initializer from Swift ( ```let classObject = NSClassFromString("MyClass"); let classInstance = classObject.init()``` from Swift, but not sure you can do any arbitrary init method that way. You may need to implement a wrapper function or class method which is then bridged and callable from Swift. – Carl Lindberg Jul 10 '20 at 16:02

1 Answers1

2

Try this:

if let allocatedObject = NSClassFromString("MyClass")?.alloc() as? NSObject {
    let selector: Selector = NSSelectorFromString("initWithApiKey:order:")
    let methodIMP: IMP! = allocatedObject.method(for: selector)
    let objectAfterInit = unsafeBitCast(methodIMP,to:(@convention(c)(AnyObject?,Selector,NSString,NSNumber)->NSObject).self)(allocatedObject,selector,"mykey", NSNumber(integerLiteral: 1))
}

More examples with details in my answer here

Kamil.S
  • 5,205
  • 2
  • 22
  • 51
  • I've ended up with a similar solution ``` if let allocatedObject = NSClassFromString("MyClass")?.alloc() as? NSObject { let selector: Selector = NSSelectorFromString("initWithApiKey:order:") let obj = allocatedObject.init() if (obj.responds(to: selector)) == true { obj.perform(selector, with:"key", order:0); } } ``` – TpoM6oH Jul 16 '20 at 16:56