xamarinとmvvm crossとf#と
DESCRIPTION
Xamarin開発でMvvmCrossとF#使って開発してるのでその辺もろもろとTRANSCRIPT
XamarinとMvvmCrossとF#と
自分について
宮坂雅彦
@omanuke
主に株式会社トレードワークスという会社で金融向けのソフトを作成
F#大好き
でもモナドとかよくわかってない
アジェンダ
• 今回やってるものサラッと説明。
• MvvmCross使ってみてあれこれ。
• F#のおすすめ。
• HTML5とのソース共有
• 独自レイアウトツールについてさらっと。
• Xamarinについて所感。
今回やってるもの構成
• サーバーはWebAPI
• VM以上をF#で作成
• C#でアプリケーションスタートアップとUI周り
• フレームワークとしてMvvmCross
• ViewのレイアウトはAutoLayoutが糞っぽい難しいのでXAMLライクな独自レイアウトツール作成
サーバーWebAPI
サービス
ViewModel
UIViewController
レイアウト
Mvvm
Cro
ss
AppDelegate
F#
C#
Xamarin
• C#でiOS/Androidなど含めクロスプラットフォーム開発できる環境
• ベースはMono。元MonoTouch・MonoDroidといわれていたもの。
• ネイティブアプリを開発できる。iOSはAOTコンパイル。AndoirdではJIT。
• Mac向けもある。まだ成熟してないらしい…
• MSもがっつり協力してる模様
MvvmCross
• iOS、Android、WindowsPhone、WindowsStoreApp、WPF
など様々なプラットフォームに対応したMVVMフレームワーク。
• バインディングの他、サービスの登録、それをDI的に使うなどアプリケーションフレームワーク的な仕組みも。
• ネイティブな機能を抽象的に扱えるプラグイン機能なども(使ってないのでよくわかりません)。
MvvmCrossを使う上で調べたところ
• アプリケーション全体の構成
• バインディングどこまでできるのか
• サービスの登録や利用、DI機能あるのか
• ナビゲーション含む画面の単位とVMとの関係
• それに絡んでタブビューでどう使えるのか
• Viewの中に子ViewなどVMとバインディングしつつ部品化できるのか
• コレクションの表示はどうなるのか
アプリケーション全体の構成
• MvxApplication-PCL側でServiceの登録やStartup画面登録など。
• Setup-NativeUI側でMvxApplication
の初期化など含むもろもろの初期化。それらのカスタマイズフック。
• AppDelegateなどからSetup.Initialize
呼び出してIMvxAppStartをResolveしてStart。
MvxApplication
RootVM
Setup
AppDelegate
RootView
Controller
登録
Start
Initialize
VM元に生成
Start時に生成
バインディングどこまでできるのか
• INotifyPropertyChangedでのプロパティバインディングとそのConverterによる変換。
• コマンドバインディング。
• ObservableCollection使ってのコレクションのバインディング。
• UIButtonのTitleなどプロパティじゃないものにもできる拡張あり。
• VMの中のVMなどネストしたVMに対してプロパティパス指定してバインド(一昨日知りました(-_-;))。
サービスの登録や利用、DI機能あるのか
• Mvx.RegisterSingleton<IHoge>(()=>new Hoge())などあるインターフェースに対する具象クラスを登録して、使うときにResolveしてひっぱってこれる。
• 開発時やテスト時にサーバーにリクエストするものの代わりにモックをRegistしとくなど。
• Mvx.Resolve<IHoge>としてひっぱってきたりコンストラクタインジェクションなどでDIすることもできます(ほかのパラメータ渡したいときはInitメソッド使う)
ナビゲーション含む画面の単位とVMの関係
• VMが画面1ページとしか表示出来ないのなら色々めんどくさいと思っていたけれど、VMからUIViewController引っ張って何とでもなりそう。
• VMとUIViewControllerを結び付ける手段はネーミングコンベンションやらその型のViewModelプロパティを定義するなど色々。
• Mvx.Resolve<IMvxTouchViewCreator>.CreateView(viewModel) as MvxViewControllerでVMより該当のUIViewControllerをひっぱる。
• 普通のUIViewControllerとMvxViewControllerの混在とか問題ない(はず)。
タブビューでどう使うのか
• タブのサンプルあるのでそれもとに解決。さっきのVMからViewControllerを引っ張る方法はそれからソース追っかけて探したはず…
• ざっくりいうとタブとして表示したい画面のもととなるVMをどっかから引っ張ってきてそれ元にViewController作ってUITabBarControllerのViewControllersにセットするなど。
• これ含めハンバーガーメニューなどのやり方のサンプルなどもググれば出てくるはず。
Viewの中に子ViewなどVMとバインディングしつつ部品化できるのか
• さっきも言ってたようにできる。VMの中にVMネストもできるので部品化も可。
• UI側は各VMに対応したViewControllerを定義して小分けするもよし、親のViewControllerだけ定義して子のVMにバインドするもよし。プロパティパスだけ合えばおけー。
• 各VMに対応したViewController作るなら各々のViewControllerの中でBindingSetを定義して使用。
• 今回諸事情でネストした各VMに対応するViewをUIViewとする必要があったため、ルートのBindingSetをUIViewに渡してプロパティパス合わせて使用してる。VMの階層構造とUIの階層構造は関係ない。
コレクションの表示はどうなるのか
• MvxViewModel継承したものがはいってるObservableCollection
をMvxTableViewSourceおよびその派生クラスを介してMvxTableViewCell継承したものに結び付けてバインドできる。
• GetCellあたりでVMに応じたCellの作成を振り分けることでDataTemplate的なことができる(はず)。
• VMに応じて高さが可変なCellはDelayでBindされるのとHeightを返すタイミングが合わず自前でVMのないように応じた高さを計算してかえさないといけなかったような気がします…(結局試してないかも)
MvxTableViewCell
MvvmCrossのよいところ
• 一通り、アプリケーションのコードを共有する仕組みはある。
• 一番使われてる?
• ドキュメント・サンプルが充実してる。動画もあるんですが、だるくて見てません…
• カメラや地図などネイティブの機能を抽象的に使えるプラグイン機能もあるのでプラットフォーム展開したい人は便利そう(使ってないのでよくわかりません)
MvvmCrossの悪いところ
• ビヘイビアとかない?のでXAMLer的には不満?
• iOSではバインディングとかC#で書かないと。
• バインディングの記法がやたらありませんかね…TibetとかSwissとか。歴史的な経緯?
• XamarinFormsとかまともになってくるといらない子になる?
• まだUnifiedAPIに対応してない?ので来年2月のアプリ登録が64bit必須になるのに対応できるのか不安・・・
F#についてざっくり
• MS製の.NET向け関数型言語
• OCamlライクな文法
• 静的型付け
• 関数型とオブジェクト指向のハイブリッド
• デフォルトイミュータブルだが副作用を許容
• Actorや非同期処理など組み込み
• モナド的な仕組みもある(ComputationExpressions)
F#の良いところ
• モデルの定義や業務ロジックを書きやすい。
• コード量少なく、バグも少ない。
• 非同期処理や入力待ちなどが混在する状態遷移をそのまま記述可。
• javascript化してスマホやWebもワンソース化。
• Xamarinの中の人も推してくれてる。
モデルの定義や業務ロジックを書きやすい
• 代数データ型(Discriminated Union)、レコード型、タプルなどを使ってモデルの定義をクラスだけで表すよりもわかりやすく記述できる。
• それに対する処理もパターンマッチを分かりやすく書ける。
• 処理も型推論使ってコンパクトに書ける。C#だとタプル使おうとすると泣ける。
• 数値に単位をつけてより厳密に扱える仕組みもある。
• F#はとても良い業務記述言語です。
コード量少なく、バグも少ない
• 先ほどのコンパクトなモデル記述や型推論、関数の合成などを使うことで、無駄な記述のない密度の高いコードが書ける。
• 同じロジックを書いた場合、C#の30%ぐらいの量になるかと。
• ヌルリを起こさない仕組みなどが最初からあり、デフォルト状態変更ができないので、バグの原因となる副作用があるコードの箇所が特定される->副作用あることに意識的になる。
• C#でも副作用のないコードはかけるけどやはり書きにくい。C#はデフォルト副作用あり。F#はなし。
非同期処理や入力待ちなどが混在する状態遷移をそのまま記述可
• asynchronous workflowsという仕組みを利用。await/async
みたいなもの。
• Aからあるイベントが起きたらBという状態に遷移して、そこであるイベント起きたらCに遷移したりAに戻るなどの状態遷移をA,B,Cを対応したコードブロックとしてそのままかける。C#だと末尾再帰ができないのでスタックオーバーフロー起こす。
• UIのイベント待ちやサービスに対する非同期なリクエストなどもシームレスに書ける。
非同期処理や入力待ちなどが混在する状態遷移をそのまま記述可2
非同期処理や入力待ちなどが混在する状態遷移をそのまま記述可3
• 遷移する際に値を引き渡せるので状態の更新間違いなどが入りこむ余地がない。
• try-catch(with)の中でも使えます。
• 詳しくはこちらでC# と F# の Async: C# の非同期の落とし穴
• asynchronous workflowはasync/awaitと違い.NET2.0ターゲットでも使えます。
javascript化してスマホやWebもワンソース化
• WebSharper
F#で使える、AltJS。オプソにもなってるけど商用利用は有料。
ほんとはAltJSというよりもWebサーバーとのやり取りも一緒に書ける開発環境らしい。
気持ち開発者少ないような…日本人でまともに使ってる人他にいるのか不安(;´∀`)
javascript化してスマホやWebもワンソース化2
• 今回株式・FXなどのリアルタイムチャートをワンソース化した。
• F#といえども数千行あったのでjavascriptで書きなおすとかだるい->WebSharperでコードの共有かにチャレンジ。
• ロジックなどはほぼそのままで描画する部分などプラットフォームで違うところを抽象化して使用->95%をコード共有した(気がする)
• 出力されるコードも追いやすいのでデバッグなどで困ることもほとんどなかった。
javascript化してスマホやWebもワンソース化3
• とはいえ、それなりにめんどくさいですよと。
• 色々なものが使えない。string.Format的なのも使えないので泣ける。
• javascript化するところは属性をつけないといけなかったり#if#elseなどで記述分けしないといけなかったりでコードが汚く…
• けどものによっては十分にやる価値あり。
フル.NET
PCL
WebSharper
使える範囲
Xamarinの中の人も推してくれてる
• F#だけでiOSアプリ作れるなど一級市民扱い。
• Sketchesも使えるようになったらしい(beta?)リンク。
• いまだにWinRT用のライブラリすら作らせてくれないMS
の中の人よりもF#好きなんじゃないか疑惑。
F#の悪いところ
• いうてもF#使える人が少ない…
• PCLとして満足に使えるようになったのも去年。それまではMSのコンパイラ自体PCLコードをうまく吐けなかったとかどうとか。色々プロファイルに対応してないなど。
• PCL側がF#だとVSでないとデバッグしにくい。XSだとF#側に入ってくれない(最近試してません)
• この間までF#のPCLプロジェクト、XSでビルドできず。最近できるようになったけど、実行すると全く動かず。バイトコードが違うのかしら…
独自レイアウトツール
• AutoLayout、説明を見てもどうみても糞っぽ難しい。
• 前に作ったレイアウトライブラリがあったのでそれを使って独自レイアウトライブラリ作成。
• XAMLライクな記述。
– Grid
– StackPanel(的なもの)
– Margin,HorizontalAlignment,VerticalAignment
– コントロールの作成、プロパティの設定。
– Style
独自レイアウトツール2
独自レイアウトツール3
• ファイル更新検知してレイアウトを反映するようにした。
–シミュレータで実アプリを動かしながら編集して即反映できるので結構便利。
• 実行時に値によって別のレイアウトに差し替えるなどもできる。ViewState的な?UIView.Animationの中でやればいい感じにアニメしてくれる。
• XamarinFormsがよくなったらこれもいらなくなるかと思いつつ、動かしながらいじれるのは便利かとも思ってます。
Xamarin所感
• まだツールなど怪しいところもある。
–去年の今頃はひどかった・・・ベータのある特定のバージョンじゃないとVSと連携できないなど。うかつにあげると環境が壊れる。
–今も自分の環境ではVS->XS怪しい
• VSからだと実機デプロイができない。XSからでしのぐ。
• DebugSessionの開始時、一回は必ず失敗する。続けるとデバッグできる。
–細かいがエディタも怪しい動きをすることが…特にXMLをコピペすると前後の行が表示上ずれる。
–でも最近は大分安定してきた感…
Xamarin所感2
• けど実行自体は安定している。
–いままで怪しい動きしてたのは実機デプロイ時にリフレクションだけで使ってたコードが削られてすっ飛んでたときぐらい。
• って書いてるそばから実機ではデザインが反映されない事象発生(;´∀`)これから調べる。
–それも実機上でデバッグしてとかで追えた気がする(古いことなので忘れました…)
–プロファイラとかもあるのでいろいろ調べられるかも(まだ使ってません)リンク
–スピードも特に問題ないような。ネイティブだともっと早いのかもですが比較してません。
Xamarin所感3
• とりあえずクロスプラットフォーム開発ツールとしてとても実用的なので、iOS,Androidに席巻されてもF#,C#の人もこれからしばらく困らなそう。
• AndroidWearとかAppleWatchとかWearableにも対応してくれる模様。
• 関係ないですが、サーバー側も.NETオプソ化されたのでますますF#,C#の人生きていくのに困らなくなりそうですね。