You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Swift原生模块传值丢失:如何保存RN传递的值

解决方案:React Native Swift模块传值丢失问题

你的推测是对的:调用goToNativeView后,原来的MyModule控制器实例被新的Storyboard控制器替换,导致存储的value被销毁。以下是几种可行的解决思路:

方案1:直接将参数传递给目标控制器(推荐)

修改AppDelegate的方法,让它接收RN传递的值,在实例化Storyboard控制器时直接赋值给目标控制器的属性:

步骤1:更新AppDelegate方法

- (void) goToNativeViewWithValue:(NSString *)passedValue
{
  UIViewController *vc = [UIStoryboard storyboardWithName:@"MyModuleScreen" bundle:nil].instantiateInitialViewController;
  // 假设你的Storyboard根控制器有一个名为rnPassedValue的属性
  if ([vc respondsToSelector:@selector(setRnPassedValue:)]) {
      vc.rnPassedValue = passedValue;
  }
  self.window.rootViewController = vc;
  [self.window makeKeyAndVisible];
}

步骤2:修改Swift模块调用逻辑

@objc (MyModule) class MyModule : NSObject { // 模块无需继承UIViewController
  @objc static func requiresMainQueueSetup() -> Bool { return true }

  @objc func openMyModule(_ rn_value: String) -> Void {
    DispatchQueue.main.async {
      if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        appDelegate.goToNativeView(withValue: rn_value)
      }
    }
  }
}

步骤3:在Storyboard控制器中添加属性

class MyModuleScreenVC: UIViewController {
    var rnPassedValue: String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 在这里直接使用rnPassedValue
        print("RN传递的值:\(rnPassedValue ?? "")")
    }
}

方案2:用AppDelegate存储临时全局变量

在AppDelegate中添加属性存储值,目标控制器从AppDelegate读取:

步骤1:AppDelegate添加属性

@property (nonatomic, strong) NSString *tempRNValue;

步骤2:Swift模块赋值并跳转

@objc func openMyModule(_ rn_value: String) -> Void {
  DispatchQueue.main.async {
    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
      appDelegate.tempRNValue = rn_value
      appDelegate.goToNativeView()
    }
  }
}

步骤3:目标控制器读取值

override func viewDidLoad() {
    super.viewDidLoad()
    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        let value = appDelegate.tempRNValue ?? ""
        // 使用value
    }
}

方案3:用UserDefaults临时存储

适合不需要持久化的简单值,用完记得清理:

Swift模块存储值

@objc func openMyModule(_ rn_value: String) -> Void {
  UserDefaults.standard.set(rn_value, forKey: "RN_Temp_Value")
  DispatchQueue.main.async {
    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
      appDelegate.goToNativeView()
    }
  }
}

目标控制器读取并清理

override func viewDidLoad() {
    super.viewDidLoad()
    let value = UserDefaults.standard.string(forKey: "RN_Temp_Value") ?? ""
    // 使用value
    UserDefaults.standard.removeObject(forKey: "RN_Temp_Value") // 避免残留
}

方案4:将模块改为单例类

RN原生模块无需继承UIViewController,改成单例后可以持久保存状态:

修改Swift模块为单例

@objc (MyModule) class MyModule : NSObject {
  @objc static func requiresMainQueueSetup() -> Bool { return true }
  
  static let shared = MyModule()
  var storedValue = ""

  @objc func openMyModule(_ rn_value: String) -> Void {
    self.storedValue = rn_value
    DispatchQueue.main.async {
      if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        appDelegate.goToNativeView()
      }
    }
  }
}

目标控制器访问单例值

override func viewDidLoad() {
    super.viewDidLoad()
    let value = MyModule.shared.storedValue
    // 使用value
}

内容的提问来源于stack exchange,提问作者Anderson Vanzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 05:31:18