Skip to content

Instantly share code, notes, and snippets.

@JofArnold
Last active October 26, 2022 13:31
Show Gist options
  • Save JofArnold/31dfa8edcc3b8a42bbd86fbd44dad804 to your computer and use it in GitHub Desktop.
Save JofArnold/31dfa8edcc3b8a42bbd86fbd44dad804 to your computer and use it in GitHub Desktop.
Using promises in React Native modules with Swift

Instructions

  • In a new or existing project called MyProject (for example) add the .h, .m and .swift files to the /ios/ directory
  • Put the ReactNativeSwiftPromises file wherever you like
  • Launch/compile your react native project. Note: whenever you change the native files you'll need to recompile with XCode

NOTE: if this example doesn't compile/work let me know. I just pasted random bits from a project without checking if it compiles. I'm using 9.2 with RN 0.55.2

// Created by react-native-create-bridge
// import RCTBridgeModule
#if __has_include(<React/RCTBridgeModule.h>)
#import <React/RCTBridgeModule.h>
#elif __has_include(“RCTBridgeModule.h”)
#import “RCTBridgeModule.h”
#else
#import “React/RCTBridgeModule.h” // Required when used as a Pod in a Swift project
#endif
// import RCTEventEmitter
#if __has_include(<React/RCTEventEmitter.h>)
#import <React/RCTEventEmitter.h>
#elif __has_include(“RCTEventEmitter.h”)
#import “RCTEventEmitter.h”
#else
#import “React/RCTEventEmitter.h” // Required when used as a Pod in a Swift project
#endif
// Export a native module
// https://facebook.github.io/react-native/docs/native-modules-ios.html#exporting-swift
@interface RCT_EXTERN_MODULE(Login, NSObject)
// Export methods to a native module
// https://facebook.github.io/react-native/docs/native-modules-ios.html#exporting-swift
RCT_EXTERN_METHOD(
login: (NSString *)email
password:(NSString *)password
resolve: (RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject
)
@end
// Created by react-native-create-bridge
import Foundation
@objc(Login)
class PromiseTest : NSObject {
@objc
func login(_ email: String, password: String, resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) -> Void {
resolve("You sent: email '\(email)', password '\(password)'")
}
}
// This enables the Swift file to be used with RN. If you were just using ObjC you wouldn't need this
// Created by react-native-create-bridge
// PromiseTest-Bridging-Header.h
// import RCTBridgeModule
#if __has_include(<React/RCTBridgeModule.h>)
#import <React/RCTBridgeModule.h>
#elif __has_include(“RCTBridgeModule.h”)
#import “RCTBridgeModule.h”
#else
#import “React/RCTBridgeModule.h” // Required when used as a Pod in a Swift project
#endif
// import RCTEventEmitter
#if __has_include(<React/RCTEventEmitter.h>)
#import <React/RCTEventEmitter.h>
#elif __has_include(“RCTEventEmitter.h”)
#import “RCTEventEmitter.h”
#else
#import “React/RCTEventEmitter.h” // Required when used as a Pod in a Swift project
#endif
import React from "react";
import { StyleSheet, Text, View, Button } from "react-native";
import { NativeModules } from "react-native";
const { Login } = NativeModules;
const login = async () => {
const response = await PromiseTest.login("Bob", "Salmon");
console.log(respone); // "You sent: email Bob, password Salmon"
};
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Press button to log in</Text>
<Button onPress={login} title="Login" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
@dxwave
Copy link

dxwave commented Jun 23, 2021

Got some questions regarding the threading. Let's assume the login method makes a network request, and calls a closure (not necessarily on the main thread). Is it still safe to call the resolve or reject in that closure? How would that work?

@ivangonzalezg
Copy link

image

I am having this error, could someone help me?

@bxvd
Copy link

bxvd commented Aug 29, 2021

image

I am having this error, could someone help me?

Add import React

@aakashsigdel
Copy link

@bxvd you will need to create a bridging header file with the following import
#import <React/RCTBridgeModule.h>

@pixelknitter
Copy link

It'd be good to have an example of how to use the rejecter:

reject("failed_login", "Failed to log in", error)

It takes three parameters: an identifier, message, and error object if I understand correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment