虛擬機里安裝OSX+XCode開發環境
用真機的請直接跳過這個部分。
主要是在VitrualBox里安裝mac系統和xcode,參考這篇教程,VirtualBox的版本是4.3.18 r96156,OSX版本是10.11 El Capitan,XCode版本是7.1 (7B91b)。
經過幾天的初步使用,感覺用虛擬機開發iOS基本能夠滿足要求,i5/8g/ssd的配置目測能達到真機70%的開發效率。主要存在的問題是:1)在寬屏上無法滿屏,兩邊會留有黑框,導致鼠標無法順利停靠在兩側 2)鍵盤敲擊頻率過快(約5Hz)時字符亂序出現在編輯器里,例如快速輸入“update”可能會得到“updaet” 3)虛擬機里的時鍾有可能不准,開發過程中偶爾有問題與此相關,需要考慮在內。
調整分辨率
以管理員方式啟動virtualbox和cmd命令行(重要!),執行下面的命令
cd "C:\Program Files\Oracle\VirtualBox"
VBoxManage setextradata "OSXElCapitan" VBoxInternal2/EfiGopMode 3 (注意,參數值 0=640×480, 1=800×600, 2=1024×768, 3=1280×1024, 4=1440×900, 5=1920×1200)
VBoxManage setextradata "OSXElCapitan" "CustomVideoMode1" "1360x768x32" (必須8的整數倍,我這里沒有成功)
參考鏈接:How to Guide for Mavericks VM on Mavericks
通過Virtualbox的遠程桌面連接到虛擬機
如果是NAT方式,目標地址是127.0.0.2,用guest里通過ifconfig查看到的10.0.2.xx是不行的。 遠程桌面的方式比直接使用虛擬機卡不少,作為開發使用並不實用。
修飾鍵
蘋果鍵盤與Windows鍵盤幾個修飾鍵的對應關系如下(在設置里可以改,這里是缺省情況):
Command鍵(花鍵 ⌘):對應windows鍵
Control鍵(⌃):對應ctrl鍵
Shift鍵(⇧):對應shift鍵
Option鍵(⌥):對應alt鍵
兩種鍵盤上這幾個修飾鍵物理布局最大的區別,在於Command鍵與Option鍵位置相反,可以去“偏好設置->鍵盤”里改過來,這樣切換兩種鍵盤時就比較容易適應了。
OSX
常用快捷鍵
跳到行首:“Command+左鍵”(Home鍵是跳到頁首)
結束任務:Command+Option+Esc
XCode7快捷鍵
代碼輔助:control+.
打開/關閉左側Navigator邊欄:Command+0(數字0)
打開/關閉右側Utilities邊欄:Option+Command+0(數字0)
快速打開文件(Open Quickly):Shift+Command+O(字母O)
轉到定義(Go to Definition):Command+鼠標點擊,或Option+Command+J
自動格式化代碼:Control+I(需要先全選,否則只格式化當前行)
調整模擬器大小:Command+3(50%)
Swift2
一些教程
官網:swift.org
官方文檔:The Swift Programming Language, 中文版
斯坦福免費視頻公開課:Developing iOS 8 Apps with Swift,中文翻譯
國內視頻教程:精通iOS移動開發(Xcode7&Swift2)(免費,內容比較初級)
cocoachina專題:從今天開始學習Swift(大量資源鏈接)
常量
多數項目里都需要一些常量,java里通常定義在interface里,用swift時可以定義在一個struct里,作為靜態的存儲成員(static let)。
類型轉換
Double轉Int: Int(myDouble)
保留小數點位數
方法1(3.1415926->3.14, 3->3.00):
let i = 3.1415926 let str = NSString(format:"%.2f",i) print("\(str)") //will output 3.14
方法2(3.1415926->3.14, 3->3):
let nf = NSNumberFormatter() nf.numberStyle = NSNumberFormatterStyle.DecimalStyle nf.maximumFractionDigits = 2 print("\(nf.stringFromNumber(3.1415926))") //will output 3.14
時間
NSDate:相當於java.util.Date,獲得系統當前時間直接用NSDate()
NSTimeInterval:等同於double,NSDate.timeIntervalSince1970可以得到自1970年的秒數(注意不是java里的毫秒數)
NSDateFormatter:用來幫助在String與NSDate類型之間做轉換 參考
嵌套struct
注意一個地方,例如struct A里定義了struct B,實例化A時,必須先執行a.property1 = value1以后再執行b.a=a,否則會發現b.a.property1=nil。
UIView
所有控件的基類。
frame與bound的區別:frame是view的邊界,bound是view可以繪制的區域(bound是可以超出frame范圍的)。參考鏈接1 參考鏈接2
UITableView
基本使用:可以用ViewController里放TableView,也可以直接用TableViewController,參考How to make a simple tableview with iOS 8 and Swift
使用TableViewController時顯示Activity Indicator View(菊花)有問題,不太完美的解決方案見:UITableView Activity Indicator the Apple way,或使用第三方實現,例如下面會提到的SVProgressHUD。
處理cell點擊事件,實現tableView:didSelectRowAtIndexPath方法即可,注意看清楚別實現成tableView:didDeselectRowAtIndexPath。 參考鏈接
點擊cell跳轉(假設從A跳到B):在storyboard里,直接從A的cell到B拖拽創建一個show類型的segue並指定此segue的identity,在A代碼里實現forSegue方法將要傳的參數賦值給B即可。
UICollectionView
相當於Android里的GridView,可以顯示多列數據,只是沒有cell的默認實現,也就是必須使用自定義cell。
要讓每個cell的寬度恰好等於collection view的一半,可通過實現下面的方法實現(參考鏈接):
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSize(width: CGFloat(self.view.frame.size.width / 2), height: self.view.frame.size.height / 3) }
AutoLayout
假設有一個長寬都是150的image view,里面要加載一個網絡圖片(尺寸未知),要求網絡圖片能夠完整顯示在image view里且最長邊與image view的邊長相等,如何實現呢?參考以下鏈接:
被這個問題困擾了一段時間,以上幾個鏈接提供的方法都沒成功。后來發現,在使用autolayout的情況下,控件的width和height應該通過constraint指定(見下圖),配合contentMode=scalefit即可解決。
順便提一句,在storyboard里看到的控件位置並不一定是運行時的位置,因為autolayout情況下只考慮constraint,運行時的位置在storyboard里以橘黃色虛線表示(見下圖)。
Storyboard還提供了多設備預覽功能,使用方法是“打開 Main.storyboard ,然后選擇 View\Assistant Editor\Show Assistant Editor ,這時編輯區會分隔為兩部分。再點擊頂部導航欄中的 Automatic ,在彈出菜單中選擇 Preview ,最后選擇 Main.storyboard (Preview) ... 點擊預覽界面左下角的 + 按鈕,會彈出當前storyboard
文件支持的各種尺寸的設備”(來源)
關於"Relative to margins"選項,在xcode7里這個選項是默認勾選的,每個view默認有寬度為8的margin,可以通過“Editor->Canvas->Show Layout Rectangles”菜單項打開,margin位置顯示為藍色細線。舉例來說,當勾選了“Relative to margins”選項后,如果一個子view的leading space to 父view是0,運行時會看到子view距離父view的邊界還有8的空白區域(效果相當於android里給父view設置了8的padding)。這個缺省margin值可以通過下面的方法設置:
self.rootView.layoutMargins = UIEdgeInsetsMake(0, 50, 0, 0);
參考鏈接:
第三方依賴包
依賴包管理/Carthage
先安裝Homebrew(osx的包管理工具),然后通過Homebrew安裝Carthage(比cocoapods靈活,去中心,只支持ios8和以上版本)。
在工程目錄下新建“Cartfile”文件,並填寫要依賴的包,然后執行carthage update命令,此時如果提示“unable to find utility "xcodebuild", not a developer tool”,可使用"sudo xcode-select --switch"命令解決,這樣就下載了依賴包。為了讓xcode能用到carthage編譯的framework,先從Finder把剛才生成的.framework文件拖到工程的General -> Linked Frameworks and Libraries區域(在Navigator里點擊工程根目錄即可看到)里,然后在Build Phases里添加一個新內容是“/usr/local/bin/carthage copy-frameworks”的Run Script,並在Input Files里增加所需的編譯后的依賴包如“$(SRCROOT)/Carthage/Build/iOS/SwiftyJSON.framework”。 參考Carthage的Getting Start
經測試還需要在工程的Build Setting -> Framework Search Path里添加“$(SRCROOT)/Carthage/Build/iOS”,否則build會失敗。參考資料
依賴包管理/CocoaPods
有些第三方依賴只支持cocoapods,所以也要裝一個cocoapods。cocoapods的資料比較多,例如這篇,也比較容易安裝使用。一個需要注意的問題是,執行pod setup命令后提示Setting up CocoaPods master repo要等很久,大約1小時。
在swift文件里使用object-c開發的庫,需要借助一個bridging文件,通常名稱是“項目名-Bridging-Header.h”。可以讓xcode生成這個文件,方法是在工程里創建一個空的Objective-C文件,最后一步時xcode會提示是否創建bridging文件,點YES然后再刪掉這個空文件即可。在bridging文件里使用類似#import <AFNetworking/AFNetworking.h>的方式包含依賴包。
如果pod install執行很慢,可能是pod更新spec時被牆,可以加--no-repo-update參數。參考鏈接
pod install --verbose --no-repo-update
還可以改用國內鏡像,例如:
pod repo remove master pod repo add master https://git.oschina.net/6david9/Specs.git pod reap list
無法安裝Realm:ios-charts依賴Realm,安裝時很慢(有時等待數小時無果,有時提示SSL Handshake錯誤),其實真正原因是Realm/core所在服務器被牆。可以通過1)使用VPN解決,或2)手工下載安裝core(參考Download core 0.96.0 failed),或3)使用國內鏡像(如果已經下載core失敗過需要清除緩存,參考Core occasionally cannot be downloaded from China)。
HTTP請求/遠程圖片
據說SwiftHTTP是個坑,暫時繞開,使用系統提供的NSURLSession簡單封裝一下。使用方法參考鏈接
iOS9里默認要求所有http請求都使用https,如果一定要用http,在工程的info.plist里修改“App Transport Security Settings -> Allow Arbitrary Loads”為true。
AFNetworking,功能強大且被廣泛使用的Http庫,還帶有異步加載/緩存遠程圖片的功能;對應Swift版本的名稱是Alamofire。
JSON
暫時使用SwiftyJSON,感覺還好,使用舉例:let json1 = JSON(["param1":1])。
下拉刷新/上拉翻頁
下拉刷新:iOS8起內置了UIRefreshControl可以方便的實現下拉刷新功能 用法
上拉翻頁/加載更多:暫時沒有發現原生的簡便方法實現,第三方庫倒是比較多,例如SVPullToRefresh和MJRefresh
進度條
由於TableViewController顯示Activity Indicator有問題,目前在用SVProgressHUD作為替代方案。
折線圖/餅圖
用ios-chart,項目主頁的Usage里說了一堆步驟其實都是針對手動安裝的,如果用cocoapods直接編輯Podfile添加pod 'Charts'再執行pod install即可,bridge都不用改,在自己的.swift文件里import Charts就可以使用了。不過我遇到一個編譯問題,ChartPlatform.swift這個文件編譯不過去,自己在文件結尾加了個空行解決。使用方面,一個比較好的教程見這個鏈接。
經過試用,發現ios-charts畫時序圖(timeseries)比較麻煩,要自己做一些計算(參考)。
替代方案:Core Plot(側重科學繪圖),ios-linechart(使用簡單),JBChartView(來自Jawbone),BEMSimpleLineGraph(使用簡單)。
(未完,持續補充中)