简体   繁体   English

Swift 桥接头不导出 React Native 类型

[英]Swift bridging header not exporting React Native types

I'm trying to create a native (iOS) module for a React Native app using Swift.我正在尝试使用 Swift 为 React Native 应用程序创建本机 (iOS) 模块。 I want to expose a method on the module that returns a promise, using functions of type RCTPromiseResolveBlock and RCTPromiseRejectBlock , both of which are declared in React Native's RCTBridgeModule.h header.我想在模块上公开一个返回承诺的方法,使用RCTPromiseResolveBlockRCTPromiseRejectBlock类型的函数,这两个函数都在 React Native 的RCTBridgeModule.h标头中声明。 However, my build fails with the message "Use of undeclared type..." for both of these types.但是,对于这两种类型,我的构建失败并显示消息“使用未声明的类型...”。

I had already created a bridging header (automatically using Xcode) for another purpose, so I believe importing React/RCTBridgeModule.h is all that I'd need to supply the types mentioned above.我已经为另一个目的创建了一个桥接头(自动使用 Xcode),所以我相信导入React/RCTBridgeModule.h是我需要提供上述类型的全部内容。 Presumably I've misconfigured something, as this doesn't fix the issue.大概我配置错误,因为这不能解决问题。 I've tried setting up a fresh project and everything works as expected there, but I can't seem to find a difference that would cause my project's build to fail.我试过建立一个新项目,一切都按预期工作,但我似乎找不到会导致我的项目构建失败的差异。

Some relevant configuration details:一些相关的配置细节:

  • Bridging header named <ProjectName>-Bridging-Header.h and stored in my source directory.桥接标头名为<ProjectName>-Bridging-Header.h并存储在我的源目录中。 I moved it around to confirm that Xcode is finding it (the build fails differently when it's not in the right place).我移动了它以确认 Xcode 正在找到它(当它不在正确的位置时,构建会以不同的方式失败)。
  • The contents of the bridging header is simply: #import <React/RCTBridgeModule.h>桥接头的内容很简单: #import <React/RCTBridgeModule.h>
  • In my project build settings:在我的项目构建设置中:
    • <ProjectName>-Bridging-Header.h is configured as the "Objective-C Bridging Header" <ProjectName>-Bridging-Header.h被配置为“Objective-C Bridging Header”
    • "Install Objective-C Compatibility Header" is set to "Yes" “安装 Objective-C 兼容性标头”设置为“是”
    • "Precompile Bridging Header" is set to "Yes" “预编译桥接头”设置为“是”
  • When I type alias the missing types the project builds and runs as expected当我输入别名时,缺少的类型项目按预期构建和运行
  • I have some third-party Swift libraries installed (one using react-native link and one using a Git submodule)我安装了一些第三方 Swift 库(一个使用react-native link ,一个使用 Git 子模块)
  • I've tried cleaning the build folder, reinstalling node_modules and deleting Xcode derived data, all to no effect.我试过清理构建文件夹,重新安装node_modules并删除 Xcode 派生数据,但都没有效果。

Is my project misconfigured or have I otherwise missed something important?我的项目是配置错误还是我错过了一些重要的东西?

This tutorial is pretty good at explaining how to set up a native module using Swift.本教程非常擅长解释如何使用 Swift 设置本机模块。 It breaks everything down into steps and it is quite easy to follow.它将所有内容分解为步骤,并且很容易遵循。

https://teabreak.e-spres-oh.com/swift-in-react-native-the-ultimate-guide-part-1-modules-9bb8d054db03 https://teabreak.e-spres-oh.com/swift-in-react-native-the-ultimate-guide-part-1-modules-9bb8d054db03

  1. Setup设置
  2. How to expose a Swift class to JS如何向 JS 公开 Swift 类
  3. How to expose static Swift data如何公开静态 Swift 数据
  4. How to expose a Swift method如何公开 Swift 方法
  5. How to expose a method with a callback如何使用回调公开方法
  6. How to expose a method as a Promise如何将方法公开为 Promise
  7. How to expose an Event Emitter如何公开事件发射器
  8. How to extract your React Native Module如何提取你的 React Native 模块

Clearly it is step 6 that you are looking to do.显然,您要执行的步骤是第 6 步。

Here is a code example.这是一个代码示例。 It is very similar to what is done in the above link.它与上面链接中所做的非常相似。 Your bridging header should look like this:您的桥接头应如下所示:

// <ProjectName>-Bridging-Header.h

#import "React/RCTBridgeModule.h"
#import "React/RCTEventEmitter.h"

You should have files named ModuleName.m and ModuleName.swift .你应该有名为ModuleName.mModuleName.swift文件。

// ModuleName.m
#import "React/RCTBridgeModule.h"
#import "React/RCTEventEmitter.h"
@interface RCT_EXTERN_MODULE(ModuleName, NSObject)
// this is how we expose the promise to the javascript side.
RCT_EXTERN_METHOD(functionWithPromise: (RCTPromiseResolveBlock)resolve rejecter: (RCTPromiseRejectBlock)reject)
@end

// ModuleName.swift

@objc(ModuleName)
class ModuleName: NSObject {
  @objc
  func constantsToExport() -> [AnyHashable : Any]! {
    return ["projectName": "ModuleName"]
  }

  @objc
  static func requiresMainQueueSetup() -> Bool {
    return true
  }

  @objc
  func functionWithPromise(
    _ resolve: RCTPromiseResolveBlock,
    rejecter reject: RCTPromiseRejectBlock
  ) -> Void {
    if (//something bad happens) {
      let error = NSError(domain: "", code: 200, userInfo: nil)
      reject("ERROR_FOUND", "failure", error)
    } else {
      resolve("success")
    }
  }
}

Then on the Javascript side you can access it like this:然后在 Javascript 端,您可以像这样访问它:

import { NativeModules } from 'react-native'

NativeModules.Counter.functionWithPromise()
    .then(res => console.log(res))
    .catch(e => console.log(e.message, e.code))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM