本文为『移动前线』群在 4 月 28 日的分享总结整理而成,转载请注明来自『移动开发前线』公众号。
嘉宾介绍
张西涛,架构师,全栈工程师。9 年 IT 行业工作经验,熟悉 Java、Android、JavaScript、Python、Swift 等技术,2014 年开始关注 Swift iOS 开发,最近在专注研究 Swift。目前担任千米网(专业电商 SaaS 平台)移动端架构师。技术博客是 http://offbye.com。
我从 2009 年开始做 Android 开发,开始接触 Swift 是在 2014 年底,当时组里曾经做过一个 Demo App,感觉技术还不够成熟没有正式发布。2016 年初我们正式使用 swift 开发上线了销售助手 App 产品,积累了比较丰富的 swift 项目实战经验,开源框架都是用的 swift 版本,大量使用了面向协议和函数式编程。iOS App 开发人员基本都是以前安卓版本的开发人员,同时维护安卓和 iOS 2 个版本,效率很高。 今天分享的主题是 Java/Android 开发人员如何快速上手 Swift iOS 开发。主要内容如下:
- Why From Java/Android to Swift
- Swift 语言为什么值得学习?
- Java vs Swift 语法比较
- Android 和 iOS UI 开发比较
- Android vs Swift iOS 框架比较
- 开发工具比较
Why From Java/Android to Swift
成本和效率方面,由于目前同业务的 Android 和 iOS App 产品功能一致,由一个团队开发可以降低业务同步和沟通成本,避免安卓和 iOS 两个团队带来的产品功能差异和沟通成本。
Swift 语法更接近 Java,相对 Objective C 上手容易,我 2012 年曾经带过 iOS 项目,学过 oc,因为无法忍受 oc 奇怪的语法最后放弃了,但这次学习 swift iOS 过程还是挺顺畅的,学习的主要门槛反而是 Xcode IB 的使用。
Why not React Native?
React Native 我们也要项目在用。但 RN 思想和语法的学习曲线有些陡,很多有 Web 开发经验的人都不一定喜欢。另外很多安卓开发者并没有学习过 js,学习 React Native 成本会比较高。学习 React Native 最终还是要对原生开发有一定的了解。最后,在一些功能复杂的 App,React Native 用户体验比不上原生 。
Why not HTML5 Hybrid App?
用户体验不够好,对于不熟悉 Web 开发的工程师学习成本比较高。
以前我们用 ionic 做过混合 App,在 iOS 上效果可以,但安卓低端机上比较卡,影响体验。
我们现在也有 App 是 React Native 做的,大概是去年 11 月上线的,用户体验还不错,但开发人员基本上是以前的前端开发。
Swift 语言为什么值得学习?
Swift 是现在 Apple 主推的语言,2014 年新推出的语言,比 Scala 等“新”语言还要年轻 10 岁。2015 年秋已经开源。目前在 linux 上可用,最近已经支持 Android NDK;在树莓派上有 SwiftyGPIO 库,可以通过 GPIO 控制一些硬件。 Object C is old and ugly,oc 是 1983 年苹果推出的,过于陈旧和臃肿。
Swift 语法类似 Scala,Javascript ES6, Java,OC, C++, Python, 这个我是按照语法相似度排序的。
(Redmonk 和 TIOBE 的语言排行榜,Swift 都榜上有名)
Swift 比 Scala、Clojure 等语言还有年轻很多年。
Swift 支持多范式编程:面向协议,面向对象和函数式编程。最后,我们还可以通过 Swift 学习函数式编程思想,这块 Java8 才支持。
Java vs. Swift 语法比较
基础语法
Swift 的 switch 语法和 Java 及 C++ 很像,但是它没有 break,他命中一个 case 后会自动退出 switch。对于几个不同 case 同样处理的情况,可以 case 后面连续几个 condition,用逗号隔开。
for 循环和 Java 也基本一样,不过也是不需要括号。for 循环中,…< 的用法比较方便。下划线符号 _(替代循环中的变量)能够忽略具体的值,并且不提供循环遍历时对值的访问。for-in 则有点类似与 Java 中 for each 循环。
Swift 2.2 中 try catch 和 do while 和 java 差异很大。
函数和闭包
Swift 函数的定义和 Java 很不一样,Swift 函数的定义形如 func foo(arg: Type) -> Return Type:
- Swift 中函数是一等公民,可以作为返回值和参数;Swift 支持闭包,Java8 才支持 lambda 闭包。
- Swift 支持元组,Swift 函数可以通过返回元组支持多个返回值。
- Swift 函数可以嵌套,即一个函数内部还可以定义函数,Java 不支持。
- Swift 函数可以接收不定参数,跟 Java 基本类似。
- Swift 函数参数可以带默认值,和 Python 类似,Java 函数不可以带有默认值。
常用的函数式编程方法 map,reduce, flatMap,filter,sort,相对于理解抽象的函数式编程概念,我觉得开始时先用好这些函数更重要。
struct vs. class
struct 是值类,class 是引用类型,Java 语言没有 struct,但 c/c++/c#语言都有,但不能带方法。
Swift 开发推荐使用 struct,而不是 class。Swift 语言实现包括几百个 struct,只有几个 class。
Swift 类构造方法是 init(),析构方法是 deinit(),类方法调用跟 Java 基本一样。
self 相当于 Java 中的 this,传入生命周期不一致的闭包时需要声明为 weak。
Enum 枚举
Android 开发谷歌官方不建议使用 Enum,影响性能。
Swift 的 Enum 和 Java 类似,本质是一个类,里面可以包含函数。
Swift Enum 语法更简单。
Swift Enum 支持扩展 extension。
Interface vs. Protocol
Extension 扩展就是向一个已有的类、结构体或枚举类型添加新功能(functionality)。这包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模)。扩展和 Objective-C 中的分类(categories)类似。
Swift 中的扩展可以:
- 添加计算型属性和计算静态属性
- 定义实例方法和类型方法
- 提供新的构造器
- 定义下标
- 定义和使用新的嵌套类型
- 使一个已有类型符合某个接口
Swift 中的扩展很强大,struct class enum 都可以,也可以扩展系统的类。需要注意的是扩展方法的作用域问题,这里不展开讨论。
MultiThread 多线程
iOS 的多线程相对 Java 来说比较简单,GCD 一天时间基本就能够弄明白。Java 的 Concurrency 包就比较复杂了。
Android,iOS UI 开发比较
iOS 开发苹果官方建议使用 Storyboard 开发 UI,好处是比较直观,通过看界面可以更好的理解和维护 App。现在 Xcode7 版本对 AutoLayout 和 SizeClasses 的支持越来越好,多分辨率适配变得简单,建议大家放弃使用 frame 代码写界面的传统做法。
当然,Storyboard 也有下面的弊端:
界面主要依靠 IB 生成,Xib 代码难以维护,Xcode 打开 Storyboard 或 Xib 就会对文件产生修改,即使我们没有做实际的修改,git 也会显示文件修改了。
多人协助,同时修改导致冲突,合并困难。
Storyboard 中包含页面多了后会占用了太多内存,导致 Xcode 卡顿和崩溃。
错误定位困难,错误提示不清晰,新手难以定位错误。例如不小心删掉了 IBOutlet 会很难定位。
Storyboard UI 开发实践
按照业务模块分成多个 Storyboard,每人负责的模块避免交叉。
每个 storyboard 不要超过 10 个页面,可以通过 Refactor Storyboard 功能重新划分。
用 Container 在一个 storyboard 复用 UI 模块,用 xib 在多个 storyboard 复用 UI 模块。
复杂的输入表单,建议用 SwiftyForm 框架写代码。
使用 Size Classes 做多分辨率适配比较轻松。
Android vs Swift iOS 框架比较
Swift 框架现在已经很多了,Swift 也可以使用 OC 开源框架,但不推荐使用。我们主要对比介绍项目常用的网络请求框架,JSON 解析和图片缓存框架。
在 Android 开发现在一般使用 OKHTTP,Retrofit 和 Volley 等网络框架进行开发,iOS 开发 oc 时代使用 AFNetworking 库开发,swift 开发推荐使用 Alamofire 和 Moya 库。
Moya 对 Alamofire 网络请求库进行了封装,开发不需要写网络模型,管理等。使代码更加简洁。Moya 可以代替自己编写的网络抽象层 APIManager。Moya 提供了一些很好的特性:
- 编译期检查 API 接口调用的正确性
- 通过 enum 枚举类型清晰的定义不同 API 的接口
- 把接口测试 stub 作为一等公民,让单元测试变得很简单。
- 支持 ReactiveX 扩展,方便和 RxSwift 集成。
- Moya 比 Android Retrofit 多了模拟数据调试的功能。
目前 App 基本都是使用 JSON 作为报文协议,Android 开发我们一般使用 Gson 进行解析,在 Swift 开发中,对比了 ObjectMapper,Argo+Curry,SwiftyJson 后,我们决定使用 ObjectMapper 作为 JSON 解析框架。ObjectMapper 支持的特性如下:
- 支持把对象转换成 JSON,把 JSON 转换成类对象
- 支持嵌套的对象(单一对象,对象列表集合和字典)
- 支持自定义的转换函数
- 支持结构体 struct
- 支持 Realm 和 Alamofire 集成,AlamofireObjectMapper
Realm 是 iOS 开发比较流行的针对移动端设计的数据库,代替 sqlite,也有 Android 版本。
使用例子:
let user = Mapper
let JSONString = Mapper().toJSONString(user, prettyPrint: true)
Realm 是 iOS 开发比较流行的针对移动端设计的数据库,代替 sqlite,也有 Android 版本。
图片缓存框架,Android 开发常用 Glide 和 Fresco,OC 开发一般用 SDWebImage,Swift 开发推荐用 HanekeSwift.
开发工具比较
Android 目前主流的开发工具是 Android Studio,2014 年以前是 Eclipse ADT。
iOS 开发一直使用 Xcode。对于 Java/Android 开发人员来说,Xcode 上手较难,特别是 Interface Builder,Xib 和视图代码直接通过连线来生成事件方法,比较挑战开发习惯,并且出现问题定位困难。而 Android 开发者习惯手写 xml 界面代码。
与 Android Studio 相比,Xcode 速度快,但不够稳定,一天崩溃几次很正常。
模拟器方面,Android 的 Emulator 是虚拟机,启动和安装速度比较慢,iOS 是 Simulator,速度快,但有些功能不能模拟。都推荐使用真机进行开发。
包管理器 & 构建工具对比
Android 开发早期用 Ant 做一些任务处理,后面有些团队借鉴 Java EE 项目的做法用 Maven,Android Studio 出现后谷歌推荐用 Gradle。Android 的构建工具比 iOS 功能要强大很多。
iOS 开发早期用 CocoaPods,现在推荐用 Carthage,未来 Apple 官方推出 Swift 3.0 后会推广官方的 Swift Package Manager。
Carthage 好处是比较简洁,坏处是有些框架还不支持,特别是国内 BAT 的一些开源库。
最后介绍下 Xcode 包管理器 Alcatraz,主要提供 Xcode 插件,模板和色彩模式,相比 Android Studio,目前插件还很比较少。
感谢徐川对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论