Skip to content

RCT_EXTERN_MODULE Swift modules broken in Xcode 10.2 #24139

@kdawgwilk

Description

@kdawgwilk

🐛 Bug Report

It appears Obj-C runtime got more strict with Swift ABI stability in Xcode 10.2 and now causes a crash at runtime when trying to load modules that have Swift implementations. This is the crash error:

Swift class extensions and categories on Swift classes are not allowed to have +load methods

To Reproduce

Create a RN NativeModule e.g.

BadgeHandler.m

#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(BadgeHandler, NSObject)
    RCT_EXTERN_METHOD(setBadgeNumber:(int *)badgeNumber)
@end

BadgeHandler.swift

import UIKit

@objc(BadgeHandler)
class BadgeHandler: NSObject, RCTBridgeModule {
    static func moduleName() -> String! {
        return "BadgeHandler";
    }

    static func requiresMainQueueSetup() -> Bool {
        return true
    }
    
    @objc func setBadgeNumber(_ badgeNumber: Int) {
        DispatchQueue.main.async {
            UIApplication.shared.applicationIconBadgeNumber = badgeNumber
        }
    }
}

AppName-Bridging-Header.h

#ifndef AppName_Bridging_Header_h
#define AppName_Bridging_Header_h

#import <React/RCTBridgeModule.h>

#endif /* AppName_Bridging_Header_h */

Expected Behavior

The NativeModule would load fine at runtime like it did in previous versions of Xcode

Code Example

See above ^

Environment

  React Native Environment Info:
    System:
      OS: macOS 10.14.3
      CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
      Memory: 31.36 MB / 32.00 GB
      Shell: 5.3 - /bin/zsh
    Binaries:
      Node: 11.6.0 - /usr/local/bin/node
      Yarn: 1.13.0 - /usr/local/bin/yarn
      npm: 6.5.0 - /usr/local/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    SDKs:
      iOS SDK:
        Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
      Android SDK:
        API Levels: 23, 25, 26, 27, 28
        Build Tools: 27.0.3, 28.0.2, 28.0.3
        System Images: android-28 | Google APIs Intel x86 Atom
    IDEs:
      Xcode: 10.2/10E125 - /usr/bin/xcodebuild
    npmPackages:
      react: 16.8.3 => 16.8.3
      react-native: 0.59.1 => 0.59.1

Other

This seems to point to this macro in RCTBridgeModule.h:

#define RCT_EXPORT_MODULE(js_name) \
RCT_EXTERN void RCTRegisterModule(Class); \
+ (NSString *)moduleName { return @#js_name; } \
+ (void)load { RCTRegisterModule(self); }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions