将objective-c代码转换为swift 4
Posted
技术标签:
【中文标题】将objective-c代码转换为swift 4【英文标题】:Converting objective-c codes to swift 4 【发布时间】:2017-11-07 08:15:20 【问题描述】:我已经用obj-c
写了 1.5 年了,它是一种很好的语言.. 所以我今天看到一篇关于 swift 的中型文章,真的很关注它,现在我正在尝试转换我所有的obj-c
代码swift
,幸运的是,这部分的一切都完成了..
NSString *path = [[NSBundle mainBundle] pathForResource:@"list" ofType:@"plist"];
NSArray *plistData = [NSArray arrayWithContentsOfFile:path];
NSPredicate *filter = [NSPredicate predicateWithFormat:@"english ==[c] %@", self.userQuery.text]; // something like "Abbey"
NSArray *filtered = [plistData filteredArrayUsingPredicate:filter];
NSLog(@"found matches: %@ : %@", filtered,[filtered valueForKey:@"kurdi"]);
if (filtered.count>0)
NSDictionary *dic = filtered[0];
self.theMeaningLabel.text = dic[@"kurdi"];
else
self.theMeaningLabel.text = @"Yay!";
我无法将其正确转换为新的swift 4
,它会产生随机错误
编辑
经过几次搜索,我可以只写两行代码 这是我的快速代码
var path: String? = Bundle.main.path(forResource: "list", ofType: "plist")
var plistData = [Any](contentsOfFile: path!)
var filter = NSPredicate(format: "english ==[c] %@", searchText)
// something like "Abbey"
var filtered = plistData?.filter filter.evaluate(with: $0)
print("found matches: \(filtered) : \(filtered?.value(forKey: "kurdi"))")
if filtered?.count > 0
var dic = filtered[0]
// theMeaningLabel.text = dic["kurdi"]
else
//theMeaningLabel.text = "Yay!"
但得到
参数标签 '(contentsOfFile:)' 不匹配任何可用的重载
最终编辑
var path = Bundle.main.path(forResource:"list", ofType: "plist")
var plistData = NSArray(contentsOfFile: path!)
let filter = NSPredicate(format: "english ==[c] %@", searchText)
var filtered = plistData?.filtered(using: filter)
// [error 9:10] no viable alternative at input 'NSLog(@"found matches: %@ : %@"'
if filtered?.count > 0
var dic = filtered![0]
// theMeaningLabel.text = dic["kurdi"]
else
// theMeaningLabel.text = "Yay!"
上面的代码没问题,但是出现了一个错误
if filtered?.count > 0 // here
var dic = filtered![0]
// theMeaningLabel.text = dic["kurdi"]
else
// theMeaningLabel.text = "Yay!"
得到
二元运算符“>”不能应用于“Int?”类型的操作数和“诠释”
【问题讨论】:
不要显示 Objective-C,显示 Swift 和你遇到的错误。 @Paulw11,我实在想不通,卡在谓词格式中,等待有人给出正确的干净代码 谓词格式完全相同,因为它是基础库的一部分,而不是 Swift 或 Objective-C。 How to use native Swift way to Read Plist in Swift 3?的可能重复 @VishalPatel,不要在没有真正阅读双方的情况下标记问题,你给出了错误的代码,我很感激,但这不是重复的,我自己解决了! 【参考方案1】:不推荐从 Objective-C 到 Swift 的直译,因为在许多情况下它没有利用 Swift 改进的语义。
由于 Apple 从 String
中删除了所有路径操作 API,并向其他类添加了更多与 URL
相关的 API,因此如果可能,请始终使用 URL
let url = Bundle.main.url(forResource: "list", withExtension: "plist")!
强制解包的 url 是安全的,因为文件必须在包中。崩溃将揭示设计错误,并且不得在运行时发生。
与 Foundation 集合类型不同,Swift 集合类型不支持隐式属性列表转换,因此 Swift 方法是使用 Data
和 PropertyListSerialization
let data = try! Data(contentsOf: url)
let dataArray = try! PropertyListSerialization.propertyList(from: data, format: nil) as! [Any]
出于同样的原因,强制try!
与强制解包url
一样安全。
[Any]
是最未指定的 Swift 数组。如果该数组应该是一个字典数组,则写入[[String:Any]]
,如果所有值都是String
,则甚至写入[[String: String]]
。如果它应该是一个字符串数组,请写[String]
。 Swift 鼓励开发人员尽可能地指定类型。
NSPredicate
可以替换为 Swift 中的 filter
函数。例如,可以使用
let filtered = dataArray.filter $0.compare(searchText, options:.caseInsensitive) == .orderedSame
如果数组包含字典,则需要指定键(同NSPredicate)
let filtered = dataArray.filter ($0["foo"] as! String).compare(searchText, options:.caseInsensitive) == .orderedSame
最后是 ObjC 表达式
if (filtered.count > 0) ...
在 Swift 中可以写得更具描述性
if filtered.isEmpty == false ...
或
if !filtered.isEmpty ...
如果你只寻找一个项目,你甚至可以写
if let foundObject = dataArray.first(where: $0.compare(searchText, options:.caseInsensitive) == .orderedSame ) ...
【讨论】:
上次我遇到了 obj-c 的问题,你帮忙了,再说一次,sof 需要更多像你这样的人以上是关于将objective-c代码转换为swift 4的主要内容,如果未能解决你的问题,请参考以下文章
将 PinchRecognizer Objective-C 代码转换为 Swift
将 NSData Objective-C 代码转换为 Swift 时遇到问题
将代码从 Objective-C 转换为 Swift 后测试用例失败