Xamarin + F# の話をいくつか

Xamarin Advent Calendar 2014 – Qiita
http://qiita.com/advent-calendar/2014/xamarin

の8日目の記事です。

まずは Xamarin で F# を使う入り口を

F# は関数型言語だとか、.NET ライブラリがそのまま扱えるとかという話はさておき(そこが利点だったりするわけですが)、まずは Xamarin で F# を使うときの入り口をみていきましょう。

F# Support Overview | Xamarin
http://developer.xamarin.com/guides/cross-platform/fsharp/fsharp_support_overview/

Xamarin のサイトとしては、この1ページしかありません(苦笑)。これ、F# が導入されたころから1ページしかなくて、その後1年経っても1ページしかないんですね。だからといって虐げられているわけではなくて、Xamarin のカンファレンスのビデオを見ると「F# F# F#」連呼していたりする(英語の合間ですが)ので、それなりに重きを置いている言語です。少なくとも VB に対するそっけなさよりも手厚い感じです。

F# 本家のサイトにも Xamarin との連携ページがあって

Use F# for iOS App Development | The F# Software Foundation
http://fsharp.org/use/ios/

こんな風に勉強会のビデオがあります。この解説をしている Rachel Reese さんが発表しているのは、New York City F# User Group なんですが、所属が NYC Mobile .NET Developers Group ってところで、ここのスポンサーに Xamarin と Microsoft が並んでいます。ちなみに Reese さんは、F# MVP  で Xamarin 社とは無関係です(どちらかというと F# 寄りな人)。

このあたりの関係は、以前書いた

Xamarin.iOS/android+F#で作る関数型アプリ
http://www.slideshare.net/moonmile/xamarini-osandroidf

の参考リンクから辿って行けます。

でもって、F# を使って Xamarin.iOS/Android を作る入門編なページを探す訳ですが「ありません」。これは、Xamarin Studio 自体に F# のテンプレートが導入れて間もないのと(1年位しか経ってない?)、ライブラリのあれこれの整合性が大変だったり、そもそも F# を使っているプログラマ人口が少なかったり(あわせて Xamarin を使っている人口もそれなりに少ないだろうし)ってことで、そういうのがありません。
最初のプロジェクト自体は、先の Xamarin のドキュメントにあるように作成できるようにしてあるのですが、その先がなかなか大変です。

F# と Xamarin を同時に学ぶ…ってのは不可能ではないけれども、同時にやるのは大変なので、

  • F# を学んだあとに、ライブラリとして Xamarin に組み込む
  • Xamarin を使いこなした後で、F# に置き直しておく

というアプローチがお勧めです。

どんなところで F# を使うのか?

Xamarin のサンプルも Microsoft のサンプルも C# が一番充実している(というか、唯一になりつつありますが)ので、C# 以外の選択をする場合にはそれなりに理由が要りますよね。Javascript で書くから Cordova、C# で書くから Xamarin、Objective-C/Swift で書くから Xcode みたいなものです。それぞれの利点と欠点を踏まえたうえで(特に欠点を踏まえたうえで)、組み合わせを選択する落とし穴にはまりづらくなります。

端的に言えば、「C# の苦手な部分」あるいは「F# でないと実現できない部分」を見つけて C# と置き換えるのがベターです。

MvvmCross や Xamarin.Forms を使って MVVM パターンを利用すると、自然と View と Logic をライブラリ単位で分けることができます。PCL を使って分けてもよいし、ターゲットが iOS だけなれば、Xamarin.iOS だけ利用するネイティブのライブラリを作ってわけても構いません。PCL にしてしまうと、使えるライブラリが減ってしまったり、DI パターンを利用する必要があったりするので、さくっと作りたいときに不便なので使い分けをします。

この図で行けば、4パターンが考えらます(全体を F# で書く場合も含めると5パターンになるけどそれは別の機会に)。View に F# を使うときは、PCL の Xamarin.Forms を通す場合と、ネイティブの Xamarin.iOS を直接扱う場合。ロジックに含む場合には、ネイティブのデバイス(カメラやGPS)を触る場合と、全く触らずにロジックだけで完結する場合ですね。

F#単独のライブラリを作る

1番導入しやすいのは、ロジックだけで完結する場合ですね。ロジックだけで完結しているので、NUnit が使いやすいし、他のライブラリを使うわけではないのでテストがしやすくなります。このあたりは、普通に C# のライブラリを作るときと変わりませんね。
計算ロジックとかパズルロジックとかを F# で書いて、ユーザーインターフェースを C# で書くパターンがこれです。パズルロジック自体は、NUnit などを使ってテストしたり、別の UI(WPFとか)を使って作れるので便利です。Xamarin との組み合わせではありませんが、F# + OpenCvSharp の画像フィルタをこのパターンで作ったりしています。

特定のデバイスをF#で扱う

特定のデバイスを扱う部分をライブラリ化しますが、これを F# で作るパターンです。この場合、ネイティブのライブラリが C#(内部的には Objecive-C や Java)で提供されているために、あまり F# を使うメリットは無いように見えるのですが…、実はフィルタ絡みとかイベント絡みを書くときに F# は便利です。パイプライン演算子「|>」を使うのと、カリー化をうまく利用すると柔軟にフィルターが作れます。
あとは、デバイスへのアクセスを F# Interactive で動かせるように単独化させておくと、実験などが楽になります。

Viewを扱う部分を F# で書く

moonmile/XFormsPreviewer
https://github.com/moonmile/XFormsPreviewer

では、Xamarin.Forms の XAML を自前でパースしていますが、このようなコードを書くときに F# は便利です。字句解析とクラス生成あたりが素直に書けるのが F# のよいところです。同じコードは C# でも書けるのですが、かなり冗長になります。この場合、ネックだったのが既存のパーサライブラリを使えない(PCL用のパーサがなかった)ってのがあって、F# で自前で書いています。

Xamarin.formsとカスタムコントロールの話
http://www.slideshare.net/moonmile/xamarinforms-41882310

の中にある、カスタムコントロールなところは、F# で書いても十分有効なところです。データバインドとかカスタムセルのところも作りやすいところです。

とはいえ、ハイブリッド特有の落とし穴がある

これは将来的に直るかもしれませんが(One.NETというスタイルで)、現状では、ネイティブアセンブリと、PCL の各種で使えるライブラリが異なるので、ここかかなりネックになります。多くの場合は、DI として Xmarin.Forms の中からネイティブのUIクラスを使うようにインターフェースを切るか、ネイティブそのものでリビルドをしてしまいます。ソースコードが社内や個人持ちであれば、コード共有してリビルドのほうがいいのですが、NuGet などの配布を考えるとクラス設計をして PCL 化しないといけません。ただし、NuGet が絡むと C# でも F# でも事情は同じで、PCL からネイティブのクラスを触るときに問題がでてきます。そのあたりプロジェクト扱いは、次期の Visual Studio 2015 で変わるので、それに次期?Xamarin Studio がどのように対応していくのか、によって F# で作るライブラリの扱いが変わってくるでしょうね。

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