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.

Jogendra.Com
  • 6,394
  • 2
  • 28
  • 35
abankitbaid
  • 137
  • 5
  • 15

2 Answers2

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);
});
Gev
  • 842
  • 4
  • 21
  • 2
    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")** – abankitbaid Apr 01 '19 at 14:14
  • 1
    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 https://facebook.github.io/react-native/docs/native-modules-ios#sending-events-to-javascript – Gev Apr 01 '19 at 14:51
  • 1
    @objc func callNativeEvent(_ callback: RCTResponseSenderBlock) -> Void { Those who are using the latest swift version please add an underscore before the param – Ashokkumar Adichill Oct 06 '21 at 06:20
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")
Jogendra.Com
  • 6,394
  • 2
  • 28
  • 35