はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

MessagePack for C#始めました

以前から使おう使おうと思って(実際は使ってみようとして上手くいかなくてを何回か繰り返して、最近の状況で在宅でがっつり集中できるようになったので)いたneueccさんの素敵ライブラリMessagePack-CSharpを既存アプリに組み込むことができました。

github.com

いくつか、DataContractJsonSerializerから書き換えるうえで迷った点がありましたので、まとめておきたいと思います。

MessagePack-CSharpは、非常に高速なC#用シリアライザーです。例えば構造体⇔Byte配列、構造体⇔Byte配列⇔JSON文字列あたりの変換が多数あるような例えば多端末間メッセージ送受信のデータシリアライズなどに適用するとシステム全体の快適さが増すかもしれません。

GitHubで公開されている測定結果を見ると、まさに桁が違う処理速度です。

https://cloud.githubusercontent.com/assets/46207/23835716/89c8ab08-07af-11e7-9183-9e9415bdc87f.png

 

PublicクラスじゃなくてInternalやPrivateなクラスを使う場合

MessagePack-CSharpでは、デフォルトでは指定する構造体はPublicクラスじゃないと実行時エラーが発生します。ネットで検索してみると「Publicクラスでなければならない」という解説もありましたが、本家のneueccさんの説明ではそのような説明がありませんでした。ということはきっとできる方法が用意されているのだろうと考えてドキュメントをもう一度よんでみるた次のような方法の記載をみつけました。やっぱり原典をみないとですね。

InternalやPrivateなクラスを指定したいときは次のようにします。

gist.github.com

 MessagePackSerializerOptions.Standard.WithResolverの引数にStandardResolverAllowPrivate.Instanceを指定してオプション指定をつくり、それをSerialize<プライベートクラス>メソッドの第二引数に指定してあげれば、Privateクラスでも実行時エラーなくシリアライズできます。

便利ですね。

クラスのプロパティ名をJSON文字列の項目名に使う場合

これは簡単で、クラスに[MessagePack.MessagePackObject(true)]属性をつけてあげればOKです。

JSON文字列上の項目名を、クラスのプロパティ名とは別の名前にしたい場合

JSONに指定する項目名が"message-id"などが必要でプロパティ名に指定が難しいような場合には、Key属性で項目名を指定することができます。

まずはダメな例

gist.github.com

クラスに[MessagePack.MessagePackObject(true)]属性をつけて、変更したいプロパティにだけ[MessagePack.Key("message-id")]属性でJSON項目名を指定してみましたが、これでは変更されませんでした。

OKな例。きちんとすべてにKey属性をつけてクラスの属性ではkeyAsPropertyNameをfalseつまり指定しないようにします。

gist.github.com

これでいままで悩んでいた点が解決できたので、リリース版に反映&テストフェーズに入りたいと思います。

米国に旅行にいくなら、Amazon Lockerを活用しよう

Amazon.comで買い物したものを日本に送ってくれたりしますが、まだまだ(特に電池が入っているものなど)すべてがという訳にはいきません。

米国に旅行に行く機会があったとしても、送付先にホテルを指定してうまく受け取れるか、そもそも滞在期間中に届くようにするにはどうしたらいいのかなどの不確定要素が付きまといます。

 

そんなとき、オースティンに出張に行ったときに街中で見かけたのがAmazon Lockerです。

Amazon.comのサイトを見てみると

  • 配達及び返品に使える
  • 利用時間帯も長く
  • 追加料金なし

というAmazon公式ロッカーのようです。

image

 

ためしにMicrosoft MVP Global Summitで宿泊する近くをさがしてみるといくつかあるようです。

image

郵便番号にホテルの98004という郵便番号を入力して検索すると、

image

ベルビュースクエアの東南ブロックにいくつかありますね。高速の近くは not public lockerなので住民専用とかでしょうか。

希望するロッカーの場所の[Select]ボタンをクリックすれば送付先リストに、そこのAmazon Lockerが指定できるようになります。

日曜日も受け取れる「Amazon Locker ? Bery!」か「Amazon Locker ? Frannie」が良さそうですね。

ここで注意することは、Amazon.comでの配達は基本的にbusiness dayつまりは平日のみとなっています。

ですので、日曜日に現地着だから日曜日に受け取ろうと思うと金曜日着になるように早め早めに行動するのがいいでしょう。

もしくは、Amazon Primeのお試しに入って、月曜日の朝の9時までに申し込みをしてSame Dayかone business dayで配達してもらうのもいいかもですね。

 

それでは実際にAmazon Lockerから品物を受け取りましょう。

Amazon.comで購入してAmazon Lockerに荷物がはいると取り出しようのパスコードが書かれたメールが来ます。

画像に含まれている可能性があるもの:テキスト

宿泊場所からはだいたい10分くらい歩いたところにAmazon Lockerはありました。

空港に戻るときに乗るバスターミナルのちょっと先ですね。

画像に含まれている可能性があるもの:空、夜、木、屋外

expediaビルの地下駐車場に設置されていまいた。

写真の説明はありません。

写真の説明はありません。

ロッカーの液晶画面のところでメールに書かれたコードを入力するとロッカーのドアが開きます。

画像に含まれている可能性があるもの:テキスト

無事、ゲットできました。簡単ですね。

写真の説明はありません。

今回購入したのはWear OS by Googleな腕時計です。

写真の説明はありません。

技適も通ってますし、日本語化もされているので良い感じです。

写真の説明はありません。

MAVIC AIRにも使えるDJI SDKを入手しよう

SDKの入手

現在のSDKはいろいろな種類がでていますが、MAVIC AIRで使うのであればMobile SDKに注目です。

https://github.com/dji-sdk/Mobile-SDK-Android

https://github.com/dji-sdk/Mobile-SDK-iOS

SDK自体はどこにあるかといえば、Mobile-SDK-Android-master\Sample Code\gradle\wrapper\gradle-wrapper.jarがSDKになります。

Xamarin.AndroidSDKを利用する

jarファイルをXamarinから呼び出すためには、バインディングライブラリを作成してjarファイルをまるっとXamarinのクラスライブラリでラッピングしてあげる必要があります。

image

jarファイルの追加

プロジェクトが生成できたら、Jarsフォルダを右クリックして[追加]-[既存の項目]メニューを選択します。

image

ダイアログが開いたらgradle-wrapper.jarを指定して、Jarsフォルダにgradle-wrapper.jarを追加します。

jarファイルのプロパティ指定

image

jarファイルに対するビルドアクションとして「EmbeddedJar」をしてしてdllにjarファイルを埋め込むようにします。

バインディングライブラリのビルドエラー対策

この状態でバインディングライブラリをビルドしてあげてエラーなくビルドできれば、バインディングライブラリのdllが完成します。

しかしながら、ここでエラーが出ないもののほうが少なく、gradle-wrapper.jarも当然のようにビルドエラーが発生します。

ビルドエラーは3件、すべてCS0535「〇〇はインターフェイスメンバー△△△を実装しません」です。

image

解決方法はいくつかありますが、今回出ているエラーは、「AbstractCommandLineConverter」、「AbstractCommandLineConverterInvoke」、「DownLoad」なので、主要な部分ではなさそうで使わないでもアプリ作れそうですから、とりあえずはなかったことにしてしまって、後日、必要だったらまた考えることにしたいと思います。

そのためには、Metadata.xmlに次の定義を入れておきます。

<remove-node path="/api/package[@name='org.gradle.wrapper']/class[@name='Download']" />
<remove-node path="/api/package[@name='org.gradle.cli']/class[@name='AbstractCommandLineConverter']" />

 

次回に続きます。

AndrodでGoogle Playに公開するときのSDKバージョン制限について

android-developers.googleblog.com

2018年8月以降

新規登録は、ターゲットSDKとしてAPIレベル26 (Android 8.0以上) が必須となります。既存アプリについては従来通りでもまだ大丈夫です。

2018年10月以降

上記に加えて、既存アプリのアップデートもターゲットSDKとしてAPIレベル26 (Android 8.0以上) が必須となります。

 

アップデートしないときはお目こぼしのようですが、現在提供中のアプリの更新を行わないというのも考えられませんので、既存アプリの名前を変更するなど(だとしても10月までにやらないといけない)して提供をキープして、主流派APIレベル26でということになるのでしょうか。

Androidアプリの有識者の方、ぜひ、教えてください。

 

2018年8月:APIレベル26(Android 8.0以上)をターゲットにするために必要な新しいアプリ。
2018年11月:APIレベル26以上をターゲットにするために必要な既存のアプリのアップデート。

Xamarin.Forms 2.xと3.0の違い(Xamarin.Forms.Application.Current.Resources)

App.csのコンストラクタで、Xamarin.Forms.Application.Current.Resourcesの初期状態が、Xamarin.Forms 2.xとXamarin.Forms 3.0では異なっていました。

2.x:null

3.0:not null

問題点

そのため、nullだったらCurrent.Resourcesに項目をAddするようなロジックにした場合、2.xでは正常に動作し、3.0ではAddしないため、XAML

BackgroundColor="{StaticResource BorderBrush}"

のような参照をしていると、そこで実行時エラーになってしまいました。

対策

if (Xamarin.Forms.Application.Current.Resources == null || Xamarin.Forms.Application.Current.Resources.Count == 0)

のようにCount判定も追加する。

Xamarinの共有プロジェクトでXamarin.Forms 3.0を使う

Xamarin.Formsも3.0となり、魅力的な機能がさらに追加されました。

主な新規のは次のようなものがあります。

  • FlexLayout
  • ResourceDictionary
  • 右から左(アラビア語など)のサポート
  • CSS StyleSheet
  • Visual State Manger

Microsoft XAMLではおなじみの「ResourceDictionary」や「Visual State Manager」のサポートもうれしいですが、「FlexLayout」と「CSS StyleSheet」のサポートも魅力的ですね。

例えば、FlexLayoutはコンテンツを折り返しならが横方向に並べてくれるレイアウトで、Gridのようにあらかじめ縦横のマス数を指定しなくてもいいので、可変数のコンテンツを効率よく表示するのに適しています。従来であれば、ListViewのように横幅が一定の1列リストなどしか方法がありませんでしたが、タイル状に表示することが可能になりました。

Xamarin.Forms Layout Types

 

新規プロジェクトでのXamarin.Forms 3.0の指定

Visual Studio 2017 (15.7.2)で新規に作成したプロジェクトでXamarin.Forms 3.0を使う方法を紹介します。Xamarin.AndroidとXamarin.iOSに共通のロジックは.NET Standard 2.0でDLL化して共有するのではなく、共有プロジェクトでソースコードレベルで共有するスタイルにします。

image

そのためには、CrossPlatform - Xamarin.Formsテンプレートを選択して、空のアプリで「共有プロジェクト」を選択します。

image

 

この方法で作成したプロジェクトでは、Xamarin.Formsは最初から3.0が設定されています。Xamarin.Formsもnugetパッケージとして提供されていますから、ソリューションエクスプローラーでAndroidのプロジェクトの[参照]フォルダを右クリックして[Nugetパッケージの管理]メニューを選択して、使用されているnugetパッケージのバージョン確認してみましょう。

image

Xamarin.Forms 3.0のnugetパッケージの最新化

テンプレートのXamarin.Forms 3.0は3.0.0.482510ですので、その後に新しいものがでている場合があります。今回も、2018/06/05に3.0.0.530893がでているので、必要に応じてnugetパッケージん更新をしましょう。更新していいかどうかの判断基準は一概にはありませんが、リリースノートなどで判断するのがいいでしょう。

https://developer.xamarin.com/releases/xamarin-forms/xamarin-forms-3.0/3.0.0/

 

Xamarin.Androidのサポートライブラリの最新化

Xamarin.Androidの場合、さらにXamarin.Android.* (サポートライブラリ)のnugetパッケージのバージョンをどうするかも考える必要があります。

テンプレートで指定されてるサポートライブラリのバージョンは、25.4.0.1となっており、この時の依存関係にあるMonoAndroidバージョンはv7.0となっております。

2018/6/6現在に対応している最新MonoAndroidバージョンはv8.1ですので、最新のものを使うなら、サポートライブラリを最新のv27.0.2にします。

 

サポートライブラリとAndroid SDKのバージョンの関連

サポートライブラリのバージョンを更新してMonoAndroidのバージョンが変更されたときは、該当するAndroid SDKがイントールされている必要があります。

たとえば、サポートライブラリをv27.0.2にしたいのであれば、事前にAndroid SDK ManagerでSDK 8.1がインストールされていることを確認してください。

image

該当するSDKバージョンがないとnugetでサポートライブラリのバージョンを更新するときにエラーとなります。

image

ターゲットフレームワークの関連

Android SDK v8.1がインストール出来たらプロジェクトのターゲットフレームワークAndroid 8.1にします。

image

こちらターゲットAndroidバージョンとは別となります。もし(そんなタイミングはすくないでしょうけれど)、ターゲットを最新OSにするのを待ちたいときは、ターゲットAndroidバージョンを明示的に指定することも可能です。

image

2つ指定するのが面倒であれば、SDKのバージョン=ターゲットAndroidバージョンにする「SDKバージョンを使用したコンパイルの使用」という指定もあります。

image

 

Xamarin.Formsで画面を定義してみよう

それでは試しにFlexLayoutを使った画面を定義してみましょう。

画面定義は、AndoridとiOSで共通化できるところは共有プロジェクト側に記載します。

image

>|html|
<!--?xml version="1.0" encoding="utf-8" ?-->
<contentpage x:class="XamarinForms3Sample.Views.MainPage" xmlns:local="clr-namespace:XamarinForms3Sample.Views" xmlns:converter="clr-namespace:XamarinForms3Sample.Converters" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns="http://xamarin.com/schemas/2014/forms">
        
    <grid>
        <scrollview>
            <flexlayout justifycontent="SpaceAround" wrap="Wrap" x:name="Flexbox">
                <img />
            </flexlayout>
        </scrollview>
        <activityindicator x:name="activityIndicator" verticaloptions="Center" isrunning="{Binding IsBusy}">
    </activityindicator>
</grid>
||<

Modelなどのロジック部分も完成して実行すればタイル状に画像が表示されるアプリの完成となります。

image

 

ところでFlexLayoutでViewModelとBindingするのはどうするだろう。

 

build 2017雑感

build 2017も残すところあと1日となりました。

1日目、2日目のキーノートとセッションに参加して感じたことは、AI - Cognitive、HoloLens、Xamarinということでしょう。

そしてすべてのセッションには英語字幕がついている(これ、音声認識なのか、どこかに会場音声を飛ばしてキー入力している人がいるのか不明。後者なのかな)点も見逃せませんでした。

今回の会場は道路を挟んで2つの建物で行われていました。キーノートや展示会場もあるWCC側のセッションでは手話通訳者の人がスピーカーの話す内容を手話にしていました。もちろん、キーノートでも。

AI - Cognitive

 画像認識を使って危険予知や体調を推測するなど、Cognitive Serviceで提供されている機能を使うことで、人の気配りを機械にさせることができるようになるかもしれません。

疲れることも気分にも左右されない機械がいろいろなところに入ってきて、それによって生まれた余裕を使って臨機応変の部分で人が対応できるような未来が感じられるのが今年のbuildの特徴の1つでしょう。

そしてもう一つの未来がキーノートで紹介されたマイクロソフトリサーチの研究

youtu.be

パーキンソン病の症状の1つである手の震えを二軸のモーターで相殺する腕時計デバイスです。動画中にもあるような小型化できたのも、機械学習による成果と言えるでしょう。

HoloLens - Microsoft Mixed Reality

今までは文字通り箱入り娘のようだったHoloLensですが、今回のbuildの展示会場では、普通のブースにもHoloLensを展示している企業さんがいて、HTCやOculusのように気軽にかぶせて自分たちのアプリを体験させていました。

そして、Microsoft Mixed Realityに準拠したAcerHMDの体験コーナーもありました。AcerHMDですが、HoloLensのように単体動作ではなく、PCに接続して使う従来型のHMDです。ですからHoloLens向けに作成したアプリをローカルコンピュータで実行すればAcerHMDに表示されるという寸法です。

Mixed Reality AcademyでもHoloLensとAcerの両方が試せました。同じアプリが両方で試せるのは素晴らしいですね。Acer HMDですが今までにない綺麗さでした。いわゆるフルダイブ型ですが装着感もいいし、これでVRコンテンツをプレイしたら楽しいかなと思いました。

Xamarin

そして今年もXamarin界隈は元気ですね。セッションもたくさんあるし。

Visual Studio for MacがGA(正式提供)されたり、Xamarin Live PlayerやXAML Standardなどのいままでかゆかったところに手が届くような発表もあり、今後もXamarin界隈は元気な感じですね。

■Xamarin Live Player

AndoridやiOSでの実行(画面表示?)をシミュレートしてくれるインタープリター環境です。VMのように重たくもないし、実機デプロイと違って、Visual Studio側での変更もリアルタイムに反映ができます。

もちろん、シミュレーターや実機のように厳密には動作が違う部分もあるかもしれませんし、(実はインタープリターなのでMacなくてもPCだけで)iOS画面が確認できるといっても、まだまだ基本的なXAMLページしか対応できていないし、実機デプロイやストアへの登録はMacが必須なのは変わりませんが、この方向が示されただけでも、また、初学者の人が入門記事を試すのにも最適化なんじゃないかな。

XAML Standard

現状、Microsoft XAMLとXamarin XAMLは同じように書けそうで、コントロール名が違っていたり、プロパティが違っていたりします。そこで、XAML Standardという考え方を入れて共通化していきましょうというものです。

私としては、コントロール名やプロパティ名を共通化するときに、全部、Microsoft XAMLによせるのではなくて、例えば、VisibleプロパティなんかはIsVisibleプロパティのようにXamarin XAMLにしてもらった方がConverter書かなくていいのになーと思ったりするので考慮してほしいなぁーと思ったりもしています。

それ以上に期待するのが、各プラットフォームごとに動きの差異が最小になるようにしてほしいという点です。それができるならば、コントロール名やプロパティ名が違うくらい外側の話ですから使う側でいくらでも補完できます。

若干、今回のXAML Standardの発表を否定的にとらえているようなコメントもTwitter上で見かけますが、build現地の空気感や使う側の開発者にしてみれば、XamarinがMSに買収されたときから【長い間】「こうなるはずだよね?」と思っていたことが【やっと公式に表明】されたという点が大きいわけで、個人的にはそれこそ去年のbuildで表明されてもよかったくらいだと思うので、それは素直に評価して喜んでいいじゃないかって思うところです。