Xamarin.iOS/Android から F# PCL プロジェクトを使う方法

ちょっとトリッキーなので、後から Xamarin Studio 側が修正するような気もしますが、現状の回避策として。

■Xamarin.Forms を F# で使う

Xamarin.Forms は、PCL版とShared版があります。C# では “Mobile Apps” から どちらかのプロジェクトを選びますが、F# のプロジェクトにはこれがありません。じゃあ、F# では作れないのかというとそうではなくて、単純に、

– F# で PCL プロジェクトを作成する
– F# で iOS/Android プロジェクトを作成する
– iOS/Android プロジェクトから PCL プロジェクトを参照させる

という手順で Ok なハズです。PCL プロジェクト自体は、Xamarin Studio では作れないので、Visual Studio のほうで作りますが、後で述べるようにどっち作っても構わなそうです。
それぞれのプロジェクトに NuGet から Xamarin.Formss を入れてビルドが通る状態にしておきます。

iOS/Android プロジェクトから、PLC プロジェクトを参照設定したいところですが、参照設定ができません。この現象は、Visual Studio でも同じで…というか、Visual Studio では F# の iOS/Android プロジェクトが開けないので、Xamarin Studio 上でしかできません。

ひとつの方法としては、

F#のPCLプロジェクトをC#から参照するときにunable to add a reference to project… – omanuke-ekunamoの日記
http://d.hatena.ne.jp/omanuke-ekunamo/20140108/1389171418

のように、アセンブリの方を参照します。が、Xamarin.Forms の場合は、PCL 自体にロジックが入ることが多く、デバッグが結構手間なので、プロジェクト参照をさせます。

ちなみに、
– F# で作った PCL を C# プロジェクトから参照する。
– C# で作った PCL を F# プロジェクトから参照する。

ということは可能なのですが、なぜか F# から F# PCL だけが参照できません。

■ *.fsproj を開いて直接編集する

参照元(iOS/Android プロジェクト)の *.fsproj を開いて以下を追加します。

  <ItemGroup>
    <ProjectReference Include="../../WebBrickClientFs/WebBrickClientFs/WebBrickClientFs.fsproj">
      <Project>571E0A3B-E069-4B46-BBAC-B0F060351904</Project>
      <Name>WebBrickClientFs</Name>
    </ProjectReference>
  </ItemGroup>

ProjectReference に参照先のプロジェクト(PCLプロジェクト)fsprojを設定して、Project にプロジェクトGUIDを設定します。この部分は、C#からF# PCLを参照したときと同じものです。

そうして、Xamarin Studio で開くと、警告が出た状態ではありますが、参照ができるようになります。この状態でビルドも通ります。

■ビルドの警告はなぜでるのか?

ビルドをすると、こんな風な警告が出ます。

C:/Program Files (x86)/MSBuild/12.0/bin/Microsoft.Common.CurrentVersion.targets(5,5): Warning MSB3277: 同じ依存アセンブリの異なるバージョン間で、解決できない競合が見つかりました。 これらの参照上の競合は、ログの詳細度が詳細に設定されている場合にビルド ログにリストされます。 (MSB3277) (WebBrickClientFs.Android)

これは、それぞれのプロジェクトに入っている FSharp.Core のバージョンが異なるからなんですね。

Visual Stuido で作った F# PCL では、Reference Assemblies/Microsoft/FSharp/.NETCore/$(TargetFSharpCoreVersion)/FSharp.Core.dll を参照していますが、Android のほうでは、Reference Assemblies/Microsoft/Framework/MonoAndroid/v1.0/FSharp.Core.dll を参照しています。
.NETCoreのほうは、3.3.1 なのですが、MonoAndroid のほうは 2.3.1 なんですよね。これがずれてしまっているようです。ちなみに MonoTouch にあるのは 2.9.9 なのでこれもバージョンが違っています。おそらく、このバージョンが揃わない限り、先の警告が出てしまうようです。

■バージョンを揃えることができるのか?

試しに Xamarin.Forms.Core のバージョンを見ると PCL/Android/iOS ともに 1.1.1.0 になっています。おそらく、これを揃えればいいのでしょうが、現状の配布状況(Nuget にもいくつかの Fsharp.Core があります)をみると、揃えるのは難しそうですね。自前でビルドをすると、バージョンが揃うのかなと。このあたりは別途調べてみます。せめて、F# 3.0 なのか F# 3.1 なのかがわかるといいんだけど。

カテゴリー: F#, Xamarin パーマリンク