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",
},
});
@romixch
Copy link

romixch commented Sep 17, 2019

This helped me a lot. The login elegantly shows how to use function parameters and promises together. Thanks for sharing!

@AliRehman7141
Copy link

AliRehman7141 commented Dec 31, 2020

Hello sir!
how are you?

I need have started the camera in the swift controller could you help me to add promise there so when the camera is done with the recording or capturing image it should return URI in resolve

the callback methods are working fine that returns the data in the callback

@a-eid
Copy link

a-eid commented Jun 16, 2021

it would be really cool if you add an example of how to handle delegates such as these

Screen Shot 2021-06-16 at 3 25 13 PM

keeping in mind that .catch & .then would need to be invoked by other functions.

@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