【问题标题】:React-Native Module in Swift with async function throws is not a recognized Objective-C method具有异步函数抛出的 Swift 中的 React-Native 模块不是公认的 Objective-C 方法
【发布时间】:2023-01-10 16:16:20
【问题描述】:

我正在尝试导出一个 swift 模块 according to react-native's documentation,但是当我尝试在我的 javascript 文件中调用此函数时遇到以下错误。我认为这个问题与在我的 swift 代码中调用 async 方法有关。所以我不确定在 react-native 中创建本机模块时如何从我的 swift 文件中导出和调用 async 方法。

这是包含我要导出的 async 方法的 AppleMusicAuth.swift 文件

//
//  AppleMusicAuth.swift
//
//
//

import Foundation
import MusicKit

@available(iOS 15.0, *)
@objc(AppleMusicAuth)
class AppleMusicAuth: NSObject {

  @objc
  func getAuthStatus() async -> Void {
    let response = await MusicAuthorization.request()
    print(response)
  }
}

与我的 AppleMusicAuth.m 文件一起使用 RCT_EXTERN_METHOD 方法将模块导出到我的 JS 应用程序

//
//  AppleMusicAuth.m
//
//
//

#import <Foundation/Foundation.h>

#import <React/RCTBridgeModule.h>


@interface RCT_EXTERN_MODULE(AppleMusicAuth, NSObject)

RCT_EXTERN_METHOD(getAuthStatus)

@end

以及导入调用模块和方法的Javascript文件

import { NativeModules } from 'react-native';
const { AppleMusicAuth } = NativeModules;
export default AppleMusicAuth;
import React from 'react';
import {Button} from 'react-native';
import AppleMusicAuth from '../nativeModules/AppleMusicAuth';

type Props = {};

const App: React.FC<Props> = () => {
  return (
        <Button
          onPress={() => {
            AppleMusicAuth.getAuthStatus();
          }}
          title="Button"
          color="#841584"
        />
  );
};

export default App;

【问题讨论】:

  • 感觉这个问题需要更多关注,目前还没有对 MusicKit 的 objective c 支持,所以 swift 是唯一的选择,但据我所知,没有办法在 RN 模块中使用 async await 我觉得 PromisesSwift 可能值得研究但不当然。

标签: javascript reactjs swift objective-c react-native


【解决方案1】:

编辑:从 2023 年 1 月 10 日开始,我的建议是使用 expo-modules-core,因为它支持这个用例。

见:https://docs.expo.dev/modules/get-started/

示例:https://github.com/expo/expo/pull/20645

原始答案

我刚遇到这个,这是我的解决方法。 我们可以导出一个常规函数,然后调用 async 函数,而不是将 async 函数导出到 React Native/Objective-C。

  • 要从 Swift 中的普通函数调用异步函数,我们可以使用 Task
  • 要将结果发送回 React Native,我们可以使用 events
  func myAsyncFunction(_ data: NSDictionary) async -> Void {
    // Processing...
    self.sendEvent(withName: "MyEvent", body: "The result")
  }

  @objc
  func myExportedFunction(_ data: NSDictionary) -> Void {
    Task {
      await myAsyncFunction(data)
    }
  }

【讨论】:

  • 我想补充一点,async 不适用于 React Native 的原因是该函数在 Objective-C 中添加了一个完成处理程序。我们可以在 Objective-C 中导入 #import &lt;PRODUCT_NAME-Swift.h&gt; 标头以查看可用的内容。如果你打开那个头文件,你会发现你的 async 方法已经添加了一个桥不支持的完成处理程序。
  • 救命的答案,谢谢!如 RN 文档中所述,我还能够使用类型为 RCTResponseSenderBlock 的回调将结果发送回 React Native。它只需要在导出的(非异步)函数中声明为@escaping。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2020-09-06
  • 2022-01-02
  • 2017-06-18
  • 1970-01-01
  • 2019-03-09
相关资源
最近更新 更多