bazel-ios / rules_ios

Bazel rules for building iOS applications and frameworks
Apache License 2.0
276 stars 85 forks source link

@objc directive does not work on swift extension #122

Open edias opened 3 years ago

edias commented 3 years ago

I have a mixed framework where a Objective-C class is extended in swift(@objc) but the Objective-C class does not have visibility to the method. I'm getting error: no visible @interface for 'Objective-C Class' declares the selector 'myMethod'.

I'm using the apple_framework rule.

Any help will be welcome.

segiddins commented 3 years ago

Can you point to a repo that reproduces the issue? Thanks!

gyfelton commented 3 years ago

I made this PR which probably does not reflect your issue but maybe similar? Also I feel they might have the same root cause: https://github.com/bazel-ios/rules_ios/pull/123

edias commented 3 years ago

Just want to give you guys some update on this one.

#import <Foundation/Foundation.h>

@interface MixedClass: NSObject

-(void)run;

@end
#import "MixedClass.h"
#import <MixedFramework/MixedFramework-Swift.h>

@implementation MixedClass

-(void) run {
    [self runSwift];
}

@end

Swift Extension

extension MixedClass {
    @objc
    func runSwift(){}
}

I was getting no visible @interface for MixedClass declares the selector runSwift

It turned out that making the Swift extension public (extension MixedClass -> public extension MixedClass) solved the problem. I have no idea why Xcode can build it as internal.

Any thoughts about that @segiddins?

tinder-maxwellelliott commented 3 years ago

@edias I am running into the same issue, but this is more an issue that XCode is able to expose those internal symbols to the generated Swift Bridging code while we must be more explicit with Bazel by making these extensions public. I believe there are some flags you can pass to Xcode to emit these symbols even if they are not public, but I found that had its own share of issues (thread here)

If I were you I would just make what you need exposed public, that seems to be the consensus from others who have run into this issue

Also are you trying to migrate an iOS application to use apple_framework and consume that as a dependency in an ios_application target? ios_application is allowed to use the internal symbols because of its bridging header, frameworks do not allow this and therefore we must make things public to expose them.