將Xamarin.Forms的Droid與iOS專案轉換使用NuGet v3和Project.json管理套件

將Xamarin Droid與iOS專案轉換使用NuGet v3和Project.json管理套件

Xamarin develop platforms

前一篇 將Xamarin的PCL專案升級轉換為.NET Standard Library 我們將 Xamarin 跨平台裡的 PCL 專案轉換為使用 .NET Standard Library,但這只完成整個 Xamarin 專案的其中一個專案,其實並未算是把整個 Xamarin 專案完全使用 .NET Standard Library 目標,目前這個當下(或許 Visual Studio 2017 會改善),還有許多工作需要人工作業,讓我們一步步來將整個專案完成轉換。

Xamarin.UWP專案使用PC的Xamarin.Forms套件

在完成 PCL - .NET Standard Library 轉換後,我們先挑軟的吃。我們來把 UWP 專案裡的 Xamarin.Forms 套件給移除。

Remove UWP Xamarin.Forms

移除後進行建置動作:

Build UWP without Xamarin.Forms

我們能發現 UWP 專案非常順利完成建置。證明 UWP 專案能順利使用的 PCL - .NET Standard Library 環境了。

注意,如果你在改用 PCL - .NET Standard Library 之前有建置過,建議,先清除後再建置。

移除 Xamarin.iOS 專案的 Xamarin.Forms 套件

我們先建置 Xamarin.iOS 專案看看:

Build iOS with Xamarin.Forms

在未移除 Xamarin.Forms 套件之前,Xamarin.iOS 一樣能正常建置。但當我把 Xamarin.Forms 套件移除後,並能未像 UWP 專案一樣能順利完成建置動作。

Build iOS without Xamarin.Forms

NuGet v3 與 project.json

先讓我們離題一下,還記得前一篇,當我們第一次要升級至 .NET Standard Library 時出現一個 NuGet v3 的錯誤訊息嗎?其實那個錯誤蠻關鍵的,為什麼,往下看就知道了。

NuGet 3.0 錯誤

你有沒有很好奇,同一個 Xamarin 專案,為什麼 UWP 專案可以順利吃到新的 PCL - .NET Standard Library,但其他(iOS、Droid)都無法移除 Xamarin.Forms 套件,還是必須安裝 Xamarin.Forms 套件才能順利通過建置。

It doesn't make sence!

事出必有因,其中的差異在專案中一個非常細小的差異點:packages.configproject.json

如果你重新新增一個 Blank App(Xamarin.Forms Portable) 專案,注意看一下每個專案檔下的套件管理檔,你就能發現,除了 UWP 是採用 project.json,其他所有專案都是用 packages.config。

packages.config project.json

packages.config 是我們非常熟悉 XML 組態檔:

例如,原始 PCL 專案的 packages.config 的內容:

<?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="Xamarin.Forms" version="2.2.0.45" targetFramework="portable45-net45+win8+wp8+wpa81" />
 </packages>
 

這種方式為 NuGet v2 所採用的管理方式,其中指定了 NuGet Id、版本與targetFramework。targetFramework 就是我們前篇有提到的 TFM(Target Framework Moniker) 這個專有名稱,也就是我們最後轉換到 .NET Standard Library 後指定到 project.json 的 imports 的值。再看一次轉換後的 project.json:

{
   "supports": {},
   "dependencies": {
     "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
     "NETStandard.Library": "1.6.1",
     "Xamarin.Forms": "2.3.3.175"
   },
   "frameworks": {
     "netstandard1.4": {
       "imports": "portable-net45+wpa81+wp8+win8"
     }
   }
 }
 

轉換為 .NET Standard Library 的 PCL 改採用了 NuGet v3 的組態管理,這就是為什麼我說一開始那個 NuGet v3 的錯誤訊息是個關鍵。在比對 UWP 的範本就能瞭解,UWP 範本從一開始就採用 NuGet v3 在管理套件,所以在我們轉換 PCL 之後,UWP 專案能非常順利吃到一樣使用 NuGet v3 的 PCL 並通過建置,不是沒有道理的。

知道問題點後,就是接下去處理 Xamarin.iOS 與 Xamarin.Droid 的問題。

升級 Xamarin.iOS 採用 NuGet v3 與 project.json

  • 僅 Visual Studio 2015 Update 1 之後才支援 project.json 組態。
  • 如果使用 TFS Team Build,你需要 TFS 2015 Update 1。
  • 如果你使用 git 版控,那麼確認 .gitignore 檔包含:*.lock.json*.nuget.props*.nuget.targets 三組設定。

以下是你會需要的 project.json 範本:

{
     "dependencies": {
     },
     "frameworks": {
         "net452": { }
     },
     "runtimes": {
         "win": { }
     }
 }
 

裡面只有指定專案目標使用 .NET Framework 4.5.2,這裡指定採用短簡稱(short moniker)。

前置檢查作業

刪除 packages.config (最好先備份)。

我自己從新 Xamarin 專案製作 .NET Standard 範本的經驗來看,只要把專案的 NuGet 套件移除到 packages.config 不見了,應該就符合以下條件。後續如果有建置問題,再回來一一檢查即可。

  1. 然後卸載專案(unload project)。編輯 *.iOS.csproj
  2. 移除所有 .props 檔案(看來指向 \packages 目錄)的 NuGet 設定。
  3. 尋找所有包含 HintPath<Reference> 元素,刪除它們。
  4. 移除所有 NuGet 加入的 .targets 檔案設定。還有 NuGet 加入的 targets 或 Task,類似:<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
  5. 如果有任何套件包含 Roslyn Analyzers,請移除它們。

加入 project.json

利用前面的 project.json 範本或從 PCL / UWP 複製至 iOS 專案,修改內容如下:

{
   "dependencies": {
   },
   "frameworks": {
     "Xamarin.iOS,Version=v1.0": {
     }
   },
   "runtimes": {
     "win": {}
   }
 }
 

確認 project.json 的屬性「建置動作:None」,None 應該是預設值。

此時進行建置,會得到大一堆的錯誤。這是因為 PCL 的 project.json 多加入一個 Microsoft.NETCore.Portable.Compatibility 套件造成。從 NuGet 網站的說明來看:

Enables compatiblity with portable libraries targeting previous .NET releases like .NET Framework 4.0 and Silverlight.

這反而影響到我們,請回到 PCL 專案移除此行設定:

{
   "supports": {},
   "dependencies": {
     "NETStandard.Library": "1.6.1",
     "Xamarin.Forms": "2.3.3.175"
   },
   "frameworks": {
     "netstandard1.4": {
       "imports": "portable-net45+wpa81+wp8+win8"
     }
   }
 }
 

清除 PCL 專案與重新建置,確定 Microsoft.NETCore.Portable.Compatibility 不在參考列表中。

清除 Xamarin.iOS 專案與重新建置:

Build iOS with NuGet v3

Xamarin.iOS 已經順利升級為 NuGet v3 的管理方式,Xamarin.Forms 套件也移除並且建置也都正常。

升級 Xamarin.Droid 採用 NuGet v3 與 project.json

有了 Xamarin.iOS 的經驗,那麼 Xamarin.Droid 專案就簡單了。

首先把 NuGet 中所有 Xamarin.* 套件依順序完全移除:

  1. Xamarin.Forms
  2. Xamarin.Android.Support.v7.CardView
  3. Xamarin.Android.Support.v7.MediaRouter
  4. Xamarin.Android.Support.Design
  5. Xamarin.Android.Support.v7.AppCompat
  6. Xamarin.Android.Support.v4

和前面一樣,新增或複製修改 project.json 都行:

{
   "dependencies": {},
   "frameworks": {
     "MonoAndroid,Version=v7.0": {}
   },
   "runtimes": {
     "win": {}
   }
 }
 
Build Droid with NuGet v3

系列文章:

小結與參考資料

透過以上整理與修改後,我們就可以得到一個完整使用 .NET Standard 的 Xamarin 專案。

沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。