|
直到最近,要為蘋果的iPhone開發(fā)應(yīng)用程序的唯一選擇就是一頭扎進(jìn)蘋果的開發(fā)系統(tǒng)中。這意味著,你必須“愿意”在XCode IDE中編寫Objective-C代碼。對于很多開發(fā)人員,學(xué)習(xí)Objective-C被看作是一個巨大的障礙。特別對于哪些從來不用擔(dān)心內(nèi)存管理、指針和C語言要負(fù)責(zé)處理的東西的開發(fā)人員來說,更是如此。
隨著MonoTouch框架(Novell的Mono Project的一部分)的出現(xiàn),這一切都將改變。Mono Project是微軟.NET平臺的開源實現(xiàn)。其允許你在幾乎任何平臺上運行.NET應(yīng)用程序,包括Apple、FreeBSD、Linux、Unix等等。MonoTouch是Mono Project的新組成部分,讓你能夠用C#和.NET平臺編寫可以運行在iPhone上的應(yīng)用程序。
本篇文章的目的,就是提供MonoTouch平臺的一個完整介紹,讓大家知道到那里獲取必要的工具,MonoTouch有什么樣的限制,以及如何構(gòu)建一個簡單的應(yīng)用程序。
背景和限制
對于打算為iPhone開發(fā)應(yīng)用的.NET開發(fā)人員而言,MonoTouch的出現(xiàn)無疑是一件好事。然而,在決定創(chuàng)建應(yīng)用程序之前,有一些限制和背景知識需要先了解清楚。
它如何工作?
在創(chuàng)建MonoTouch應(yīng)用程序的時候,大部分非UI方面的.NET 3.5功能依舊可用,或者一些還處于計劃之中(如.NET 4.0的功能)也囊括其中。這讓你可以使用很多業(yè)已熟悉的.NET Framework技術(shù)來編寫應(yīng)用程序,包括Windows Communication Framework (WCF)、Workflow Foundation (WF)等等。也包括幾乎所有的基類庫(Base Class Library,BCL),涵蓋諸如垃圾收集(Garbage Collection)、線程、數(shù)學(xué)函數(shù)、System.NET、加密等。
對于可用的標(biāo)準(zhǔn).NET程序集列表,見http://monotouch.NET/Documentation/Assemblies。MonoTouch是一種基礎(chǔ).NET函數(shù)庫的特別定制版本,這也類似Silverlight和Moonlight的實現(xiàn)方式。
這意味著,你能夠使用MonoTouch的核心程序集來編譯標(biāo)準(zhǔn)的.NET 3.5代碼成相應(yīng)的函數(shù)庫,并在你的應(yīng)用程序中使用它們。因此,如果你有一個用于其它應(yīng)用程序的特別函數(shù)庫,其包含著一些用于工程問題的高級數(shù)學(xué)函數(shù),那么只需簡單地把這些代碼庫加入到你的MonoTouch解決方案中,并引用它。在你構(gòu)建解決方案的時候,編譯器就利用MonoTouch核心函數(shù)庫對其進(jìn)行編譯,接著就能在iPhone應(yīng)用程序中使用它了。
MonoTouch也包括一些原生iPhone API的包裝函數(shù)庫,如訪問位置(Location,GPS)、加速計、地址簿等的函數(shù)。MonoTouch也提供相應(yīng)的功能,讓你能夠調(diào)用那些尚未進(jìn)行包裝的原生Objective-C函數(shù)庫,所以你可以直接和現(xiàn)存的Objective-C代碼進(jìn)行互操作。
我如何創(chuàng)建用戶界面(UI),我能使用Silverlight嗎?
MonoTouch應(yīng)用程序的UI需要使用蘋果的Interface Builder(界面創(chuàng)建器,IB)應(yīng)用程序來創(chuàng)建,IB連同iPhone SDK一起提供。Interface Builder使用Cocoa Touch(蘋果用于iPhone的UI框架)控件對象,這些控件對象在iPhone上原生提供的。這意味著,你能在應(yīng)用程序中使用所有的標(biāo)準(zhǔn) iPhone控件,如選擇器(Pickers)、滑動條(Sliders)、按鈕等等。
你也能通過代碼來創(chuàng)建界面,即實例化Cocoa Touch對象后,把它們添加到應(yīng)用程序的視圖(Views)中(關(guān)于視圖,后面會詳細(xì)講述)。
然而,你不能利用傳統(tǒng)的.NET技術(shù),如Silverlight、WPF、WinForms等來創(chuàng)建MonoTouch界面。
Cocoa Touch使用一種融合了MVC(Model View Controller)模式思想的結(jié)構(gòu),我們將在后面一篇文章中介紹。
我如何分發(fā)我的應(yīng)用?
MonoTouch應(yīng)用程序的分發(fā)完全和傳統(tǒng)iPhone應(yīng)用程序的分發(fā)一樣,既可以通過蘋果App Store,也可以通過企業(yè)部署。
App Store是一個在線資源庫,讓用戶可以付費購買(如果不是免費的話)和下載應(yīng)用程序。可以從iTunes中訪問,或直接通過iPhone本身來訪問。為了得到通過App Store分發(fā)應(yīng)用的許可,你必須向蘋果注冊,并支付每年99美元的年費。
企業(yè)部署方式就是為公司開發(fā)內(nèi)部應(yīng)用程序,并分發(fā)給員工等人員使用,無需把應(yīng)用在App Store中列出。
什么是許可模型?
不像Mono那樣,MonoTouch不是開源的,且是一個收費產(chǎn)品。這意味著,如果你打算開發(fā)一些實際的應(yīng)用,就必須購買軟件許可。
- 專業(yè)版($399)——單個的個人開發(fā)人員許可,讓你可以開發(fā)應(yīng)用程序,并通過蘋果App Store來分發(fā)它們。
- 企業(yè)版($999)——單個的企業(yè)開發(fā)人員許可,讓你可以開發(fā)應(yīng)用程序,并通過蘋果App Store來分發(fā)它們,或者進(jìn)行企業(yè)部署。
- 企業(yè)版,5人($3999)——和企業(yè)版一樣,只是提供了5個坐席的授權(quán)。
以上所有選項都包括了一年的免費升級權(quán)益。
還有一個評估版本,你只能把應(yīng)用部署到模擬器中。出于介紹的目的,我們只需要評估版本就行。
MonoTouch有哪些限制?
沒有即時(JIT)編譯
根據(jù)蘋果的iPhone政策,任何應(yīng)用程序都不能包含需要JIT編譯的代碼。但是稍等,.NET確實能正確工作,是不?對,不過MonoTouch是通過把應(yīng)用程序編譯為原生的iPhone程序集來跳過這個限制的。但是,這也帶來了幾個限制。
- 泛型——泛型是由JIT編譯器在運行時進(jìn)行實例化的,然而,Mono具備一種提前(Ahead of Time ,AOT)編譯的模式,可以為類似List<T>這樣的泛型集合生成方法和屬性。而泛型的其他用法,例如泛型虛方法、泛型類型上的 P/Invokes和Dictionary<TKey, TValue>上的值類型,就不被支持(雖然存在Dictionary<TKey, TValue>的代替方法)。
- 動態(tài)代碼生成——因為動態(tài)代碼生成依賴于JIT編譯器,所以對任何動態(tài)語言編譯的過程也不能支持。包括System.Reflection.Emit、 Remoting和動態(tài)語言運行時(DLR)。
C#是唯一的語言
另外,目前用于編寫MonoTouch應(yīng)用程序的唯一可用語言是C#。Visual Basic.NET有望在MonoTouch未來的發(fā)布中支持,不過此時此刻我們別無選擇。
更多信息
限制的完整列表和更多信息,可參見http://monotouch.NET/Documentation/Limitations。
入門
要進(jìn)入為iPhone創(chuàng)建MonoTouch應(yīng)用程序的大門,我們需要下面幾樣?xùn)|西:
- 一個使用Intel CPU的Mac電腦,其要安裝MacOSX 10.5或10.6 (Leopard或Snow Leopard)
- 蘋果的iPhone SDK 3.0或更高版本
- Mono的當(dāng)前版本
- MonoTouch SDK
- 一個IDE工具,如MonoDevelop或XCode,或一個文本編輯器程序
安裝著Leopard或Snow Leopard的Mac
這是最重要也是最容易忽視的需求。盡管,理論上你能在任何平臺上開發(fā)大部分應(yīng)用程序,然而iPhone Simulator和Interface Builder只能在Leopard和Snow Leopard上運行。另外,編譯器本身用到了一些特定于Intel Mac機(jī)器的底層功能,所以購買這樣一臺電腦是絕對必須的。
蘋果的iPhone SDK
iPhone SDK可通過http://developer.apple.com/iphone/來免費下載,不過必須在蘋果網(wǎng)站上注冊,才能訪問這個地址。
在安裝了iPhone SDK后,要確保你能正常啟動iPhone Simulator。要啟動它,只需打開Spotlight,鍵入iPhone Simulator。
Mono
一旦你測試iPhone Simulator正常,那么就要安裝Mono for OSX的最新版。
Mono可以從http://mono-project.com/Downloads下載。記住要點擊“Intel”版本的鏈接,不要點CSDK版本。同樣,安裝MonoTouch SDK之前也需要安裝Mono的。Mono的安裝包是磁盤鏡像的形式,掛接鏡像,雙擊安裝包,根據(jù)安裝向?qū)瓿砂惭b過程。
MonoTouch SDK
接下來,下載和安裝最新的MonoTouch SDK。
你既可以在MonoTouch商店(http://monotouch.NET/Store)購買,購買后會收到一個下載鏈接,也可以從http://monotouch.NET/DownloadTrial下載評估版。如果購買了MonoTouch,你就能把應(yīng)用程序部署到一臺正確配置了的iPhone上,不過也可像我這樣,僅僅在模擬器中運行。所以,目前而言試用/評估版就足夠了。
文本編輯器或集成開發(fā)環(huán)境(IDE)
如果你打算創(chuàng)建MonoTouch應(yīng)用程序,所需的所有東西就是前面提及的,和一個文本編輯器。你能創(chuàng)建所有代碼文件,并用命令行(終端窗口)來手動編譯。這種方式雖然可行,但是實際操作起來可能會非常痛苦,所以我們還是需要使用一個IDE來開發(fā)我們的應(yīng)用程序。
你可以編輯/hack一下XCode(隨iPhone SDK一起安裝)來利用MonoTouch的函數(shù)庫和編譯器,也可以使用MonoTouch版的MonoDevelop,其已經(jīng)為MonoTouch應(yīng)用程序做好所有配置了。我們理所當(dāng)然要用MonoDevelop,所以訪問這里http://monodevelop.com/Download/Mac_MonoTouch來下載它。要安裝MonoDevelop,只用把下載文件拖到應(yīng)用程序目錄中就行。
如果你已經(jīng)正確安裝Mono,那么MonoDevelop應(yīng)該可以正常啟動。
Hello World應(yīng)用程序
現(xiàn)在,一切已經(jīng)準(zhǔn)備妥當(dāng),讓我們開始來嘗試開發(fā)點東西了。
MonoDevelop
首先,啟動MonoDevelop。你應(yīng)該會看到和下圖類似的界面【譯者注:如果OSX的首選語言是中文的話,MonoDevelop的菜單和工具欄的文字顯示不正常,所以最好把English拖到語言選項的第一位】:
作為一個標(biāo)準(zhǔn)的IDE,看上去還是蠻熟悉的。它非常類似Visual Studio、SharpDevelop、Visual C# Express等等。
我們創(chuàng)建一個新解決方案,來包含iPhone項目。這里的解決方案和Visual Studio中的概念一樣,實際上你可以在MonoDevelop中打開Visual Studio創(chuàng)建的解決方案。在MonoDevelop中的一個不同點就是,你能夠在一個MonoDevelop實例中打開多個解決方案,正如下面的截圖所示:
這完全是由于在OSX中,你不能啟動MonoDevelop的多個實例(事實上,任何程序都不行),且沒有任何變通方法。所以,如果你需要在解決方案間切換(例如,你希望另外打開一個包含示例代碼的解決方案),你就能簡單地一次性打開多個。
那么,說了上面這么多,讓我們現(xiàn)在來創(chuàng)建一個解決方案吧。在菜單中,點File:New:Solution:
我們要創(chuàng)建一個如下面截圖所示的“iPhone MonoTouch Project”。選中,命名為Example_HelloWorld_1。
這里再次和Visual Studio中創(chuàng)建新解決方案的對話框很類似。點擊Forward ,顯示下一屏,直接點擊OK,因為我們不需要這些功能:
你現(xiàn)在應(yīng)該可以看到如下所示的解決方案視圖了(注意,我展開了解決方案中的節(jié)點,以便顯示出所有文件和引用程序集):
我們來過一遍這些東西:
- References ——這個文件夾包含MonoTouch應(yīng)用程序需要的基本引用。MonoTouch程序集包括特定于iPhone的任何東西,也包括了所有Cocoa Touch控件的包裝器,以及類似位置、數(shù)據(jù)等核心iPhone接口。以System.開頭的程序集是.NET的基類庫和運行時,其被裁減過以便能運行在 iPhone上。
- Main.cs ——這和控制臺應(yīng)用程序、WPF應(yīng)用程序等是一致的。在這里調(diào)用的是static void main() ,其是作為應(yīng)用程序的入口點。過一下我們會仔細(xì)研究一下這個文件。
- MainWindow.xib和MainWindow.xib.designer.cs ——這個和Winforms Window或WPF Window類似。xib文件實際上要在Interface Builder中進(jìn)行編輯,而designer.cs文件包含這個窗體的屬性。
讓我們來仔細(xì)研究一下Main.cs文件中的代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace Example_HelloWorld_1
{
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args);
}
}
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// If you have defined a view, add it here:
//window.AddSubview(navigationController.View);
window.MakeKeyAndVisible ();
return true;
}
// This method is required in iPhoneOS 3.0
public override void OnActivated (UIApplication application)
{
}
}
}Outlets(對象關(guān)聯(lián)口)
我們來為之前添加的標(biāo)簽和按鈕控件添加outlets,以便能在代碼中訪問它們。這點在Leopard和Snow Leopard上也有所區(qū)別,所以大家要嚴(yán)格遵循這里提到的正確指示。
【SNOW LEOPARD指示開始】
確保Library Window是打開的。點擊頂部的“Classes”標(biāo)簽。點擊第一個下拉列表框,這個就是所謂的“Library”,滾動到最后選擇“Other Classes”。就會顯示在你的項目中存在的自定義類。從上面列表中選擇AppDelegate,接著選擇下面的“Outlets”標(biāo)簽:
點擊“+”按鈕兩次來創(chuàng)建兩個新的Outlet。
【SNOW LEOPARD指示結(jié)束】
【LEOPARD指示開始】
首先,保證在Document Window中App Delegate是被選中的。如果App Delegate未被選中,那么在創(chuàng)建Outlets的時候,它們的屬性不會被創(chuàng)建,或者會在錯誤的地方創(chuàng)建。
接下來,來看Identity Inspector。Identity Inspector是Inspector窗口的最后一個標(biāo)簽頁。現(xiàn)在,在Identity Inspector中定位到“Class Outlets”部分。在Class Outlets上,點擊“+”按鈕兩次來創(chuàng)建兩個新的Outlet。
【LEOPARD指示結(jié)束】
每個outlet都具有一個名稱和一個類型。名稱代表了控件屬性的名字,這個類似于ASP.NET的ID,或WPF中的Name。類型是 Outlet的實際類型,比如UIButton、UILabel、UITextView等等。為了命名它們,在它們的名稱上雙擊,鍵入相應(yīng)的名稱。對于我們之前添加的outlet來說,我們修改為“btnClickMe”和“lblResult”。
目前,它們兩者的類型都是“id”。如果你不改變類型,就能把它們掛接到任何東西上,因為id就意味著動態(tài)類型,本質(zhì)上就是.NET世界中的“object”。id類型雖然好,不過我們打算把它們改為實際的類型。過一會我們會看到這樣做會有什么不同。現(xiàn)在,雙擊btnClickMe的類型,鍵入“UIButton”。你的Class Outlets 窗口應(yīng)該顯示如下這個樣子:
如果在里面沒有window的outlet,意味著你沒有在App Delegate創(chuàng)建outlet。如果這樣的話,刪除Outlets,保證在Document Window中選中App Delegate,重新創(chuàng)建outlets。
現(xiàn)在我們已經(jīng)創(chuàng)建了這些outlets了,就需要實際地把它們關(guān)聯(lián)到我們的控件上。首先,在Inspector窗口上點擊第二個標(biāo)簽頁,來選中 Connections Inspector。在Outlets部分,應(yīng)該可以看到我們之前創(chuàng)建的兩個Outlets了。然而,你不能把它掛接到任何東西上。注意,“window”這個outlet已經(jīng)掛接到“Window”對象上了。
為了掛接我們的Outlets,我們要從“Outlets”中的outlet圓點上,拖動到我們想要掛接的控件上。在這樣做的時候,我們將會看到如下所示的效果:
對兩個Outlet都進(jìn)行這樣處理。你也可以從Connections Inspector拖到Document Window上。如果控件相互重疊的情況下,這樣就很有用。下面的截圖就描述了這種方式:
在我們這樣做的時候,你可能會注意到一些有趣的事情。因為設(shè)置lblResult的類型為UILabel,所以在我們把它的 Outlet拖到Window的時候,它只允許我們掛接到那些類型一致的控件上,在這個例子中就是UILabel。另外一方面,btnClickMe能被拖到任何東西上,因為它具有動態(tài)的ID類型。這就是我們要設(shè)置強(qiáng)類型outlet的一個原因,以便降低它掛接到錯誤控件上的可能性。當(dāng)然,這不是必須的,不過這樣做是一個良好的習(xí)慣。
好的,現(xiàn)在我們創(chuàng)建好了界面了,outlets也掛接好了,讓我們回到MonoDevelop把一起串在一起。
回到MonoDevelop
如果你打開MainWindow.designer.cs,在其中會到兩個屬性:
[MonoTouch.Foundation.Connect("btnClickMe")]
private MonoTouch.UIKit.UIButton btnClickMe {
get {
return ((MonoTouch.UIKit.UIButton)(this.GetNativeField("btnClickMe")));
}
set {
this.SetNativeField("btnClickMe",value);
}
}
[MonoTouch.Foundation.Connect("lblResult")]
private MonoTouch.UIKit.UILabel lblResult {
get {
return ((MonoTouch.UIKit.UILabel)(this.GetNativeField("lblResult")));
}
set {
this.SetNativeField("lblResult",value);
}
}
NET技術(shù):MonoTouch:用.NET開發(fā)iPhone應(yīng)用,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。