将 React Native 与现有 iOS Swift 应用程序集成时的不变违规和类型错误

问题描述 投票:0回答:1

我目前正在将用 Swift 编写的 iOS 应用程序迁移到新的 React Native 项目。我首先使用以下命令生成

main.jsbundle
,成功将 React Native 组件集成到我的 iOS 应用程序中:

react-native bundle --dev false --entry-file index.js --bundle-output ios/myApp/main.jsbundle --platform ios --assets-dest iOS

在 Swift 中,我使用以下代码集成了 React Native 组件:

private func showRNComponent() {
    let rootView = RCTRootView(
        bundleURL: Bundle.main.url(forResource: "main", withExtension: "jsbundle")!,
        moduleName: "DemoPage",
        initialProperties: nil,
        launchOptions: nil
    )
    let vc = UIViewController()
    vc.view = rootView
    self.present(vc, animated: true, completion: nil)
}

此方法与

main.jsbundle
配合使用效果很好。但是,我尝试使用 Metro 作为开发服务器以获得更好的调试功能,并更新了从开发服务器获取捆绑包的方法:

private func showRNComponent() {
    guard let jsCodeLocation = URL(string: "http://localhost:8081/index.bundle?platform=ios") else {
        NSLog("Invalid URL")
        return
    }
    let rootView = RCTRootView(
        bundleURL: jsCodeLocation,
        moduleName: "DemoPage",
        initialProperties: nil,
        launchOptions: nil
    )
    let vc = UIViewController()
    vc.view = rootView
    self.present(vc, animated: true, completion: nil)
}

启动 Metro 并运行开发服务器后,当尝试触发该功能时,我在 XCode 控制台中收到以下错误:

Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'DevSettings' could not be found. Verify that a module by this name is registered in the native binary. Bridgeless mode: false. TurboModule interop: false. Modules loaded: {"NativeModules":["PlatformConstants","Timing","AppState","SourceCode","BlobModule","WebSocketModule","SettingsManager"],"TurboModules":[],"NotFound":["NativePerformanceCxx","NativePerformanceObserverCxx","LogBox","DevSettings"]}, js engine: hermes
TypeError: Cannot read property 'render' of undefined, js engine: hermes

我怀疑这个问题可能与XCode构建目标设置有关,应该将其设置为调试模式以加载开发设置。尽管我已确保我的构建设置和预处理器宏 (

preprocessor macros: debug=1
) 应用于所有构建配置,但问题仍然存在。

以下是我的

Podfile
package.json
的摘录,详细介绍了我正在使用的库和设置:

//Poddile
source 'https://github.com/CocoaPods/Specs.git'

require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, '14.0'
# min_supported_versions = { :ios => "13.0"}
prepare_react_native_project!

target 'MyApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    :flipper_configuration => FlipperConfiguration.disabled,
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  # Pods for MyApp
  pod 'RxSwift'
  pod 'RxCocoa'
  pod 'SDWebImage'
  pod 'Alamofire'
  pod 'MBProgressHUD'
  pod 'SwiftyJSON'
  pod 'SwiftyUserDefaults'
  pod 'ObjectMapper'
  pod 'Firebase/Crashlytics', '9.2.0'
  pod 'Firebase/Analytics', '9.2.0'
  pod 'Firebase/Messaging', '9.2.0'
  pod 'SwipeCellKit'
  pod 'Kingfisher'
  pod 'WeScan'
  pod 'RxDataSources', '~> 4.0'
  pod 'ChameleonFramework'
#  pod 'FlexLayout'
  pod 'SwiftSoup'
  pod 'IQKeyboardManagerSwift'
  pod 'GoogleMLKit/BarcodeScanning', '2.6.0'
  pod 'MJRefresh'
  pod 'DGCharts'
  
  target 'MyAppTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'MyAppUITests' do
    inherit! :search_paths
    # Pods for testing
  end


# post install
post_install do |installer|
  react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
  installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
      end
    end
  # fix xcode 15 DT_TOOLCHAIN_DIR - remove after fix oficially - https://github.com/CocoaPods/CocoaPods/issues/12065
  installer.aggregate_targets.each do |target|
    target.xcconfigs.each do |variant, xcconfig|
      xcconfig_path = target.client_root + target.xcconfig_relative_path(variant)
      IO.write(xcconfig_path, IO.read(xcconfig_path).gsub("DT_TOOLCHAIN_DIR", "TOOLCHAIN_DIR"))
    end
  end
  
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      if config.base_configuration_reference.is_a? Xcodeproj::Project::Object::PBXFileReference
        xcconfig_path = config.base_configuration_reference.real_path
        IO.write(xcconfig_path, IO.read(xcconfig_path).gsub("DT_TOOLCHAIN_DIR", "TOOLCHAIN_DIR"))
      end
    end
  end
end
end
{
    "name": "MyApp",
    "version": "0.0.1",
    "private": true,
    "scripts": {
        "doctor": "react-native doctor",
        "upgrade": "react-native upgrade",
        "config": "react-native config",
        "android": "react-native run-android",
        "ios": "react-native run-ios --mode \"ETE-t1-Debug\" --scheme=\"MyApp-ETE(t1)\"",
        "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
        "start": "react-native start",
        "bundle:ios": "react-native bundle --dev false --entry-file index.js --bundle-output ios/MyApp/main.jsbundle --platform ios --assets-dest ios",
        "bundle:android": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res",
        "clean": "npx react-native-clean-project"
    },
    "dependencies": {
        "@react-native-async-storage/async-storage": "1.23.1",
        "axios": "^1.6.8",
        "react": "18.2.0",
        "react-native": "0.73.6",
        "react-native-progress": "^5.0.1"
    },
    "devDependencies": {
        "@babel/core": "^7.20.0",
        "@babel/preset-env": "^7.20.0",
        "@babel/runtime": "^7.20.0",
        "@react-native/babel-preset": "0.73.21",
        "@react-native/eslint-config": "0.73.2",
        "@react-native/metro-config": "0.73.5",
        "@react-native/typescript-config": "0.73.1",
        "@types/react": "^18.2.6",
        "@types/react-test-renderer": "^18.0.0",
        "babel-jest": "^29.6.3",
        "eslint": "^8.19.0",
        "prettier": "2.8.8",
        "react-test-renderer": "18.2.0",
        "typescript": "5.0.4"
    },
    "engines": {
        "node": ">=18"
    }
}

任何有关如何解决这些错误或调试此问题的进一步步骤的建议将不胜感激!

ios swift xcode react-native metro-bundler
1个回答
0
投票

通过将自定义构建配置添加到 podfile 解决了我的问题,因为我的项目使用了自定义构建配置。

示例代码来自https://github.com/CocoaPods/CocoaPods/issues/10015

enter image description here

谢谢@达斯汀

© www.soinside.com 2019 - 2024. All rights reserved.