RCT_EXTERN_MODULE Swift modules broken in Xcode 10.2
See original GitHub issue🐛 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
:
Issue Analytics
- State:
- Created 4 years ago
- Reactions:78
- Comments:65 (7 by maintainers)
Top Results From Across the Web
Failed to build module, Apple Swift version 5.1.3 have features ...
This error indicates that you have a binary named SciChart that was built with a previous version of the Swift compiler (5.1.3). Your...
Read more >After clean build in xcode getting no such module on all imports
My code was running fine, but after clean build (cmd+shift+k) all of sudden i started getting no such module found on all my...
Read more >Enabling Module Stability in Swift Package Manager Projects
To compile with module stability outside of Xcode, we need to pass the following flags: -emit-module-interface; -enable-library-evolution. For ...
Read more >How to update to Xcode 10.2.1 on High Sierra - CodeWithChris
4), this means that developers who have old Macs won't be able to update their OS and develop in Swift 5 using Xcode...
Read more >Modularize Xcode Projects using local Swift Packages - ITNEXT
Swift Package Manager is most likely the future of working with Swift dependencies, but we can also use it to manage local code!...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Hi! I’m not very familiar with react-native, but I found myself here because I’m blocked from upgrading to 10.2 by one of dependency that uses react-native.
I have an idea for a fix though:
The problem with this is that
RCT_EXPORT_MODULE
macro will require objc_name parameter now. As I understand, this is not very convenient, as it is used in many places by users. So another solution is to introduce another macro:And replace call in RCT_EXTERN_REMAP_MODULE to new macro:
I’m ok to make a pr, but it will take some time until I figure out how to setup everything.
If you can’t update your react-native version to get this fix when it is merged because you are using the Expo fork of react-native. Then add this code ( based on above PR ) to a header file:
Then in your module .m objective C file import that header file you just created and use
RCT_EXTERN_MODULE_2
instead ofRCT_EXTERN_MODULE
Example: