2

I have a swift class, which i am exposing to react-native, inside that i have a function that is also exposed to react-native. Now when react native calls that function it does a lot of this internally, but after some point of time it returns an object.

Now it will call a specific function that will get the object. I cannot change the parameter to that function. But i have another function, to which i want to return to react native. How can i do it.

  func AckCallback(response:APIResponse) -> Void
  {
    print(response)  

  }

for this function I cannot change the paremeter, becaused it had been used a lot of places, But I want to return that response from this function to react-native. If anybody know this issue, please let me know.

  @objc func sendEvent(_ response: APIResponse, callback: (NSObject) -> ()) 
-> Void {

    callback( [[
      "responseCode" : "Working",
      ]] as NSObject)

  }

I just want to know how to use this sendEvent inside the AckCallback, or is there any other way to send that **

response: APIResponse

**

to react-native.

2 Answers 2

4

For the first create Swift class (e.g YourModule.swift)

//
//  YourModule.swift
//

@objc(YourModule)
class YourModule: NSObject {

  @objc func callNativeEvent(callback:RCTResponseSenderBlock) 
-> Void {

   // Here you can do your work and pass an object to the callback function.
  // You can save assign a `callback` to the class property (e.g self.eventCallback = callback)
// and invoke that self.eventCallback after the asynchronous code ol somewhere else
  NSObject *obj = [[NSObject alloc] init]; // your object here
   callback([NSNull(), obj]);
   // or if you want to return an error
   // callback(["Error calling NativeEvent", NSNull()]);

  // I'm not sure that RCTResponseSenderBlock works the same as in previous react-native versions. Maybe now you can pass an Object instead of an Array.
  }
}

Create a Bridge file (e.g. YourModuleBridge.m)

//
//  YourModuleBridge.m
//

#import <Foundation/Foundation.h>
#import "UIKit/UIKit.h"

#import <React/RCTBridgeModule.h>


@interface RCT_EXTERN_MODULE(YourModule, NSObject)

RCT_EXTERN_METHOD(callNativeEvent:(RCTResponseSenderBlock)callback);

@end

Also, you need Bridging-Header file if it doesn't exist in your project.

//
//  YourModule-Bridging-Header.h
//

#ifndef YourModule_Bridging_Header_h
#define YourModule_Bridging_Header_h

#if __has_include("RCTBridgeModule.h")
#import "RCTBridgeModule.h"
#else
#import <React/RCTBridgeModule.h>
#endif

#endif /* YourModule_Bridging_Header_h */

And from JS

import { NativeModules } from 'react-native';

const YourModule = NativeModules.YourModule;

...

YourModule.callNativeEvent((error, response) => {
  console.log('Error', error, 'Response', response);
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the help, But i have some registered callbacks with this, and those have 3 functions, based on the activity in "callNativeEvent" function it will call any of those three functions. Now i have three functions to call, and all three definitions are defined, i cannot change that, But my registered callback can call anyone from that, from there i want to return something to my react native callback. I tried another option to send a notification from swift file, But its giving error. self.bridge.eventDispatcher()?.sendAppEvent(withName: eventName, body: "testing")
You can try to extend from RCTEventEmitter and call self.sendEvent(withName: "yourEventName", body: ["key": "value"]). In that case you need to override supportedEvents and return an array of event names ( ["yourEventName"]) And in JS import { NativeModules, NativeEventEmitter } from ''react-native; const myModuleEvt = new NativeEventEmitter(NativeModules.MyModule); myModuleEvt.addListener('yourEventName', (data) => console.log(data)) You can find an ObjectiveC example here facebook.github.io/react-native/docs/…
@objc func callNativeEvent(_ callback: RCTResponseSenderBlock) -> Void { Those who are using the latest swift version please add an underscore before the param
2

In iOS Project Create 2 Files

SwiftComponentManager.swift and SwiftComponentManager.m  create these 2 files. 

SwiftComponentManager.swift ->

@objc(SwiftComponentManager)
class SwiftComponentManager: NSObject {

@objc func passValueFromReact(_ value : String) {
    debugPrint(" Print Here \(value)")
 }
}

In SwiftComponentManager.m

#import <Foundation/Foundation.h>

#import "React/RCTBridgeModule.h"
@interface RCT_EXTERN_MODULE(SwiftComponentManager, NSObject)

  RCT_EXTERN_METHOD(passValueFromReact:(NSString *)value) //Here exported your swift function for React Native 
@end

Here start work in React-Native project

Now How will call this Swift function in React Native.

Import your SwiftComponent in React JS file

const { SwiftComponentManager } = NativeModules

Now call your function with value where you want in JS file

SwiftComponentManager.passValueFromReact("Hello World")

2 Comments

I got error: TypeError: null is not an object (evaluating 'SwiftComponentManager.passValueFromReact')
It works, i forget to check m file in Target Membership in right panel

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.