VS中使用MonoTouch開發(fā)iOS應(yīng)用程序 開發(fā)體驗
Visual Studio中使用MonoTouch開發(fā)iOS應(yīng)用程序 開發(fā)體驗是本文要介紹的內(nèi)容,對于熟悉.NET程序員來說,編寫iOS應(yīng)用程序的最佳選擇自然是MonoTouch。在上一篇文章里,(VS中使用MonoTouch開發(fā)iOS應(yīng)用程序 配置環(huán)境 (上))我們已經(jīng)在Mac OS X上安裝了MonoTouch開發(fā)環(huán)境,并已經(jīng)能夠在Mac OS X和Windows之間共享文件?,F(xiàn)在我們就可以來簡單體驗一下,如何使用Visual Studio,Interface Builder以及少量的MonoDevelop來開發(fā)一個最最簡單的iOS應(yīng)用程序。
新建項目
根據(jù)我的個人習(xí)慣,我會先創(chuàng)建一個空白的解決方案。首先在Mac OS X中打開MonoDevelop,然后在菜單中選擇File - New - Solution,在彈出對話框的Other分類中選擇Blank Solution模板,并填寫合適的位置和名稱:
然后便是創(chuàng)建iPhone應(yīng)用程序項目。還是剛才的對話框,選擇C# - iPhone and iPad分類下的iPhone Window-based Project模板。同樣,在對話框下方填寫合適的位置和名稱,我的習(xí)慣是將所有的源代碼統(tǒng)一放在src目錄下(在解決方案中也會創(chuàng)建一個src目錄與之對應(yīng)):
點擊OK。下一步是額外的項目配置,可以直接點擊OK。此時我們就會發(fā)現(xiàn)MonoDevelop里展示出的項目文件:
其中Main.cs里包含了項目的啟動代碼及一個AppDelegate類,MainWindow.xib是主窗口的界面文件,而MainWindow.xib.designer.cs文件則是MonoDevelop根據(jù)xib文件中的標(biāo)記所自動創(chuàng)建的C#代碼,在絕大部分情況下我們不會去修改它。
編輯界面
雙擊MainWindow.xib文件,便會打開Interface Builder。下圖左為Library窗口(近似于VS中的Toolbox);中間上方是可視化的UI編輯器,下方則是對象管理器,顯示了界面中定義的對象;右側(cè)便是用來修改屬性的Inspector窗口(近似于VS中的Properties窗口):
首先,在Library窗口上方選擇Objects,并將一個Round Rect Button拖動至UI編輯器,雙擊,輸入Hello World:
然后,在Library窗口上方選擇Classes,在上方列表中選擇AppDelegate,并在下方下拉框中選取Outlets,并使用下方加號添加一個id,叫做ButtonCounter:
接著便是個比較有趣的操作。在對象管理器里選中App Delegate對象,并在Inspector上方選擇Connections,再將ButtonCounter右側(cè)的小圓點拖動至按鈕,這會將ButtonCounter這個id與按鈕關(guān)聯(lián)起來,如下圖:
在Interface Builder中保存,回到MonoDevelop,打開MainWindow.xib.designer.cs文件,便可以看到其中在AppDelegate中生成的ButtonCounter屬性:
- private MonoTouch.UIKit.UIButton __mt_ButtonCounter;
- [MonoTouch.Foundation.Connect("ButtonCounter")]
- private MonoTouch.UIKit.UIButton ButtonCounter {
- get {
- this.__mt_ButtonCounter = ((MonoTouch.UIKit.UIButton)(this.GetNativeField("ButtonCounter")));
- return this.__mt_ButtonCounter;
- }
- set {
- this.__mt_ButtonCounter = value;
- this.SetNativeField("ButtonCounter", value);
- }
- }
可見,MonoDevelop根據(jù)xib的內(nèi)容,自動生成了一些C#代碼。AppDelegate是個Partial Class,它的另一部分在Main.cs文件中,一會兒我們便會使用這里的ButtonCounter定義。
配置Visual Studio
雖然MonoDevelop的sln和csproj文件的格式與Visual Studio兼容(包括2005、2008、2010三個版本的VS),但是VS無法識別iPhone應(yīng)用程序的項目模板,因此如果您直接打開iOS101.sln則會加載失敗。因此,我們需要并行地創(chuàng)建一些sln和csproj,其中大部分內(nèi)容與MonoDevelop創(chuàng)建的內(nèi)容保持同步。
例如,我創(chuàng)建了iOS101.VS.sln及iPhoneApp.UI.VS.csproj(一個.NET 2.0的Class Library)兩個文件,它們分別與iOS101.sln和iPhoneApp.UI.csproj放在同樣的目錄下。值得注意的是iPhoneApp.UI.VS.csproj文件,如果您直接在VS里創(chuàng)建這個項目文件,它的默認(rèn)命名空間里也會包含“VS”,您可能需要手動修改一下。由于要和MonoDevelop中的項目保持一致的“可編譯通過性”,我們還需要引用MonoTouch SDK里提供的dll。于是我在iOS101目錄中創(chuàng)建了lib/monotouch目錄,并使用如下命令復(fù)制所有的MonoTouch提供的dll文件:
cp /Developer/MonoTouch/usr/lib/mono/2.1/*.dll ~/Projects/iOS101/lib/monotouch然后,編輯iPhoneApp.UI.VS.csproj的程序集引用和項目文件,最終結(jié)果差不多是這樣的。請注意MonoTouch中xib文件的類型為Page,而VS中則需要設(shè)為None:...
- <?xml version="1.0" encoding="utf-8"?>
- <Project ...>
- ...
- <ItemGroup>
- <Reference Include="monotouch">
- <HintPath>..\..\lib\monotouch\monotouch.dll</HintPath>
- </Reference>
- <Reference Include="System">
- <HintPath>..\..\lib\monotouch\System.dll</HintPath>
- </Reference>
- <Reference Include="System.Core">
- <HintPath>..\..\lib\monotouch\System.Core.dll</HintPath>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <None Include="Info.plist" />
- <Compile Include="Main.cs" />
- <None Include="MainWindow.xib" />
- <Compile Include="MainWindow.xib.designer.cs">
- <DependentUpon>MainWindow.xib</DependentUpon>
- </Compile>
- </ItemGroup>
</Project>在VS的結(jié)果則類似于:
試著編譯一下,通過則表示配置成功。
編寫代碼
這里您是否有些疑惑,為什么上面創(chuàng)建的是一個.NET 2.0項目呢?這樣我們還能夠使用C# 3.0中的高級特性嗎?答案是肯定的,只要我們使用的是Visual Studio 2008或是2010,則即使是針對.NET 2.0所編寫的代碼,VS也會使用C# 3.0的編譯器,因為我們都知道其實C# 3.0只需要一點點框架和類庫的支持(擴展方法)。您甚至可以使用C# 4.0的部分特性,例如參數(shù)的默認(rèn)值,命名參數(shù)等等??上鸁o法使用C# 4.0的動態(tài)性,因為它需要DLR和Microsoft.CSharp.dll,又涉及到大量的動態(tài)代碼生成,我對此沒什么信心和意愿。當(dāng)然您感興趣的話也可以嘗試一下。我在這里使用.NET 2.0的原因,是希望可以盡可能減少對系統(tǒng)程序集的依賴,而盡量使用MonoTouch所提供的dll。例如現(xiàn)在,除了mscorlib以外,所有的程序集都與Windows上所安裝的.NET Framework無關(guān),這保證了我們編寫的代碼可以在MonoTouch兼容。
現(xiàn)在就來開始編寫代碼吧,您可以在VS里打開Main.cs,在AppDelegate的FinishedLaunching方法中添加如下代碼,使之成為:
- public override bool FinishedLaunching(UIApplication app, NSDictionary options)
- {
- int i = 0;
- this.ButtonCounter.TouchDown += delegate
- {
- this.ButtonCounter.SetTitle((++i).ToString(), UIControlState.Normal);
- };
- window.MakeKeyAndVisible();
- return true;
- }
FinishedLaunching方法在程序啟動時調(diào)用,此時我們?yōu)锽uttonCounter添加一個TouchDown事件(類似于Click)添加一個處理函數(shù)。這里用到了C#中的匿名函數(shù)特性,并捕獲外部的變量i,每次點擊按鈕都將i加一,并顯示在按鈕上。在這里我們使用.NET中比較常用方式添加事件處理,事實上您也可以在Interface Builder中定義一個Action,并把它與Button的TouchDown事件關(guān)聯(lián)起來。這個Action會表現(xiàn)為一個Partial Method,您可以在代碼里補全其實現(xiàn)。
保存代碼后您便可以回到MonoDevelop中,為了能夠在iPhone模擬器里運行,您還要修改一個參數(shù)。對iPhoneApp.UI點擊右鍵,打開Options對話框,在左側(cè)選中Build - iPhone Build類別,并將右側(cè)的SDK version設(shè)為4.0,如下:
點擊OK保存并關(guān)閉對話框。此時可以選擇菜單Run - Run,或直接使用快捷鍵Command(即Win鍵) + Alt + Enter便會編譯項目,并打開模擬器執(zhí)行程序。在默認(rèn)情況可能打開的iPad模擬器,您可以在Hardware - Device中選擇iPhone或iPhone 4。運行效果如下:
試著點擊按鈕查看效果吧。
單元測試及其他
如果您想調(diào)試代碼,只需要在MonoDevelop中設(shè)置端點,并選擇菜單Run - Debug,或直接使用快捷鍵Command + Enter便可以對模擬器進(jìn)行調(diào)試。但是如果是要單元測試呢?這問題也不大,MonoDevelop自帶NUnit項目,您可以創(chuàng)建這樣一個單元測試項目,刪除其默認(rèn)引用,換之為MonoTouch SDK里所提供的程序集,同樣您可以在Visual Studio中開發(fā)單元測試代碼,但是調(diào)試執(zhí)行必須在MonoDevelop里進(jìn)行,因為MonoTouch提供的程序集都是Mac下的Mono實現(xiàn),它們在Windows下的作用只是為Visual Studio提供必要的元數(shù)據(jù),使我們能夠享受到智能提示之類的便利,想要在Windows里運行則是不行的。
但是,事實上我們也可以將Visual Studio里面的項目定義為.NET Framework 3.5項目,并直接使用.NET提供的程序集,對于MonoTouch里額外的程序集,例如System.Json.dll,則面向.NET 3.5自己重新構(gòu)建一遍即可(源代碼可以使用.NET Reflector獲得或是利用Mono上的開源代碼)。這么做的優(yōu)勢在于,對于那些與MonoTouch無關(guān)的代碼,我們都可以在Visual Studio里進(jìn)行調(diào)試與測試了。于是乎,我們可以在代碼開發(fā)階段盡可能留在熟悉而強大的環(huán)境中,對開發(fā)效率有很大幫助。
這種做法也有缺點,例如,雖然MonoTouch提供的類庫與.NET 3.5兼容,但事實上我并不能百分之百保證這點,因此在.NET 3.5里可以編譯通過的代碼,也有可能無法在MonoTouch里編譯執(zhí)行。此外,這種方法也會讓您無法使用Mono程序集中對.NET的擴展(主要是Mono命名空間下的類庫)。不過這兩個理論上問題到目前為止還沒有給我造成什么困擾,我也只有在需要在查看模擬器運行效果時才回到Mac及MonoDevelop中。
有些朋友看到System.Json可能會有些熟悉,因為它在Silverlight開發(fā)中也有出現(xiàn)。您說的沒錯,事實上MonoTouch里的程序集版本號與Silverlight一樣,都是2.0.5.0,甚至連強簽名都是一致的。只可惜Silverlight里的類庫是.NET 3.5的子集,例如所有同步的IO操作都被去除了,因此我們很難使用Silverlight來開發(fā)MonoTouch程序。當(dāng)然,有了Silverlight,對我們開發(fā)MonoTouch也是有所幫助的,這點以后再談。
最后,您應(yīng)該已經(jīng)意識到,我們需要在VS的項目文件與MonoDevelop的項目文件直接做同步,這個同步包括程序集引用與代碼文件兩方面。如果您覺得手動編輯比較麻煩的話,就寫一個自動同步的小程序咯——不會?那么還是先別搞MonoTouch了,從編程基礎(chǔ)學(xué)起吧。
小結(jié):Visual Studio中使用MonoTouch開發(fā)iOS應(yīng)用程序 開發(fā)體驗的內(nèi)容介紹完了,希望本文對你有所幫助,更多相關(guān)內(nèi)容請參考編輯推薦。