かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Xamarin.Forms と Azure の組み合わせサンプル書いてみたよ

Microsoft Cognitive Services を使ったサンプルを ABC 2017 Spring で作ってみたら動かなくて悲しい目にあったので、全部スマホでやってた処理を、きちんとサーバーサイドとクライアントサイドにわけてデータも1度処理したものは永続化してというのをやってサンプルプログラムにしてみました。

どんなプログラムなの?

Twitter から #microsoft のハッシュタグを検索して画像を収集するアプリケーションになります。収集した画像は、Microsoft Cognitive Services の Vision API を使ってカテゴリ分けを行い、画像がどんなものかという説明文も Vision API を使って生成しています。 Vision API の結果は英語でかえってくるので Microsoft Cognitive Services の Translator Text API を使って日本語に翻訳しています。

カテゴリ分けされた画像のデータは Microsoft Azure の Cosmos DB に保存しています。画像の収集と Vision API による認識処理は Azure Functions を使って定周期で実行しています。

f:id:okazuki:20170605174226p:plain

クライアントアプリケーションは Xamarin.Forms で作ってるので Android / iOS / UWP で動かすことが出来ますが作業環境の都合上 iOS で動作確認が出来てません!後でやらないと…。クライアントアプリケーションの実行結果は以下のような感じになります。

f:id:okazuki:20170605174345p:plain

f:id:okazuki:20170605174357p:plain

f:id:okazuki:20170605174409p:plain

ポイント

何を見たらいいのだろうか?

Cognitive Services API の呼び出し方

Cognitive Services の API を呼び出すコード例として見ることが出来ると思います。具体的には VisionService クラスあたりがそれになります。

github.com

Cosmos DB に C# からアクセスする方法

Cosmos DB に対して C# からアクセスする際のコード例になります。DBの作成からデータの追加検索を行っています。また、データ件数が多くなったときのページング処理も実装しています。

github.com

Prism.Forms を使ったコード例として

Prism.Forms を使ったコード例としても見てください。具体的には CognitiveServicesSample.Client プロジェクトになります。

github.com

Xamarin.Forms の ListView を使ったインクリメンタルローディング

データは基本的に50件ずつ取得してListViewが下までスクロールされたらデータを追加で読み込むようにしています。 Xamarin.Forms の ListView には、このようなインクリメンタルローディングの処理は組み込みでサポートされていないため ListView を拡張して IncrementalLoadingListView を作成して使っています。

github.com

実際に使っているのは CategorizedImagePage になります。

github.com

CategorizedImagePageViewModel に追加読み込みのロジックがあります。

github.com

作ってて諦めたことや、やらないといけないこと

.NET Standard

.NET Standard で出来るところは .NET Standard のプロジェクトにして WebAPI は ASP.NET Core で実装しようと思ってたのですが Cosmos DB の SDK の要求する .NET Standard のバージョンが 1.6 だったりした関係で UWP のプロジェクトから参照できなかったりして泣いて諦めました。

自動ビルド

リポジトリに Push したら自動でビルドしてテスト流して配備とかやるとかっこいいなぁと思ってるけど、そもそも単体テストが無い!!!一応、外部リソースに依存する部分とかは interface 切ってたりするので単体テスト書いたりできる土壌は出来てるのでそのうちやらないといけないと思いつつやってない…。

おまけとして

ここで作ってる Controller 2つですが

github.com

http://cogsample.azurewebsites.net にデプロイしてあるので API を叩くことでデータがとってこれます。

http://cogsample.azurewebsites.net/api/Category で現在収集してる画像のカテゴリ一覧が取れます。

http://cogsample.azurewebsites.net/api/CategorizedImage?category=people_ で指定した名前のカテゴリの画像を50件とってくることが出来ます。続きのデータを読み込みたいときは結果の JSON の Continuation の値を continuation パラメータとしてくっつけて送ることで取得できます。

結果の JSON の形式は以下のクラスを使えば JSON.NET とかでデシリアライズできます。

github.com

github.com

実際に URL を叩いてるコードは以下のクラスになります。

github.com

まとめ

突っ込みかなんかあったら PullRequest や Issue 待ってます。日本語でおk。