我已经用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?'的操作数。和' Int'
答案 0 :(得分:3)
不推荐从Objective-C到Swift的字面翻译,因为在很多情况下它没有利用Swift改进的语义。
当Apple从String
删除所有路径操作API并向其他类添加了更多URL
相关API时,请尽可能使用URL
let url = Bundle.main.url(forResource: "list", withExtension: "plist")!
强制解包的网址是安全的,因为文件必须在包中。崩溃将揭示设计错误,并且不得在运行时发生。
与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 }) { ...