在Visual Studio中使用MonoTouch開發iOS應用程序(下):開發體驗

作者: 趙劼  發布時間: 2010-11-02 14:59  閱讀: 6534 次  推薦: 0   原文鏈接   [收藏]  
摘要:國內技術社區也有關于MonoTouch的內容,老趙將描述在虛擬機中安裝Mac OSX雪豹操作系統,以及利用Visual Studio開發MonoTouch應用程序的方式。

  對于熟悉.NET程序員來說,編寫iOS應用程序的最佳選擇自然是MonoTouch。在上一篇文章里,我們已經在Mac OS X上安裝了MonoTouch開發環境,并已經能夠在Mac OS X和Windows之間共享文件。現在我們就可以來簡單體驗一下,如何使用Visual Studio,Interface Builder以及少量的MonoDevelop來開發一個最最簡單的iOS應用程序。

  新建項目

  根據我的個人習慣,我會先創建一個空白的解決方案。首先在Mac OS X中打開MonoDevelop,然后在菜單中選擇File - New- Solution,在彈出對話框的Other分類中選擇Blank Solution模板,并填寫合適的位置和名稱:

  然后便是創建iPhone應用程序項目。還是剛才的對話框,選擇C#- iPhone and iPad分類下的iPhone Window-based Project模板。同樣,在對話框下方填寫合適的位置和名稱,我的習慣是將所有的源代碼統一放在src目錄下(在解決方案中也會創建一個src目錄與之對應):

  點擊OK。下一步是額外的項目配置,可以直接點擊OK。此時我們就會發現MonoDevelop里展示出的項目文件:

  其中Main.cs里包含了項目的啟動代碼及一個AppDelegate類,MainWindow.xib是主窗口的界面文件,而MainWindow.xib.designer.cs文件則是MonoDevelop根據xib文件中的標記所自動創建的C#代碼,在絕大部分情況下我們不會去修改它。

  編輯界面

  雙擊MainWindow.xib文件,便會打開Interface Builder。下圖左為Library窗口(近似于VS中的Toolbox);中間上方是可視化的UI編輯器,下方則是對象管理器,顯示了界面中定義的對象;右側便是用來修改屬性的Inspector窗口(近似于VS中的Properties窗口):

  首先,在Library窗口上方選擇Objects,并將一個Round Rect Button拖動至UI編輯器,雙擊,輸入Hello World:

  然后,在Library窗口上方選擇Classes,在上方列表中選擇AppDelegate,并在下方下拉框中選取Outlets,并使用下方加號添加一個id,叫做ButtonCounter:

  接著便是個比較有趣的操作。在對象管理器里選中App Delegate對象,并在Inspector上方選擇Connections,再將ButtonCounter右側的小圓點拖動至按鈕,這會將ButtonCounter這個id與按鈕關聯起來,如下圖:

  在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根據xib的內容,自動生成了一些C#代碼。AppDelegate是個Partial Class,它的另一部分在Main.cs文件中,一會兒我們便會使用這里的ButtonCounter定義。

  配置Visual Studio

  雖然MonoDevelop的sln和csproj文件的格式與Visual Studio兼容(包括2005、2008、2010三個版本的VS),但是VS無法識別iPhone應用程序的項目模板,因此如果您直接打開iOS101.sln則會加載失敗。因此,我們需要并行地創建一些sln和csproj,其中大部分內容與MonoDevelop創建的內容保持同步。

  例如,我創建了iOS101.VS.sln及iPhoneApp.UI.VS.csproj(一個.NET 2.0的Class Library)兩個文件,它們分別與iOS101.sln和iPhoneApp.UI.csproj放在同樣的目錄下。值得注意的是iPhoneApp.UI.VS.csproj文件,如果您直接在VS里創建這個項目文件,它的默認命名空間里也會包含“VS”,您可能需要手動修改一下。由于要和MonoDevelop中的項目保持一致的“可編譯通過性”,我們還需要引用MonoTouch SDK里提供的dll。于是我在iOS101目錄中創建了lib/monotouch目錄,并使用如下命令復制所有的MonoTouch提供的dll文件:

cp /Developer/MonoTouch/usr/lib/mono/2.1/*.dll ~/Projects/iOS101/lib/monotouch

  然后,編輯iPhoneApp.UI.VS.csproj的程序集引用和項目文件,最終結果差不多是這樣的。請注意MonoTouch中xib文件的類型為Page,而VS中則需要設為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的結果則類似于:

  試著編譯一下,通過則表示配置成功。

  編寫代碼

  這里您是否有些疑惑,為什么上面創建的是一個.NET 2.0項目呢?這樣我們還能夠使用C# 3.0中的高級特性嗎?答案是肯定的,只要我們使用的是Visual Studio 2008或是2010,則即使是針對.NET 2.0所編寫的代碼,VS也會使用C# 3.0的編譯器,因為我們都知道其實C# 3.0只需要一點點框架和類庫的支持(擴展方法)。您甚至可以使用C# 4.0的部分特性,例如參數的默認值,命名參數等等。可惜您無法使用C# 4.0的動態性,因為它需要DLR和Microsoft.CSharp.dll,又涉及到大量的動態代碼生成,我對此沒什么信心和意愿。當然您感興趣的話也可以嘗試一下。

  我在這里使用.NET 2.0的原因,是希望可以盡可能減少對系統程序集的依賴,而盡量使用MonoTouch所提供的dll。例如現在,除了mscorlib以外,所有的程序集都與Windows上所安裝的.NET Framework無關,這保證了我們編寫的代碼可以在MonoTouch兼容。

  現在就來開始編寫代碼吧,您可以在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方法在程序啟動時調用,此時我們為ButtonCounter添加一個TouchDown事件(類似于Click)添加一個處理函數。這里用到了C#中的匿名函數特性,并捕獲外部的變量i,每次點擊按鈕都將i加一,并顯示在按鈕上。在這里我們使用.NET中比較常用方式添加事件處理,事實上您也可以在Interface Builder中定義一個Action,并把它與Button的TouchDown事件關聯起來。這個Action會表現為一個Partial Method,您可以在代碼里補全其實現。

  保存代碼后您便可以回到MonoDevelop中,為了能夠在iPhone模擬器里運行,您還要修改一個參數。對iPhoneApp.UI點擊右鍵,打開Options對話框,在左側選中Build - iPhone Build類別,并將右側的SDK version設為4.0,如下:

  點擊OK保存并關閉對話框。此時可以選擇菜單Run - Run,或直接使用快捷鍵Command(即Win鍵)+ Alt + Enter便會編譯項目,并打開模擬器執行程序。在默認情況可能打開的iPad模擬器,您可以在Hardware - Device中選擇iPhone或iPhone 4。運行效果如下:

  試著點擊按鈕查看效果吧。

  單元測試及其他

  如果您想調試代碼,只需要在MonoDevelop中設置端點,并選擇菜單Run - Debug,或直接使用快捷鍵Command + Enter便可以對模擬器進行調試。但是如果是要單元測試呢?這問題也不大,MonoDevelop自帶NUnit項目,您可以創建這樣一個單元測試項目,刪除其默認引用,換之為MonoTouch SDK里所提供的程序集,同樣您可以在Visual Studio中開發單元測試代碼,但是調試執行必須在MonoDevelop里進行,因為MonoTouch提供的程序集都是Mac下的Mono實現,它們在Windows下的作用只是為Visual Studio提供必要的元數據,使我們能夠享受到智能提示之類的便利,想要在Windows里運行則是不行的。

  但是,事實上我們也可以將Visual Studio里面的項目定義為.NET Framework 3.5項目,并直接使用.NET提供的程序集,對于MonoTouch里額外的程序集,例如System.Json.dll,則面向.NET 3.5自己重新構建一遍即可(源代碼可以使用.NET Reflector獲得或是利用Mono上的開源代碼)。這么做的優勢在于,對于那些與MonoTouch無關的代碼,我們都可以在Visual Studio里進行調試與測試了。于是乎,我們可以在代碼開發階段盡可能留在熟悉而強大的環境中,對開發效率有很大幫助。

  這種做法也有缺點,例如,雖然MonoTouch提供的類庫與.NET 3.5兼容,但事實上我并不能百分之百保證這點,因此在.NET 3.5里可以編譯通過的代碼,也有可能無法在MonoTouch里編譯執行。此外,這種方法也會讓您無法使用Mono程序集中對.NET的擴展(主要是Mono命名空間下的類庫)。不過這兩個理論上問題到目前為止還沒有給我造成什么困擾,我也只有在需要在查看模擬器運行效果時才回到Mac及MonoDevelop中。

  有些朋友看到System.Json可能會有些熟悉,因為它在Silverlight開發中也有出現。您說的沒錯,事實上MonoTouch里的程序集版本號與Silverlight一樣,都是2.0.5.0,甚至連強簽名都是一致的。只可惜Silverlight里的類庫是.NET 3.5的子集,例如所有同步的IO操作都被去除了,因此我們很難使用Silverlight來開發MonoTouch程序。當然,有了Silverlight,對我們開發MonoTouch也是有所幫助的,這點以后再談。

  最后,您應該已經意識到,我們需要在VS的項目文件與MonoDevelop的項目文件直接做同步,這個同步包括程序集引用與代碼文件兩方面。如果您覺得手動編輯比較麻煩的話,就寫一個自動同步的小程序咯——不會?那么還是先別搞MonoTouch了,從編程基礎學起吧。

  【相關文章】:在Visual Studio中使用MonoTouch開發iOS應用程序(上):環境配置

0
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()