用Xamarin和Visual Studio編寫iOS App

來源:互聯網
上載者:User

標籤:

原文:Building iOS Apps with Xamarin and Visual Studio
(Bill Morefield](https://www.raywenderlich.com/u/bmorefield)
譯者:kmyhy

一說開發 iOS app,你立馬就會想到蘋果的開發語言 Objective C/Swift 和 Xcode。但是,這並不是唯一的選擇,我們完全可以使用別的語言和架構。

一種主流的替換方案是 Xamarin,這是一個跨平台架構,允許你開發 iOS、Android 和 OSX、Windows app,它使用的是 C# 和 Visual Studio。最大的好處在於,Xamarin 允許你在 iOS 和 Android app 間共用代碼。

Xamarin 與其他跨平台架構相比有一個最大的好處:使用 Xamarin,你的項目能夠編譯出本地代碼,並使用本地 APIs。也就是說,用 Xamarin 編寫的 app 和用 Xcode 編出來的 app 毫無區別。更多細節,請閱讀這篇文章Xamarin vs. Native App Development。

但是 Xamarin 還有一個巨大的缺點,就是它的價格。每個平台 1000 美元/年的價格,可能要讓你戒掉每天都喝的拿鐵或法布奇諾才能負擔得起……程式員如果不喝咖啡是件很危險的事情。因為高昂的價格,Xamarin 至今只在預算豐沛的企業專案中才會採用。

但是,自從微軟收購 Xamarin 之後這種情況發生了改變,微軟將它整合到新版的 Visual Studio 中,甚至是免費的社區版。而社區版對個人開發人員和小團隊是免費的。

免費?真是太好了!

除了價格以外(或者根本不考慮價格),Xamarin 還擁有其它好處,包括允許程式員:

  • 利用原有的 c# 庫和工具編寫手機 app。
  • 在不同平台的 app 之間共用代碼。
  • 在 ASP.net 後台和前端 app 之間共用代碼。

Xamarin 還允許你根據你的需求改變工具。如果想最大化地跨平台共用代碼,請使用 Xamarin Forms,它非常適合於不針對特定平台的特性或者需要單獨定製 UI 的 app。

如果你的 app 需要調用針對特定平台的功能或介面,請使用 Xamarin.iOS、Xamarin.Android 或其他平台的模組,這樣就可以直接調用本地 API 和架構。這些模組能夠建立高度定製的 UI,同時在通用代碼上支援跨平台。

在本教程中,你將使用 Xamarin.iOS 建立 iPhone app,這個 app 用於列出使用者的照片庫。

本教程不需要任何 iOS 或 Xamarin 開發經驗,但最好具備 C# 基礎。

開始

要用 Xamarin 和 Visual Studio 開發 iOS app,理想的情況下你需要兩台電腦:

  • 一台 Windows 電腦,用於運行 Visual Studio,並編寫代碼。
  • 一台裝有 Xcode 的 Mac 電腦,用於充當 buid 主機。並不是專門用它來進行編譯,而是在開發和調試過程中,用它來接受自 Windows 電腦發出網路請求。

兩台電腦的物理距離越近越好,因為當你在 windows 電腦上編譯和運行時,iOS 模擬器會在 Mac 電腦上運行。

你可能會問“如果我沒有兩台電腦怎麼辦?”

  • 對於只使用 Mac 平台的使用者,Xamarin 也提供了 OSX 下的 IDE,但本教程主要目的是示範全新的 Visual Studio。如果你不喜歡這樣,你可以在 Mac 上跑一個 Windows 虛擬機器。VMWare Fushion 或者免費開源的 VirtualBox 都可以。

    如果使用 Windows 虛擬機器,你需要保證 Windows 能夠通過網路訪問 Mac。也就是說,你需要在 Windows 下 Ping 到 Mac 的 IP 位址。

  • 對於純 Windows 使用者,那麼現在、馬上去買一台 Mac。我在這裡等你!如果不行,就使用 MacinCloud 或 Macminicolo 之類的雲端服務吧。

本教程假設你有單獨的 Mac 和 Windows 電腦,當然,對於在使用 Mac 下使用 Windows 主機的人來說,本教程也是適用的。

安裝 Xcode 和 Xamarin

下載、安裝 Xcode 到你的 Mac 電腦上,如果你還沒有這樣做的話。這個和從市集安裝其他 app 並無不同,只不過有好幾 G 大,需要的時間長一點。

裝完 Xcode 之後,下載 Xamarin Studio 到 Mac 電腦上。不用填寫 email 地址,下載是免費的。插一句:是不是覺得很爽——這不需要犧牲你的任何一種咖啡為代價!

下載完成後後,開啟安裝包,雙擊 Install Xamarin.app。接收協議條款,點擊 continue。

安裝器會自動找到已經安裝的工具並檢查當前作業系統版本。它會顯示一個開發環境列表。勾上 Xamarin.iOS,點擊 continue。

然後你會看到一個確認清單,列出了將要安裝的內容。點擊 continue。然後你會看到一個概要,以及一個啟動 Xamarin Studio 的選項。直接點 Quit 完成安裝。

安裝 Visual Studio 和 Xamarin

在本教程中,你可以使用任意版本的 Visual Studio,甚至是免費的社區版。社區版的功能並不完全,但完全不影響你開發複雜的 app。

你的 Windows 當你必須滿足 Visual Studio 的最小系統需求。要獲得比較順暢的開發體驗,至少需要 3 GB 的記憶體。

如果你沒有安裝過 Visual Studio,你可以從社區版網頁上點擊綠色的社區版2015按鈕,下載社區版的安裝器。

運行安裝器,開始安裝,選擇定製安裝選項。在特性列表中,展開跨平台手機開發,然後選擇 C#/.NET(Xamarin v4.0.3)(本教程編寫時的版本,很可能會有不同)。

點擊 Next,等待安裝完成。時間有點長,你可以站起來走一下,消化掉安裝 Xcode 時吃的餅乾 :]

如果你已經裝過 Visual Studio 但沒有 Xamarin tools,進入 Windows 的 Programs and Features,找到 Visual Studio 2015,選擇它,點擊 Change,然後選擇 Modify。

在 Cross Platform Mobile Development 下面找到 Xamarin,即 C#/.NET (Xamarin v4.0.3),勾選它,點擊 Upate 以進行安裝。

呼——裝的東西真多,但總算是搞定了!

編寫 app

開啟 Visual Studio,選擇 File\New\Project。在 Visual C# 下面,展開 iOS,選擇 iPhone -> Single View App 模板。這個模板建立一個只有一個 view controller 的 app,view controller 是 iOS app 中用於管理檢視的類。

無論 Name 還是 Solution Name,都請輸入 ImageLocation。選擇項目儲存路徑,然後點擊 OK,新項目就建立好了。

Visual Studio 會提示你需要指定一台 Mac 電腦作為 Xamarin 的 buid 主機:

  1. 在 Mac 電腦上,開啟系統喜好設定,選擇共用。
  2. 開啟遠程登入。
  3. 將“允許訪問”改為“僅這些使用者”,然後添加將用於訪問 Mac 上的 Xamarin 和 Xcode 的使用者。

  4. 關閉視窗,返回 Windows 電腦。

回到 Visual Studio,在要求你指定一台 Mac 作為 build 主機時,選擇你的 Mac 電腦,然後點擊 Connect。輸入使用者名稱密碼,點擊 login。

你可以查看工具列,檢查是否已經串連成功。

從 Solution Platform 下拉框中選擇 iPhone Simulator,這將自動選擇 build 主機的一個模擬器。如果要改變為其他模擬器,可以點擊當前模擬器右邊的小箭頭。

按下綠色的 Debug 箭頭或者 F5 快速鍵,編譯運行程式。

編譯完成後,你卻不能在 Windows 上看到任何效果。因為它運行在你的 Mac (build 主機) 上。這就是為什麼最好將兩台機器盡量靠近的理由!

在前幾天的 Evolve 大會上,Xamarin 宣布將推出 iOS Simulator Remoting ,它能夠讓你和運行在蘋果 iOS 模擬器上的 app 進行互動,就像在 Windows PC 上運行了一個模擬器一樣。但在目前,你仍然需要和運行在 Mac 上的模擬器打交道。

在模擬器上,你會看到一個啟動畫面閃現,然後顯示一個空的視窗。恭喜你!你的 Xamarin 能夠正常工作了。

要停止 app,可以點擊紅色的 Stop 按鈕(Shift+F5 快速鍵)。

建立 Collection View

這個 app 會顯示給使用者一個 Collection View,以展示使用者相簿中的縮圖片。Collection View 是一個 iOS 控制項,以網格形式顯示多個條目。

要編輯 app 故事板中的“情境”,請從解決方案管理器中開啟 Main.storyboard。

在工具箱中的搜尋欄中,輸入 collection 字樣進行過濾。將 Data View 下面的 Collection View 對拖到空白的視圖中央。

選擇 Collection View,你會看到它四周出現一些空心的小圓圈。如果你看到的是 T 字而不是小圓圈,請再點它一次,即可切換到小圓圈。

點擊並拖動每個小圓圈直到看見藍色線條後放開滑鼠按鍵,控制項的邊緣就自動對齊到線條所在的地方。

然後設定 Collection View 的自動布局約束,自動布局約束用於告訴 app 當裝置旋屏時視圖應當如何重新改變大小。在故事板上邊的工具列中,點擊 CONSTRAINTS 字樣右邊的綠色的加號按鈕。這將自動為 Collection View 建立約束。

自動建立的約束大部分正確,但也需要對其中一些進行調整。在屬性視窗中,切換到 Layout 標籤,拉到 Constraints 一欄。

邊距中的兩個約束是正確的,但寬高約束不正確。刪除 Width 和 Height 約束(點擊它們右邊的 X 按鍵)。

注意,Collection View 此時變成橙色。這表明約束不正確。

點擊 Collection View 以選中它。如果你看到之前一樣的圓圈,再點擊它一次切換到綠色的 T 字表徵圖。點擊並拖放 Collection View 上端的 T 字直到綠色的名為 Top Layout Guide 的外框處。放開滑鼠左鍵,這將建立一條相對於視圖頂部的約束。

然後,點擊並向左拖放 Collection View 左邊的 T 字直到看到一條藍色的虛線。放開滑鼠左鍵,這將建立一條相對於視圖左邊緣的約束。

這時,你的約束應該是這樣的:

配置 Collection View Cell

看見 Collection View 中的小方塊了嗎?在這個方塊中有一個紅色的驚歎號。這就是一個 Collection View Cell,表示 Collection View 中的一個儲存格。

要配置這個 cell 的大小,需要在 Collection View 中進行。選中 Collection View,上拉到 Layout 標籤的頂部。在 Cell Size 小節,將其 Width 和 Height 設定為 100。

然後,點擊 Collection View Cell 中的紅色驚歎號,這將彈出一個提示視窗,說你還沒有為 cell 分配一個 reuse identifier。因此,選中 cell,開啟 Widget 標籤,下拉到 Collection Reusable View 小節,將 Identifier 設定為 ImageCellIdentifier。這將讓這個錯誤消失。

繼續下拉,來到 Interaction 小節,將 Background Color 設定為 Predefined 中的藍色。

現在,情境效果變成:

上拉到 Widget 節頂部,將 Class 設定為 PhotoCollectionImageCell。

Visual Studio 會自動建立同一類名的類,繼承 UICollectionViewCell,並自動建立一個 PhotoCollectionImageCell.cs 檔案。唉,什麼時候 Xcode 才能和 Visual Studio 一樣?!

建立 Colleciton View 資料來源

你還需要建立一個類,充當 UICollectionViewDataSource,為 Collection View 提供資料。

在解決方案管理器的 ImageLocation 上右擊,選擇 Add \ Class, 類名為 PhotoCollectionDataSource.cs 然後點擊 Add。

開啟新建立的 PhotoCollectionDataSource.cs,然後在檔案頂部寫入:

using UIKit;

這將匯入 iOS UIKit 架構。

然後是類定義:

public class PhotoCollectionDataSource : UICollectionViewDataSource{}

還記得你為 Collection View Cell 定義的 reuse identifier 嗎?在這裡我們將會用到它。在類定義中加入:

private static readonly string photoCellIdentifier = "ImageCellIdentifier";

UICollectionViewDataSource 類中有兩個抽象方法必須實現。在類中加入:

public override UICollectionViewCell GetCell(UICollectionView collectionView,     NSIndexPath indexPath){    var imageCell = collectionView.DequeueReusableCell(photoCellIdentifier, indexPath)       as PhotoCollectionImageCell;    return imageCell;}public override nint GetItemsCount(UICollectionView collectionView, nint section){    return 7;}

GetCell() 方法負責提供一個用於在 Collection View 中顯示的 cell。

DequeueReusableCell 方法會重用那些不再使用的 cell,例如那些已經不需要在螢幕上顯示的 cell,然後返回該 cell。如果沒有可重用的 cell,則會建立一個新的 cell。

GetItemsCount 方法負責告訴 Collection View 需要顯示多少(7 個) cell。

然後需要在 ViewController 類中添加一個 Collection View 的引用,ViewController 就是管理著 Collection View 的那個 Scene。回到 Main.storyboard,選擇 Collection View,來到 Widget 標籤,將 Name 設為 collectionView。

Visual Studio 會自動在 ViewController 類中建立一個名為 collectionView 的執行個體變數。

注意,在 ViewController.cs 中你無法看到這個執行個體變數。要看到這個變數,你需要點擊 ViewController.cs 左邊的右箭頭,以開啟 ViewController.designer.cs。這裡才看得見 Visual Studio 為你建立的執行個體變數。

從解決方案管理器中開啟 ViewController.cs,在類中添加如下欄位:

private PhotoCollectionDataSource photoDataSource;

在 ViewDidLoad()最後,添加代碼,初始化資料來源並將它綁定到 Collection View:

photoDataSource = new PhotoCollectionDataSource();collectionView.DataSource = photoDataSource;

這樣,photoDataSource 就能夠為 Collection View 提供資料了。

編譯運行程式。你會看到 Collection View 顯示了 7 個藍色方塊。

好極了—— 一切順利!

顯示照片

藍色方塊搞定了,接下來是將資料來源變成從裝置中擷取的圖片,然後在 Collection View 中顯示它們。你將用 Photos 架構訪問來自 Photos app 的照片、視頻。

接下來,你需要在 cell 中加入一個 Image View。開啟 Main.stroyboard,選擇 Collection View Cell。在 Widget 標籤,下拉並設定 Background Color 為預設。

在工具箱中,搜尋 image view,然後拖一個 Image View 到 cell 中。

Image View 的預設大小比 cell 大,要修改其大小,選擇這個 Image View 然後在 Properties \ Layout 標籤的 View 小節下面,將 X 和 Y 設為 0 ,Width 和 Height 設為 100。

切換到 Widget 標籤,將 Name 設定為 cellImageView。Visual Studio 會自動建立一個名為 cellImageView 的變數。

拉到 View 小節,將 Mode 設為 Aspect Fill。這將防止圖片被縮放。

注意:在 PhotoCollectionImageCell.cs 中無法看到 cellImageView 變數。這個類是部分類別,這個變數在另外一個檔案中。
在解決方案管理器中,點擊 PhotoCollectionImageCell.cs 左邊的箭頭,展開它。開啟 PhotoCollectionImageCell.designer.cs,你將看到 cellImageView 變數聲明。

這個檔案是自動建立的,不要去改變它。否則,它們會在你不知道的情況下被覆蓋,或者導致類和故事板之間的綁定被打斷,從而導致執行階段錯誤。

這個變數不是公有的,因此別的類無法訪問它。因此,你需要提供一個訪問它的方法,以便我們能夠改變 Image View 上顯示的圖片。

開啟 PhotoCollectionImageCell.cs 添加如下方法:

public void SetImage(UIImage image){    cellImageView.Image = image;}

現在你可以讓 PhotoCollectionDataSource 去抓取照片了。

在 PhotoCollectionDataSource.cs 的頂部:

using Photos;

在 PhotoCollectionDataSource 增加變數:

private PHFetchResult imageFetchResult;private PHImageManager imageManager;

imageFetchResult 變數用於儲存照片對應 Asset 的數組,然後通過 imageManager 對象來擷取照片資料。
在 GetCell() 方法前,添加構造方法:

public PhotoCollectionDataSource(){    imageFetchResult = PHAsset.FetchAssets(PHAssetMediaType.Image, null);    imageManager = new PHImageManager();}

這個構造方法從 Photos app 中抓取所有圖片資源,並將結果放到 imageFetchResult 變數中。然後初始化 imageManager,app 用它來查詢每一張照片的具體資料。

在構造方法下面,添加析構方法,將 imageManager 對象釋放:

~PhotoCollectionDataSource(){    imageManager.Dispose();}

在 GetItemsCount 和 GetCell 方法中用新資料來源中的圖片替換原來的空 cell。修改 GetItemsCount() 方法為:

public override nint GetItemsCount(UICollectionView collectionView, nint section){    return imageFetchResult.Count;}

修改 GetCell 方法為:

public override UICollectionViewCell GetCell(UICollectionView collectionView,     NSIndexPath indexPath){    var imageCell = collectionView.DequeueReusableCell(photoCellIdentifier, indexPath)         as PhotoCollectionImageCell;    // 1    var imageAsset = imageFetchResult[indexPath.Item] as PHAsset;    // 2    imageManager.RequestImageForAsset(imageAsset,         new CoreGraphics.CGSize(100.0, 100.0), PHImageContentMode.AspectFill,        new PHImageRequestOptions(),         // 3         (UIImage image, NSDictionary info) =>        {           // 4           imageCell.SetImage(image);        });    return imageCell;}

以上代碼分別進行說明如下:

  1. indexPath 表明當前將返回哪一個 cell 。其 Item 屬性工作表示了 cell 的索引。 我們根據這個索引獲得圖片資源並將之轉換為 PHAsset 對象。
  2. 用 imageManager 對象去請求擷取 PHAsset 所對應的圖片,同時指定了所需圖片的大小和縮放模式。
  3. 許多 iOS 架構中的方法都會在執行耗時任務時使用順延強制,當任務完成時再調用委託方法。以 RequestImageForAsset 方法為例,當請求完成時,委託方法將被調用,所請求的圖片和相關資訊將通過參數傳遞到委託方法。
  4. 最後,設定 cell 中的圖片。

編譯運行。你會被詢問需要存取權限。

如果你選擇 OK,app 什麼也不會顯示。搞毛啊!

iOS 認為照片屬於使用者的敏感資訊,需要經過使用者授權。但是當使用者同意授權之後, app 也必須註冊接收相應的通知,以便重新重新整理視圖。也就是你接下來的工作。

註冊照片訪問授權通知

首先,你需要在 PhotoCollectionDataSource 類中增加一個方法以便當照片庫內容發生改變後重新抓取資料。在類中加入以下方法:

public void ReloadPhotos(){    imageFetchResult = PHAsset.FetchAssets(PHAssetMediaType.Image, null);}

然後,開啟 ViewController.cs 匯入 photos 架構:

using Photos;

在 ViewDidLoad() 方法中:

// 1PHPhotoLibrary.SharedPhotoLibrary.RegisterChangeObserver((changeObserver) =>{    //2    InvokeOnMainThread(() =>    {        // 3        photoDataSource.ReloadPhotos();        collectionView.ReloadData();    });});

上述代碼負責:

  1. 將 app 註冊為接收照片庫改變通知,當照片庫內容改變時調用指定代碼。
  2. InvokeOnMainThread() 方法在主線程中重新整理 UI,否則會導致 app 崩潰。
  3. 調用 photoDataSource.ReloadPhotos() 重新擷取照片,調用 collectionView.ReloadData() 讓 Collection View 重繪。

最後,我們來解決前面的問題,在 app 還沒有得到相簿存取權限時,請求使用者授權。

在 ViewDidLoad() 方法中,在初始化 photoDataSource 之前加入:

if (PHPhotoLibrary.AuthorizationStatus == PHAuthorizationStatus.NotDetermined){    PHPhotoLibrary.RequestAuthorization((PHAuthorizationStatus newStatus) =>    { });}

這裡需要檢查當前授權狀態,如果使用者未授權,提示使用者進行授權。
為了再次提示使用者授權,你需要通過 Simulator \ Reset Content and Settings 重設模擬器。

編譯運行。你會看到照片訪問授權的提示,如果你選擇 OK,這個 app 會在 Collection View 中顯示照片的縮圖!

結束語

你可以從這裡下載完整的 Visual Studio 項目。

在本教程中,你學習了如何配置 Xamarin 以及如何用它來建立 iOS app。

在 Xamarin 指南網站 有幾個優秀的學習資源。要瞭解更多關於建立跨平台 app 的內容,請查看 Xamarin 教程關於建立同一應用的 iOS 和 Android app。

微軟收購 Xamarin 後做出了一些令人讚歎的改變。 在微軟的 Build 打回和 Xamarin Evolve 中你會看到這種傾向。Xamarin 發布了最近 Evolve 大會的會議視頻,這些視頻詳細介紹了關於如何使用 Xamarin 的資訊和未來的產品方向。

你會用 Xamarin 建立 app 嗎?如果你對本文有任何問題建議,請在下面留言。

用Xamarin和Visual Studio編寫iOS App

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.