将objective-c代码转换为swift 4

时间:2017-11-07 08:15:21

标签: ios objective-c swift

我已经用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'

1 个答案:

答案 0 :(得分:3)

不推荐从Objective-C到Swift的字面翻译,因为在很多情况下它没有利用Swift改进的语义。

当Apple从String删除所有路径操作API并向其他类添加了更多URL相关API时,请尽可能使用URL

let url = Bundle.main.url(forResource: "list", withExtension: "plist")!

强制解包的网址是安全的,因为文件必须在包中。崩溃将揭示设计错误,并且不得在运行时发生。

与Foundation集合类型不同,Swift集合类型不支持隐式属性列表转换,因此Swift方式是使用DataPropertyListSerialization

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 }) { ...