关于xCode6.3与swift1.2的初体验

今天,AppStore更新了XCode6.3,从beta版本到现在刚好2个月的时间。上一次的6.3beta更新对swift语法来说是一个重大的更新,现在AppStroe正式上线XCode6.3也看到了苹果推广swfit的决心。
在6.3中修改项目中了swift的单文件,不再对所有文件重新编译,增快了编译速度,对于习惯了修改一个空格然后等编译一分钟的swift开发者来说,简直是一个天大的喜讯!!

这篇博文讲述的内容

  • 如何将swift项目语法从swift1.1转到1.2以及一些坑
  • Swift1.2中NSString与String相互转换的坑
  • swift1.2新语法及在实际开发中的应用

swift项目的语法更新

  • 打开XCode,在菜单中选择Edit->Convert->To Latest Swift Syntax,如下图所示:
    语法转换操作步骤

  • 然后选择你要转换语法的工程项,例如我要转这个,点击Next:
    选择语法转换的项目

  • 然后等了一段时间会变成这样子,然后点击save就可以完成修改了:
    选择并且保存修改后的语法

1.不过这里有几个坑,我的项目里面第一次转换20多个文件,成功保存后Build之后还是有好几个错,然后尝试手动去改,再Build还是有几个错,然后只好再用抓换工具去修改,最终一共重复操作转换功能了大概7次左右才能完全把项目中的代码完全转换成功。所以直接一直操作转换工具知道没有没有语法错误就可以了,主要语法出错还是as!下转操作符。

2.NSString与String在swift1.2中不再相互替用了,转换器没法转换这个类型转换的错误,在项目中用到大量NSString的朋友就要花不少时间去手动改了,一般把NSStrng改成swift提倡使用的String,或者强转成String就可以了

Swift1.2中NSString与String相互转换的坑

  • 在以往的Objc项目中,有一些Objc算法代码,可以把算法文件抽出,通过搭桥,在swift项目中用swift的语法来调用来Objc的代码。在我的项目中有以下方法:
    Objc中的定义

  • 在swift1.2之前,传进去的参数可以是NSString,String,返回值可以用NSString,String来接,在今天的测试中发现,自己写的方法也会这样(以前可以混用没测试过,一直以为只有系统API与NSString相关的都变成String!,自己的写的不会自动把NSString转成String!,如果错了请指出):
    swift1.2语法通过搭桥调用Objc写的方法

注意参数和返回值都是String!类型,在传参的时候记得不要把Optional值传进去,不然一直有莫名其妙的报错,如果不怕崩溃,也可以直接把Optional变量force-unwrap后传进去

swift1.2新语法在实际开发中的应用(参考了这篇,还有这篇文章)

  • 可选绑定(Optional Binding)的改动
    在swift1.2中,可选绑定可以同时进行,它给我们避免了各种lf-let嵌套使用在swift1.2以前,我们需要这样用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    let a = "10".toInt()
    let b = "5".toInt()
    let c = "3".toInt()

    if let a = a {
    if let b = b {
    if let c = c {
    if c != 0 {
    println("(a + b) / c = \((a + b) / c)")
    }
    }
    }
    }

    在swift1.2中我们这样用:

    1
    2
    3
    if let a = a, b = b, c = c where c != 0 {
    println("(a + b) / c = \((a + b) / c)") // (a + b) / c = 5
    }
  • 这个改动在实际中获取数据,解释数据,尤其在网络请求中,大大简化了代码:
    在一个网络请求中返回了一个AnyObject?类型的JSON对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    if let json = JSON as? [String:AnyObject] {
    if (json["code"] as! Int) == 0 {
    //code = 0 网络请求成功并且返回数据成功
    }else{
    //code != 0 网络请求成功但由于某种原因没成功返回数据
    }
    }else{
    //网络状态不佳或者服务器不能访问导致请求失败返回的数据为nil
    }

    在只需要获取网络状态成功获取数据成功的情况下,我们可以这样写:

    1
    2
    3
    if let json = JSON as? [String:AnyObject] where (json["code"] as! Int) == 0 {
    //code = 0 网络请求成功并且返回数据成功
    }
  • 这篇博文中中提到了这样的一种写法去解释JSON,分享一下其详细代码:
    个人感觉这样的写法非常清晰明了,以后应该会大派用场

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     var users: [User] = []

    // load and parse the JSON into an array
    if let
    path = NSBundle.mainBundle().pathForResource("users", ofType: "json"),
    url = NSURL(fileURLWithPath: path),
    data = NSData(contentsOfURL: url),
    userList = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as? [[String: AnyObject]]
    {
    // extract individual users
    for userDict in userList {
    if let
    id = userDict["id"] as? Int,
    name = userDict["name"] as? String,
    email = userDict["email"] as? String,
    address = userDict["address"] as? [String: AnyObject]
    {
    users.append(User(id: id, name: name, ...))
    }
    }
    }

我没法解决的一个问题是,如果在if-let多可选绑定里面,我要对其中的某个几if-let的else要进行处理,我暂时只能按原来的嵌套写法来写了。如果有在多可选绑定if-let里面进行某几个else的单独处理的好方法,请在评论中告诉我,虚心请教

小结

第一次为一个语言和一个编译器的更新而感到兴奋,因为项目在迟迟没有更新6.3beta,今天AppStore上线了6.3终于下了决心下了下来并更新项目的语法。6.3在无论在Objc上的语法更新还是在swift语法上的更新,都是为了支持swift的发展,估计swift的春天快要到了。