skip to Main Content

I followed the guide here to create a turbo module. This was fine.

https://reactnative.dev/docs/the-new-architecture/pillars-turbomodules

I want to use Swift code in this turbo module. I tried adding a Swift file with this code and modifying the RTNCalculator.mm so that the number addition happens in Swift called from Objective-C.

SwiftCalculator.swift

import Foundation

@objc class SwiftCalculator: NSObject {
    @objc func add(a: Double, b: Double) -> Double {
        return a + b
    }
}

RTNCalculator.mm

#import "RTNCalculatorSpec.h"
#import "RTNCalculator.h"
#import "RTNCalculator-Swift.h"

@implementation RTNCalculator

RCT_EXPORT_MODULE()

- (void)add:(double)a b:(double)b resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
    SwiftCalculator *calculator = [SwiftCalculator new];
    double value = [calculator addWithA:a b:b];
    NSNumber *result = [[NSNumber alloc] initWithDouble:value];
    resolve(result);
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
    (const facebook::react::ObjCTurboModule::InitParams &)params
{
    return std::make_shared<facebook::react::NativeCalculatorSpecJSI>(params);
}

@end

I also modified the pod spec file to use a bridging header file.

  s.pod_target_xcconfig = { 
    'SWIFT_OBJC_BRIDGING_HEADER' => '../../node_modules/rtn-calculator/ios/RTNCalculator-Bridging-Header.h'
  }

This doesn’t work. I get this error in the project.

Using bridging headers with framework targets is unsupported

How do I use Swift in a Turbo Module?

2

Answers


  1. For your example, you shouldn’t need a bridging header at all. That allows you to import ObjC into Swift, not Swift into ObjC. Did you try just removing the SWIFT_OBJC_BRIDGING_HEADER bit?

    The RTNCalculator-Swift.h header is what lets you import Swift into ObjC, and that part of of your code looks ok. What specific error do you receive if you take out the bridging header?

    Login or Signup to reply.
  2. To resolve the issue for your Cocoa Pod (Turbo Module) you should make the following:

    1. Mark @objc and public all needed classes, method, properties etc. in your swift code because all of them are internal by default and are not visible outside.
    @objc
    public class SwiftCalculator: NSObject {
        @objc
        public func add(a: Double, b: Double) -> Double {
            a + b
        }
    }
    
    1. Import the pod’s swift/objc generated header into your obj files in the format: "<MyPodName>+Swift.h". In your case the pod name is "rtn_calculator".
    ...
    #import "rtn_calculator-Swift.h"
    ...
    RCT_REMAP_BLOCKING_SYNCHRONOUS_METHOD(add, NSNumber*, addA:(NSInteger)a andB:(NSInteger)b)
    {
        SwiftCalculator* calculator = [SwiftCalculator new];
        double value = [calculator addWithA:a b:b];
        return @(value);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search