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
相关产品推荐
相关产品推荐

