iosswiftunrecognized-selectorbridging-header

Unrecognized selector sent to class when accessing a ObjC++ function from Swift in tvOS


I'm aware there are many other posts reg this issue, but the only one which I could find that's in the same context as mine (ObjC bridge) is this... and it didn't work for me.

I have the following hierarchy:

// Dependency chain: 
// AppTarget->Lib1
// Lib1->Lib2

AppTarget
Lib1
  -- AppDelegate.swift
Lib2
  -- ObjCppWrapperApple.mm (contains ObjCppWrapper ObjC class)
  -- ObjCppWrapperIOS.mm (Contains a category named 'iOS' for the ObjCppWrapper ObjC class)

// Note: The bridging header is the same for Lib1 and Lib2. Both ObjCppWrapperApple.hpp and ObjCppWrapperIOS.hpp are included in the bridging header

ObjCppWrapperApple.hpp:

@interface ObjCppWrapper : NSObject

// Some methods

@end

ObjCppWrapperIOS.hpp:

#import     "ObjCppWrapperApple.hpp"

@interface  ObjCppWrapper (iOS)

+ (BOOL) PreInitialize NS_SWIFT_NAME (PreInitialize());

// Other methods

@end

ObjCppWrapperIOS.mm:


#import "ObjCppWrapperIOS.hpp"

@implementation ObjCppWrapper (iOS)

+ (BOOL) PreInitialize        
{
    // Some code
}

// Other methods

@end

From the AppDelegate.swift, I'm invoking

ObjCppWrapper.PreInitialize()

and this fails with

Thread 1: "+[ObjCppWrapper PreInitialize]: unrecognized selector sent to class"

And this happens only for tvOS. It is working for iOS.

According to this stackoverflow post, the category and the original class should in the same target. This is my case but from Lib1, I'm unable to access any of the methods (in this example, PreInitialize) in the iOS category of the ObjCppWrapper class. I also moved both the ObjCppWrapper classes to Lib1 i.e., the same target as AppDelegate.swift, and the app still crashes with the error.

Not sure why the PreInitialize method is not found.. and only for tvOS.


Solution

  • For those looking for a pin-point answer (like me), probably missed the link posted in the question comments.

    The underlying issue is ObjC categories in a static library. For detailed explanation, checkout this post.

    The solution is to add,

    -ObjC

    linker flag in AppTarget -> BuildSettings -> Other linker flags.