從Java/Android到Swift iOS開(kāi)發(fā):語(yǔ)言與框架對(duì)比

本文是我在『移動(dòng)前線』微信群2016年4月28日的分享總結(jié)整理。
我從2009年開(kāi)始做Android開(kāi)發(fā),開(kāi)始接觸Swift是在2014年底,當(dāng)時(shí)組里曾經(jīng)做過(guò)一個(gè)Demo App,感覺(jué)技術(shù)還不夠成熟沒(méi)有正式發(fā)布。2016年初我們正式使用swift開(kāi)發(fā)上線了銷(xiāo)售助手App產(chǎn)品,積累了比較豐富的swift項(xiàng)目實(shí)戰(zhàn)經(jīng)驗(yàn),開(kāi)源框架都是用的swift版本,大量使用了面向協(xié)議和函數(shù)式編程。iOS App開(kāi)發(fā)人員基本都是以前安卓版本的開(kāi)發(fā)人員,同時(shí)維護(hù)安卓和iOS 2個(gè)版本,效率很高。
今天分享的主題是Java/Android開(kāi)發(fā)人員如何快速上手Swift iOS開(kāi)發(fā)。主要內(nèi)容如下:

  1. WhyFrom Java/Android to Swift
  2. Swift語(yǔ)言為什么值得學(xué)習(xí)?
  3. Javavs Swift語(yǔ)法比較
  4. Android和iOS UI開(kāi)發(fā)比較
  5. Androidvs Swift iOS框架比較
  6. 開(kāi)發(fā)工具比較

1、Why FromJava/Android to Swift

成本和效率

由于目前同業(yè)務(wù)的Android和iOS App產(chǎn)品功能一致,由一個(gè)團(tuán)隊(duì)開(kāi)發(fā)可以降低業(yè)務(wù)同步和溝通成本,避免安卓和iOS兩個(gè)團(tuán)隊(duì)帶來(lái)的產(chǎn)品功能差異和溝通成本。

Swift語(yǔ)法更接近Java,相對(duì)Objective C上手容易,我2012年曾經(jīng)帶過(guò)iOS項(xiàng)目,學(xué)過(guò)oc,因?yàn)闊o(wú)法忍受oc奇怪的語(yǔ)法最后放棄了,但這次學(xué)習(xí)swift iOS過(guò)程還是挺順暢的,學(xué)習(xí)的主要門(mén)檻反而是Xcode IB的使用。

Why not React Native?

ReactNative我們也要項(xiàng)目在用。但RN思想和語(yǔ)法的學(xué)習(xí)曲線有些陡,很多有Web開(kāi)發(fā)經(jīng)驗(yàn)的人都不一定喜歡。另外很多安卓開(kāi)發(fā)者并沒(méi)有學(xué)習(xí)過(guò)js,學(xué)習(xí)React Native成本會(huì)比較高。學(xué)習(xí)React Native最終還是要對(duì)原生開(kāi)發(fā)有一定的了解。最后,在一些功能復(fù)雜的App,React Native用戶(hù)體驗(yàn)比不上原生 。

Why not HTML5 Hybrid App?

用戶(hù)體驗(yàn)不夠好,對(duì)于不熟悉Web開(kāi)發(fā)的工程師學(xué)習(xí)成本比較高。
2014年我們用ionic框架做過(guò)混合App,在iOS上效果可以,但在安卓低端機(jī)上比較卡,影響用戶(hù)體驗(yàn)。

2、Swift語(yǔ)言為什么值得學(xué)習(xí)?

Swift是現(xiàn)在Apple主推的語(yǔ)言,2014年新推出的語(yǔ)言,比Scala等“新”語(yǔ)言還要年輕10歲。2015年秋已經(jīng)開(kāi)源。目前在linux上可用,最近已經(jīng)支持Android NDK;在樹(shù)莓派上有SwiftyGPIO庫(kù),可以通過(guò)GPIO控制一些硬件。
ObjectC is old and ugly,oc是1983年蘋(píng)果推出的,過(guò)于陳舊和臃腫。
Swift語(yǔ)法類(lèi)似Scala,Javascript ES6, Java,OC, C++, Python,這個(gè)我是按照語(yǔ)法相似度排序的。
Swift支持多范式編程:面向協(xié)議,面向?qū)ο蠛秃瘮?shù)式編程 。
最后,我們還可以通過(guò)Swift學(xué)習(xí)函數(shù)式編程思想,這塊Java8才支持。

3、Java vs. Swift語(yǔ)法比較

  • 基礎(chǔ)語(yǔ)法
  • 函數(shù)
  • struct和class
  • Enum
  • Interface vsProtocol
  • MultiThread

3.1基礎(chǔ)語(yǔ)法

Java Swift
static final 常量 var 變量,let常量
Java語(yǔ)言沒(méi)有,Guava庫(kù)提供 可選型Optional,通過(guò)if let解包
Java支持自增++,自減— Swift不建議使用,3.0版本將不支持自增
邏輯控制和C基本一致 邏輯控制語(yǔ)句更現(xiàn)代
Java有main方法 Swift沒(méi)有main方法
Java需要;做行結(jié)束符 Swift不需要行結(jié)束符

Swift的switch 語(yǔ)法和Java及C++很像,但是它沒(méi)有break,他命中一個(gè)case后會(huì)自動(dòng)退出switch。對(duì)于幾個(gè)不同case同樣處理的情況,可以case后面連續(xù)幾個(gè)condition,用逗號(hào)隔開(kāi)。
for循環(huán)和Java也基本一樣,不過(guò)也是不需要括號(hào)。for循環(huán)中,..<的用法比較方便。下劃線符號(hào)_(替代循環(huán)中的變量)能夠忽略具體的值,并且不提供循環(huán)遍歷時(shí)對(duì)值的訪問(wèn)。for-in則有點(diǎn)類(lèi)似與Java中for each循環(huán)。
Swift 2.2中trycatch和do while和java差異很大

3.2 函數(shù)和閉包

Swift函數(shù)的定義和Java很不一樣,Swift函數(shù)的定義形如 func foo(arg: Type) ->Return Type:
Swift中函數(shù)是一等公民,可以作為返回值和參數(shù);Swift支持閉包,Java8才支持lambda閉包。
Swift支持元組,Swift函數(shù)可以通過(guò)返回元組支持多個(gè)返回值。
Swift函數(shù)可以嵌套,即一個(gè)函數(shù)內(nèi)部還可以定義函數(shù),Java不支持。
Swift函數(shù)可以接收不定參數(shù),跟Java基本類(lèi)似
Swift函數(shù)參數(shù)可以帶默認(rèn)值,和Python類(lèi)似,Java函數(shù)不可以帶有默認(rèn)值。
常用的函數(shù)式編程方法map,reduce, flatMap,filter,sort,相對(duì)于理解抽象的函數(shù)式編程概念,我覺(jué)得開(kāi)始時(shí)先用好這些函數(shù)更重要。

3.3 struct vs. class

struct是值類(lèi),class是引用類(lèi)型,Java語(yǔ)言沒(méi)有struct,但c/c++/c#語(yǔ)言都有。
Swift開(kāi)發(fā)推薦使用struct,而不是class。Swift語(yǔ)言實(shí)現(xiàn)包括幾百個(gè)struct,只有幾個(gè)class。
Swift類(lèi)構(gòu)造方法是init(),析構(gòu)方法是deinit(),類(lèi)方法調(diào)用跟Java基本一樣。
self相當(dāng)于Java中的this,傳入生命周期不一致的閉包時(shí)需要聲明為weak。

3.4 Enum枚舉

Android開(kāi)發(fā)谷歌官方不建議使用Enum,影響性能。
Swift的Enum和Java類(lèi)似,本質(zhì)是一個(gè)類(lèi),里面可以包含函數(shù)。
SwiftEnum語(yǔ)法更簡(jiǎn)單。
SwiftEnum支持?jǐn)U展extension。

3.5 Interface vs. Protocol

**Java Interface ** Swift Protocol
可以繼承 可以繼承
Interface不能帶有具體實(shí)現(xiàn)的方法,Java8以后才可以 protocol可以帶有具體實(shí)現(xiàn)的方法
implements extension更強(qiáng)大

Extension擴(kuò)展就是向一個(gè)已有的類(lèi)、結(jié)構(gòu)體或枚舉類(lèi)型添加新功能(functionality)。這包括在沒(méi)有權(quán)限獲取原始源代碼的情況下擴(kuò)展類(lèi)型的能力(即逆向建模)。擴(kuò)展和 Objective-C 中的分類(lèi)(categories)類(lèi)似。
Swift 中的擴(kuò)展可以:

  • 添加計(jì)算型屬性和計(jì)算靜態(tài)屬性
  • 定義實(shí)例方法和類(lèi)型方法
  • 提供新的構(gòu)造器
  • 定義下標(biāo)
  • 定義和使用新的嵌套類(lèi)型
  • 使一個(gè)已有類(lèi)型符合某個(gè)接口
    需要注意的是擴(kuò)展方法的作用域問(wèn)題,這里不展開(kāi)討論。

3.6 MultiThread多線程

Java Android Swift iOS
Thread,Runnable NSThread
Java 5 Concurrency包 GCD
Android多線程擴(kuò)展 NSOperation,NSOperationQueue
AsyncTask,Looper,HandleThread,IntentService…

iOS的多線程相對(duì)Java來(lái)說(shuō)比較簡(jiǎn)單,GCD一天時(shí)間基本就能夠弄明白。Java的Concurrency包就比較復(fù)雜了。

4、Android,iOS UI開(kāi)發(fā)比較

Java Android Swift iOS
Xml layout布局 Xib & StoryBoard
直接寫(xiě)xml代碼,可視化輔助開(kāi)發(fā) AutoLayout和SizeClass,IB自動(dòng)生成,代碼合并困難;
Android可以用Java添加和實(shí)現(xiàn)view 很多團(tuán)隊(duì)只好用代碼實(shí)現(xiàn)UI界面
Intent頁(yè)面跳轉(zhuǎn) Segue連線跳轉(zhuǎn)
Java自定義view,可以在Activity和layout中使用,可視化支持不夠好 自定義View可以使用IBDesignable & runtime attributes

iOS開(kāi)發(fā)蘋(píng)果官方建議使用Storyboard開(kāi)發(fā)UI,好處是比較直觀,通過(guò)看界面可以更好的理解和維護(hù)App?,F(xiàn)在Xcode7版本對(duì)AutoLayout和SizeClasses的支持越來(lái)越好,多分辨率適配變得簡(jiǎn)單,建議大家放棄使用frame代碼寫(xiě)界面的傳統(tǒng)做法。
當(dāng)然,Storyboard也有下面的弊端:
界面主要依靠IB生成,Xib代碼難以維護(hù),Xcode打開(kāi)Storyboard或Xib就會(huì)對(duì)文件產(chǎn)生修改,即使我們沒(méi)有做實(shí)際的修改,git也會(huì)顯示文件修改了。
多人協(xié)助,同時(shí)修改導(dǎo)致沖突,合并困難。
Storyboard中包含頁(yè)面多了后會(huì)占用了太多內(nèi)存,導(dǎo)致Xcode卡頓和崩潰。
錯(cuò)誤定位困難,錯(cuò)誤提示不清晰,新手難以定位錯(cuò)誤。例如不小心刪掉了IBOutlet會(huì)很難定位。

Storyboard UI 開(kāi)發(fā)實(shí)踐

按照業(yè)務(wù)模塊分成多個(gè)Storyboard,每人負(fù)責(zé)的模塊避免交叉。
每個(gè)storyboard不要超過(guò)10個(gè)頁(yè)面,可以通過(guò)Refactor Storyboard功能重新劃分。
用Container在一個(gè)storyboard復(fù)用UI模塊,用xib在多個(gè)storyboard復(fù)用UI模塊。
復(fù)雜的輸入表單,建議用SwiftyForm框架寫(xiě)代碼。

5、Android vs Swift iOS框架比較

Swift框架現(xiàn)在已經(jīng)很多了,Swift也可以使用OC開(kāi)源框架,但不推薦使用。我們主要對(duì)比介紹項(xiàng)目常用的網(wǎng)絡(luò)請(qǐng)求框架,JSON解析和圖片緩存框架

網(wǎng)絡(luò)請(qǐng)求框架

Java Android Swift iOS
Retrofit Moya
OKHTTP Alamofire
Volley AFNetworking
Retrofit + RxAndroid Moya + RxSwift

在Android開(kāi)發(fā)現(xiàn)在一般使用OKHTTP,Retrofit和Volley等網(wǎng)絡(luò)框架進(jìn)行開(kāi)發(fā),iOS開(kāi)發(fā)oc時(shí)代使用AFNetworking庫(kù)開(kāi)發(fā),swift開(kāi)發(fā)推薦使用Alamofire和Moya庫(kù)。
Moya 對(duì)Alamofire網(wǎng)絡(luò)請(qǐng)求庫(kù)進(jìn)行了封裝,開(kāi)發(fā)不需要寫(xiě)網(wǎng)絡(luò)模型,管理等。使代碼更加簡(jiǎn)潔。Moya可以代替自己編寫(xiě)的網(wǎng)絡(luò)抽象層APIManager。Moya提供了一些很好的特性:
編譯期檢查API接口調(diào)用的正確性
通過(guò)enum枚舉類(lèi)型清晰的定義不同API的接口
把接口測(cè)試stub作為一等公民,讓單元測(cè)試變得很簡(jiǎn)單。
支持ReactiveX擴(kuò)展,方便和RxSwift集成。

目前App基本都是使用JSON作為報(bào)文協(xié)議,Android開(kāi)發(fā)我們一般使用Gson進(jìn)行解析,在Swift開(kāi)發(fā)中,對(duì)比了ObjectMapper,Argo+Curry,SwiftyJson后,我們* 決定使用ObjectMapper作為JSON解析框架。ObjectMapper支持的特性如下:

  • 支持把對(duì)象轉(zhuǎn)換成JSON,把JSON轉(zhuǎn)換成類(lèi)對(duì)象
  • 支持嵌套的對(duì)象(單一對(duì)象,對(duì)象列表集合和字典)
  • 支持自定義的轉(zhuǎn)換函數(shù)
  • 支持結(jié)構(gòu)體struct
  • 支持Realm和Alamofire集成,AlamofireObjectMapper
    使用例子:
let user = Mapper<User>().map(JSONString)
let JSONString = Mapper().toJSONString(user, prettyPrint: true)

Realm是iOS開(kāi)發(fā)比較流行的針對(duì)移動(dòng)端設(shè)計(jì)的數(shù)據(jù)庫(kù),代替sqlite,也有Android版本
圖片緩存框架,Android開(kāi)發(fā)常用Glide和Fresco,OC開(kāi)發(fā)一般用SDWebImage,Swift開(kāi)發(fā)推薦用HanekeSwift。

6、開(kāi)發(fā)工具比較

Android目前主流的開(kāi)發(fā)工具是Android Studio,2014年以前是Eclipse ADT。

iOS開(kāi)發(fā)一直使用Xcode。對(duì)于Java/Android開(kāi)發(fā)人員來(lái)說(shuō),Xcode上手較難,特別是Interface Builder,Xib和視圖代碼直接通過(guò)連線來(lái)生成事件方法,比較挑戰(zhàn)開(kāi)發(fā)習(xí)慣,并且出現(xiàn)問(wèn)題定位困難。而Android開(kāi)發(fā)者習(xí)慣手寫(xiě)xml界面代碼。

與Android Studio相比,Xcode速度快,但不夠穩(wěn)定,一天崩潰幾次很正常。

模擬器方面,Android的Emulator是虛擬機(jī),啟動(dòng)和安裝速度比較慢,iOS是Simulator,速度快,但有些功能不能模擬。都推薦使用真機(jī)進(jìn)行開(kāi)發(fā)。

包管理器&構(gòu)建工具對(duì)比

Android開(kāi)發(fā)早期用Ant做一些任務(wù)處理,后面有些團(tuán)隊(duì)借鑒Java EE項(xiàng)目的做法用Maven,AndroidStudio出現(xiàn)后谷歌推薦用Gradle。Android的構(gòu)建工具比iOS功能要強(qiáng)大很多。
iOS開(kāi)發(fā)早期用CocoaPods,現(xiàn)在推薦用Carthage,未來(lái)Apple官方推出Swift3.0后會(huì)推廣官方的Swift Package Manager。
最后介紹下Xcode包管理器Alcatraz,主要提供Xcode插件,模板和色彩模式,相比Android Studio,目前插件還很比較少。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,063評(píng)論 25 709
  • 就你
    溜溜白閱讀 193評(píng)論 0 0
  • 飛機(jī)上免費(fèi)提供飲料這是盡人皆知的,但你不知道的是當(dāng)你選不同飲料的時(shí)候給人的感覺(jué)是不一樣的。好好回想下,有沒(méi)有感覺(jué)只...
    趙蓮貴閱讀 1,037評(píng)論 1 1

友情鏈接更多精彩內(nèi)容