如何在使用桥接头时将数据(字典)从 Objective-C 控制器传递到 Swift `viewcontroller` 中?还有其他方法吗?

Posted

技术标签:

【中文标题】如何在使用桥接头时将数据(字典)从 Objective-C 控制器传递到 Swift `viewcontroller` 中?还有其他方法吗?【英文标题】:How to pass data(dictionary) from Objective-C Controller into Swift `viewcontroller` while using bridging-header? Is there any other way? 【发布时间】:2019-04-12 11:13:41 【问题描述】:

我想将字典从 Objective-C 控制器发送到 Swift 控制器。我曾尝试在 Swift 控制器中使用关键字 @obj-c,Public 但无法访问。

Objective-C 代码:

    vc_listing_list *swiftController = [[vc_listing_list alloc] init];

    swiftController = (vc_listing_list *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];

这里我想访问"selectedDirectory" 变量来发送字典值。

Swift 代码:

@objc class vc_listing_list: UIViewController 

   var selectedDirectory: Dictionary<String, String>


我希望我的代码在目标 c 控制器中:

vc_listing_list *swiftController = [[vc_listing_list alloc] init];

swiftController = (vc_listing_list *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
swiftController.selectedDirectory = someDictionary;  // this line am expecting.

【问题讨论】:

【参考方案1】:

@objcMembers 添加到 swift 文件中

@objcMembers class vc_listing_list: UIViewController 

var selectedDirectory: Dictionary


如果你使用storyboard那么你不需要像这样初始化

vc_listing_list *swiftController = [[vc_listing_list alloc] init];

你可以直接这样使用

  vc_listing_list * swiftController = [storyboard instantiateViewControllerWithIdentifier:@"viewControllerID"];
  swiftController.selectedDirectory = someDictionary
  [self.navigationController pushViewController:swiftController animated:YES];

请尝试更正您的类和对象命名约定。 谢谢

【讨论】:

谢谢。我可以使用@objcMembers 访问该变量,而不是使用情节提要,仅通过我的设计代码。 这应该被标记为正确答案。另一种方法是将selectedDictionary 显式声明为@objc。这两种方法都会导致 Swift 属性对 Objective-C 可见,这正是你想要的。【参考方案2】:

要从 Swift 访问 Objective-C 类,您需要将其添加到桥接头中。桥接头通常以您的目标名称命名,例如MyApp-BridgingHeader.h

您在桥接头中导入 Swift 所需的任何标头:

#import "VCListingList.h" 

您可以从那里从 Swift 中访问该类。

let controller = VCListingList()

因此,对于您的问题,您需要将 Header 中的selectedDirectory 公开为具有&lt;NSString *,NSString *&gt; 桥接类型的完整属性。

您可以选择使用nullable 使其成为Optional。如果你不希望它是Optional,你必须在用 Swift 读取它之前初始化这个属性。

NS_ASSUME_NONNULL_BEGIN

@interface VCListingList: UIViewController 

@property (nonatomic, strong, nullable) NSDictionary<NSString *,NSString *>* selectedDictionary;

//the rest of your header stuff

@end

NS_ASSUME_NONNULL_END

样式说明:类名不要使用小写。这使它们很容易与变量混淆。所以 VCListingList 优于 vc_listing_list

您可以read the documentation了解更多信息

【讨论】:

【参考方案3】:

有几种方法可以将数据从目标 c 传递到 swift 类。

1) 使用 NSUserDefault

NSMutableDictionary *dic = [[NSMutableDictionary  alloc] init];

[dic addObject:@"sss" forKey:@"hi"];
[dic addObject:@"eee" forKey:@"hr"];
[NSUserDefaults standardDefaults] setObject:dic forKey:@"DicKey"];
[[NSUserDefaults standardDefaults] synchronize];

然后在swift类中获取数据

let dic = NSUserDefaults.standard.string(forKey: "DicKey")

2) 使用 swift 类的直接创建对象。

var dic : [[String:Any]]!

像这样传递字典

NSMutableDi

ctionary *dic = [[NSMutableDictionary  alloc] init];
[dic addObject:@"sss" forKey:@"hi"];
[dic addObject:@"eee" forKey:@"hr"];

SwiftViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"SwiftViewController"];
  SwiftViewController.dict = dict
  [self.navigationController pushViewController:vc animated:YES];

【讨论】:

非常感谢。我有一些想法将数据从目标 c 传递到 swift viewcontroller。它非常有用。 使用UserDefaults 在对象之间传递数据是复杂的、晦涩的、难以记录的。请不要那样做。

以上是关于如何在使用桥接头时将数据(字典)从 Objective-C 控制器传递到 Swift `viewcontroller` 中?还有其他方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

Flurry 的正确桥接头是啥?

Flurry 的正确桥接头是啥?

桥接头方法参数问题

桥接头方法参数问题

如何将桥接头添加到 Flutter 插件

Swift 桥接头失败问题