【Xamarin】iOS 程式設計與 Xamarin.iOS
一般而言,設計一個 iOS App 須使用 Mac 電腦搭配 Xcode 這套 IDE 完成。而大部分的教學文多強調先拖拉再一步步實作按鈕等功能,與實際開發人員的做法有出入。一台麥金塔電腦的售價加上每年 USD$99 的上架費用使人卻步。其實,開發一個 iOS App 一點都不難,而現在蘋果除了 iCloud Kit 以外也不再要求開發者需要開發者計畫才能進行實機測試。隨著 Xamarin 的推出,iOS App 也不再只能用 Objective-C 或 Swift 進行開發, 也能用 C#,接下來這篇文章會先從一個原生的 Xcode project 的檔案架構切入,並分析由 Objective-C,Swift 和 Xamarin 架構的 C# 在語法和使用上的不同之處。
原生iOS App 架構
一般從 App store 下載的 App 會被打包成 .ipa(相當於 Android 的 .apk),而開啓一個Xcode專案後會包含以下幾種檔案:
- A. .h/.m/.Swift:程式的原始碼,所有的控制都是在這裡完成
- B. .xib:Interface Builder 存放的 XML,包含使用者拖拉元件後的位置與屬性。 iOS App 依循 MVC(Model-View-Controller)架構,一個 xib 檔相當於 View,搭配 View Controller使用。與 Android 程式設計較不相同的是這個檔案不一定要存在,可在 UIView 中描述各個元件的屬性,而不須透過拖拉。
- C. .storyboard:伴隨iOS 5推出,用法與Interface Builder相當,都能夠拖拉元件. 更進一步讓切換畫面不須以程式碼來完成。
- D. .framework:即為上面 Core service 提供的框架,為二進制檔,與函式庫的概念相近。
- E. .plist:用來存放用戶設定,以及一些與 App 本身有關的資訊,像是 CPU 架構等。
最基本的 iOS app --- 使用 Objective-C
Objective-C 是 C 語言的超集(Superset),也就是在一個 Objective-C 的檔案中可以完全使用 C 的語法而不會發生編譯錯誤。而在 iOS 程式設計中,會大量繼承 NSObject 這個 class。大部分的開發者會把class的宣告(declaration)與實作(inplementation)分成 .h 標頭檔與 .m 這兩個檔案。
#include <foundation/foundation.h> @interface foobar:NSObject { @property (strong, atomic) bar; } -(void)foo:(int)arg @end
▲ 以上示範 Objective-C 2.0
在 Objective-C 中的 instance variable 在 2.0 之前須寫一對 setter/getter,非常麻煩。 透過 @property,編譯器會自動幫我們產生 get 和 set 這兩個 method(但開發者能夠覆寫(Override)這些方法)。大括號外宣告 method,若在括號前使用 + 號代表static。 而 property 也帶有參數,若不使用 ARC(Automatic Reference Counting), 會有 assign、retain、copy 三種,請參閱這篇 StackOverflow 的問答。若使用 ARC,則分為 Strong/Weak,atomic/nonatomic 兩種:
- Strong:代表擁有該變數,不能使用代理(Delegate)。
- Weak:由代理建構的物件,並不能直接控制。 若指向一個strong類型的物件被釋放時也會跟著被釋放。
- Atomic:可防止一個 thread 完成前被另一個 thread 讀取。
- Nonatomic:禁止 multithread 以提高性能。
另外還有 ReadWrite 和 Readonly,就和字面上一樣,若設為 Readonly 則只會生成 getter,使用者無法更改其值。
@implementation foobar @synthesize bar; -(void)foo:(int)arg{ Foobar *b = [[foobar alloc] init]; [b release]; } @end
▲ 以上則為 .m的架構
當前面使用 property 時,需搭配一個 synthesize 以產生 getter 和 setter。在此值得注意的是,setter 在 Objective-C 2.0 後可使用點(dot),但其他的method依然須使用中括號。而另外還有 Objective-C++,可加入 C++ 的類別,但有許多限制。
最基本的 iOS app --- 使用 Swift
學習 Objective-C 對初學者而言是一大挑戰,尤其是其複雜的記憶體管理。Swift 的架構與Python相似,不需一開始就宣告變數型態。 Objective-C 和 Swift 可同時出現在同一個專案之中。但 Swift 多了一些基本形態,如String等,有時須先轉成 Objective-C 有的型別。
import Cocoa class AppDelegate: NSObject,NSApplicationDelegate { @IBOutlet weak var showbtn: NSButton! @IBOutlet weak var thepop:NSPopover! @IBAction func mybutton(sender: AnyObject) { thepop.showRelativeToRect(sender.bounds, ofView: sender as! NSView , preferredEdge: NSRectEdge.MinX) } }
▲ Swift 的程式碼較 Objective-C 簡潔
若開發者使用 Interface Builder 建構基本界面,程式碼中便會多出 IBOutlet 與 IBAction(可視為 Android 的 findviewbyid)。IBOutlet 可宣告介面上的元件,透過 IBAction,可以handle 介面上的元件所發出的事件。Swift 的特色是擁有 Optional type, 使得變數如果是 nil 的情況也能夠正常編譯, 程式碼中的驚嘆號代表強制解析,若執行到該行但物件不存在會出現 runtime error。而問號則多用於宣告變數, 宣告時物件可為 nil,通常搭配 if let 判斷式使用。
Xamarin.iOS
Xamarin 的特色是不必透過上述的 Objective-C 與 Swift 撰寫 iOS app,而是使用 C#。 雖然 Swift 編譯器已開源,Objective-C 也是 GCC 可編譯的語言之一,但 Cocoa touch 本身是專有軟體,所以在建置(Build)一個 Xamarin.iOS專案時,仍須準備一台裝好Xcode 的 Mac 電腦進行編譯。
在Mac上可以安裝 Xamarin studio來開發Xamarin.iOS,就算是PC上的 Visual Studio,也能夠藉由以 SSH(Secure Shell Hashing)連接 Mac 來開發。開出來的選項與一般 Xcode 無異,就連Interface Builder 的選項皆與 Xcode 相同
Xamarin.iOS 擁有的類別與 Xcode 同步,但也有自己的 reference。所有的 Objective-C 與 Swift 檔案都改成 .cs, 至於流程控制、事件傳遞等都與原生的相同,但須符合C#的語法,而前面要 using 的模組也與 Windows form 相似。
撰寫 Xamarin.iOS 程式時,一樣能夠參考蘋果官方的 iOS API Reference,但有幾個地方需要注意
- • 方法的大小寫
-
- Objective-C / Swift:viewDidLoad
-
- Xamarin:ViewDidLoad
- • 匯入模組
-
- o Swift:import
-
- o Objective-C:include 或 import
-
- o Xamarin:Using
- • Xamarin 須宣告 namespace
- • Xamarin 的建構子(Constructor)須符合 C# 的語法,如下
-
- o Xamarin
var height = new UITextField { Frame = new CGRect(50, 105, 200, 30), BorderStyle = UITextBorderStyle.RoundedRect, Placeholder = "Height" };
-
- o Swift
var height = UITextField(Frame:CGRectMake(50, 105, 200, 30), borderStyle: .RoundRect, placeHolder: "Height")
-
- o Objective-C
UITextField *height = [[UITextField alloc] initWithFrame: CGRectMake(50, 105, 200, 30)];
- • Xamarin 可使用 PCL(Portable Class Library),將某些函數模組化後移植到其他平台,如 Xamarin.Android
結語
每一種程式語言都有它的獨特性。 其中 Objective-C 可透過 Bridging Header 與 Swift 混用,故一些網路上的教學文章提供的寫法仍值得參考,且一些第三方 API 也能透過這種方式使用。 Xamarin.iOS 提供用 C# 撰寫 iOS 應用程式的方式,語法類似 Java,對於寫過 Android app 的開發人員來說非常容易上手,同時也提供了 Objective-C 的綁定(Binding)。 物件導向程式語言的架構大同小異,大多是語法和用法上的差異,而學 App 要注意的通常是流程控制與不同 UI 元件和服務(Service)的使用方式。 Xamarin 讓我們可以用 C# 搞定所有平台的 App,同時能夠學到原生 App 的架構和各種功能的實作方法,很值得 App 初學者學習。
參考資料
https://www.zhihu.com/question/20350816 https://shenfive.pixnet.net/blog/post/48054812-%EF%BC%A0property- https://kaochenlong.com/2010/12/08/property-and-synthesize/ https://www.raywenderlich.com/113388/storyboards-tutorial-in-ios-9-part-1 https://developer.apple.com/reference/uikit/uitextfield