I have some Objective-C++ code like this:
// header
@interface MyObjcClass
- (void) myMethod: (NSString *) text;
@end
// implementation
@implementation MyObjcClass
- (void) myMethod: (NSString *) text
{
someInternalObject->useWstring(nsStringToWstring(text))
}
std::wstring nsStringToWstring(const NSString * text)
{
NSData * data = [text dataUsingEncoding: NSUTF32LittleEndianStringEncoding];
// and then some other stuff irrelevant to this question
return std::wstring(pointerToNewString, pointerToNewString + stringLength);
}
@end
Straightforward so far; seems fine to me. And works great when called from Objective-C and Objective-C++ code! However, when Swift gets involved...
func mySwiftFunc(text: String) {
myObjcClassInstance.myMethod(text)
}
This also seems straightforward. The compiler's translation layer automatically bridge's Swift's String to Objective-C++'s NSString *. Unfortunately, that's false... it seems to bridge it to something called _SwiftValue. And then that's passed in and I try to call dataUsingEncoding: on it, but apparently _SwiftValue doesn't have such a selector, so I get this crash:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue dataUsingEncoding:]: unrecognized selector sent to instance 0x7f9ca7d63ee0'
I'm at a loss for how to resolve this. I can't use NSString in Swift and just pass that down because the compiler requires that I pass a Swift String.
Any of these solutions will do:
NSString * instead of a String_SwiftValue into data from within Objective-C++_SwiftValue to a NSString * before trying to message itI'd try
func mySwiftFunc(text: String) {
myObjcClassInstance.perform(#selector(NSSelectorFromString("myMethod:"), with: text as NSString)
}
If that won't work try:
func mySwiftFunc(text: String) {
let selector : Selector = NSSelectorFromString("myMethod:")
let methodIMP : IMP! = myObjcClassInstance.method(for: selector)
unsafeBitCast(methodIMP,to:(@convention(c)(Any?,Selector,NSString)->Void).self)(myObjcClassInstance,selector,text as NSString)
}
Probably possible without selector name "myMethod:" String dependence, but I skipped the casting gymnastics as it's not the essence of the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With