Quantcast
Channel: かずきのBlog@hatena
Viewing all 1388 articles
Browse latest View live

Json.NET で enum を文字列で保存したり数字で保存したりするものを混在させたい

$
0
0

Json.NET は便利ですよね。ということで、こういう感じのクラスを…

publicenum Size
{
    Small = 100,
    Large = 1000,
}

publicenum TargetType
{
    None,
    TypeA,
    TypeB,
    TypeC,
}

publicclass Target
{
    publicstring Name { get; set; }
    public Size Size { get; set; }
    public TargetType Type { get; set; }
}

Size プロパティは数字としてシリアライズしつつ、Type プロパティは enum の文字列としてシリアライズしたい…!というケースがあるとします。Json.NET には、StringEnumConverter というクラスがあるので、これを指定すれば enum を文字列としてシリアライズしてくれるようになります。

JsonConvert.SerializeObject, JsonConvert.DeserializeObject あたりでこれを指定すると Size プロパティが数字じゃなくなってしまうのでプロパティ単位で指定する必要があります。これは JsonConverterAttribute でやるのがいい感じです。

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;

namespace ConsoleApp1
{
    class Program
    {
        staticvoid Main(string[] args)
        {
            var target = new Target
            {
                Name = "Tanaka",
                Size = Size.Large,
                Type = TargetType.TypeA,
            };

            var json = JsonConvert.SerializeObject(target);
            Console.WriteLine(json);

            var deserializedTarget = JsonConvert.DeserializeObject<Target>(json);
            Console.WriteLine($"{deserializedTarget.Name}, {deserializedTarget.Size}");
        }
    }

    publicenum Size
    {
        Small = 100,
        Large = 1000,
    }

    publicenum TargetType
    {
        None,
        TypeA,
        TypeB,
        TypeC,
    }

    publicclass Target
    {
        publicstring Name { get; set; }
        public Size Size { get; set; }
        [JsonConverter(typeof(StringEnumConverter))]
        public TargetType Type { get; set; }
    }
}

このように、シリアライズ/デシリアライズのときの挙動をカスタマイズしたいプロパティにだけ JsonConverterAttribute を指定すれば OK です。

属性で汚染されたくない…!

あっ、はい。 Json.NET の属性は付けれないときもありますよね。自分が変更できないクラスとか。

JsonConverter で頑張る

JsonConverter で Target オブジェクトのシリアライズ/デシリアライズの方法をカスタマイズする方法です。 ちょっとメンドクサイ…。

ただただ、純粋にメンドクサイ。

ContractResolver で頑張る

要は特定のプロパティだけ後から JsonConverter つけれればいいので… DefaultContractResolver あたりを継承して GetProperty メソッドをオーバーライドして、狙ったプロパティのときだけ Converter を差し込んでやるとう作戦です。

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System;
using System.Reflection;

namespace ConsoleApp1
{
    class Program
    {
        staticvoid Main(string[] args)
        {
            var target = new Target
            {
                Name = "Tanaka",
                Size = Size.Large,
                Type = TargetType.TypeA,
            };

            var json = JsonConvert.SerializeObject(target, new JsonSerializerSettings
            {
                ContractResolver = new MyContractResolver(),
            });
            Console.WriteLine(json);

            var deserializedTarget = JsonConvert.DeserializeObject<Target>(json, new JsonSerializerSettings
            {
                ContractResolver = new MyContractResolver(),
            });
            Console.WriteLine($"{deserializedTarget.Name}, {deserializedTarget.Size}");
        }
    }

    publicclass MyContractResolver : DefaultContractResolver
    {
        protectedoverride JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            var p = base.CreateProperty(member, memberSerialization);
            if (member.DeclaringType == typeof(Target) && member.Name == nameof(Target.Type))
            {
                p.Converter = new StringEnumConverter();
            }

            return p;
        }
    }

    publicenum Size
    {
        Small = 100,
        Large = 1000,
    }

    publicenum TargetType
    {
        None,
        TypeA,
        TypeB,
        TypeC,
    }

    publicclass Target
    {
        publicstring Name { get; set; }
        public Size Size { get; set; }
        public TargetType Type { get; set; }
    }
}

enum を辞める

こういう風にしてしまう手もありますね。 Java に enum が無かったころに編み出された enum パターン風に。

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Reflection;

namespace CustomJson
{
    class Program
    {
        staticvoid Main(string[] args)
        {
            var target = new Target
            {
                Name = "Tanaka",
                Size = Size.Large,
                Type = TargetType.TypeA,
            };

            var json = JsonConvert.SerializeObject(target, new SizeJsonConverter(),
                new StringEnumConverter());
            Console.WriteLine(json);

            var deserializedTarget = JsonConvert.DeserializeObject<Target>(json, new SizeJsonConverter(), new StringEnumConverter());
            Console.WriteLine($"{deserializedTarget.Name}, {deserializedTarget.Size.Value}");
        }
    }

    publicclass SizeJsonConverter : JsonConverter
    {
        publicoverridebool CanConvert(Type objectType)
        {
            returntypeof(Size) == objectType;
        }

        publicoverrideobject ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jToken = JToken.Load(reader);
            intvalue = jToken.Value<int>();
            returntypeof(Size).GetTypeInfo()
                .GetProperties(BindingFlags.Static | BindingFlags.Public)
                .Where(x => x.PropertyType == typeof(Size))
                .Select(x => (Size)x.GetValue(null))
                .First(x => x.Value == value);
        }

        publicoverridevoid WriteJson(JsonWriter writer, objectvalue, JsonSerializer serializer)
        {
            var size = (Size)value;
            writer.WriteValue(size.Value);
        }
    }

    publicclass Target
    {
        publicstring Name { get; set; }
        public Size Size { get; set; }
        public TargetType Type { get; set; }
    }

    publicsealedclass Size
    {
        publicstatic Size Large { get; } = new Size(1000);
        publicstatic Size Small { get; } = new Size(100);
        private Size(intvalue) { this.Value = value; }
        publicint Value { get; }
    }

    publicenum TargetType
    {
        None, TypeA, TypeB, TypeC
    }
}

Size を enum パターン的に作ってしまって、Size クラスに対して JsonConverter を書く感じです。これならどうだろう?

まとめ

おとなしくクラスに JsonConverter を指定しましょう。


Microsoft TechSummit 2017 で Visual Studio Mobile Center について登壇してきました(方眼紙公開)

$
0
0

2017/11/08 ~ 2017/11/09 の二日間にわたり開催された TechSummit 2017 で id:chomadoさんと共同登壇ということで「モバイルアプリの開発・運用・ユーザー分析をまとめて管理できる Visual Studio Mobile Center を使ってみよう」というテーマでお話しさせて頂きました。

Mobile Center

f:id:okazuki:20171109165609p:plain

何故、モバイルアプリの開発は大変なのか?Visual Studio Mobile Center を使うことで、その課題に対してどう手助けしてくれるのか?ということをデモを交えながら発表しました。

発表資料は、後程公式サイトから共有されると思いますが、セッションのデモの中で使用した Excel による手動テストの仕様書はシェアされないのでここで公開しておきます。

1drv.ms

では!よいモバイルアプリ開発を!!

Microsoft TechSummit 2017 で Visual Studio Mobile Center について登壇してきました(方眼紙公開+スライド)

$
0
0

2017/11/08 ~ 2017/11/09 の二日間にわたり開催された TechSummit 2017 で @chomadoさんと共同登壇ということで「モバイルアプリの開発・運用・ユーザー分析をまとめて管理できる Visual Studio Mobile Center を使ってみよう」というテーマでお話しさせて頂きました。

Mobile Center

f:id:okazuki:20171109165609p:plain

何故、モバイルアプリの開発は大変なのか?Visual Studio Mobile Center を使うことで、その課題に対してどう手助けしてくれるのか?ということをデモを交えながら発表しました。

発表資料は、後程公式サイトから共有されると思いますが*1セッションのデモの中で使用した Excel による手動テストの仕様書はシェアされないのでここで公開しておきます。

f:id:okazuki:20171109184650p:plain

1drv.ms

では!よいモバイルアプリ開発を!!

追記

スライドをちょまどさんが公開してくれました!

ちょまどさんメインスピーカーのセッションでしたが結構私のためにデモ時間を割いてくれててありがたいことです。

*1:追記: ちょまどさんがアップロードしてくれました

Microsoft TechSummit 2017 で Visual Studio Mobile Center について登壇してきました その2「感想編」

$
0
0

その1

blog.okazuki.jp

登壇の感想

5月に開催された de:code 2017 に続いての大型イベントでの登壇の機会を頂くことができました。 おそらく1000人規模のイベントになるかと思います。

セッション受講者

メインターゲットが IT Pro ということになっているのでアプリケーションをばりばり開発するタイプの人たちは、そんなに多くないという毛色のイベントになります。

実際にセッションに参加して頂いた方の分布も以下のような感じで(これ見れるのスピーカーとしてはとても有難いですね!欲を言えばセッションスケジュール情報に基づいて事前に知りたいけど。このイベントアプリを作成して頂いた JMASさんには感謝です!プログレスバーがかっこいい。)60% 以上の方がアプリケーション開発系ではないという感じでした。

f:id:okazuki:20171109212508p:plain

セッション開始まで…

共同登壇という形での登壇ははじめてだったので勝手がわからずに戸惑いました。 最初のころは、かけあい?みたいなこととか寸劇?みたいなこととかも検討していましたが、最終的にちょまどさんが説明パートで、私がデモパートという明確な役割分担を設けてやるという感じになりました。

日本マイクロソフト マイクロソフトテクノロジーセンター センター長 澤円さんからも共同登壇は難しいということと、かけあいする場合は劇団に入るくらいの本気度でやらないと失敗するという話しを聞いていたので、最終的にこの形に落ち着いてよかったと思ってます。

ちなみに、前日は夜遅くまでスライドやデモも作っていたりして終わらずに、当日も直前まで資料作成とかしてて結構ドタバタはしてました。

デモアプリケーション作成

デモ用にアプリケーションも作りました。コミットログを見ると 2017/10/14 から作り始めたみたいですね。

f:id:okazuki:20171109214007p:plain

デモアプリケーションは非常にシンプルなもので、#mstsjp17 のハッシュタグから画像を拾ってきて Microsoft Cognitive Services で分類わけと概要を生成しておいて CosmosDB で管理しておいて、モバイル端末から閲覧するといったものでした。

f:id:okazuki:20171109214137p:plain

TimerTrigger の Function から定期的に画像つきツイートの情報を収集して CosmosDB に登録します。CosmosDBTrigger を使って1ツイート単位で Cognitive Services を使って付帯情報を生成しています。そして、HttpTrigger の Function で WebAPI を作って、それをクライアント端末から参照しています。

画面はこんな感じです。

f:id:okazuki:20171109214514p:plain

サーバーサイドは CosmosDB + Azure Functions だけです。クライアントサイドは、最初は Xamarin.Forms で iOS / Android / UWP に対応した形で作りました。Prism と ReactiveProperty あたりを使っています。 考えたのが、Visual Studio Mobile Center が Xamarin のみにしか対応していないという風に思われるのは嫌だったので Android のネイティブでの開発もしてみようと思いました。その際に、Java ではなく Kotlin でやってみるか!!と思い立って Kotlin で、ほぼほぼ同じ機能を持ったものを作ってみました。

Android アプリのみを開発するなら、やっぱり Android 本家の開発方法でやるほうが楽だなというのが正直な感想ですね。Kotlin も正直 C# よりもモダンな雰囲気を感じます。関係ないですが、Kotlin で iOS アプリも開発できるようなものも発表されたり、Android では公式な言語として採用されたり、サーバーサイドも Kotlin で書けたたり、さらには JavaScript にもコンパイル出来たりと、なんだか強い…という感想を感じます。

ここら辺の Xamarin と Kotlin のクロスプラットフォーム開発については @amay077さんの以下の記事が詳しいです。

qiita.com

Kotlin かわいいよ。Kotlin。因みに、Kotlin インアクションはいい本です。

Xamarin も C# での既存資産を持っている人たちはノウハウや資産の一部を再利用できる点や、現時点でネイティブアプリと同等のパフォーマンスを持ったアプリケーションを作成できる実績のあるクロスプラットフォームである点や、Visual Studio / Microsoft Azure との高い親和性を持った点などなど、いい面がいっぱいあります。ただ、個人的に思うのは、きちんと特徴を知ったうえで適材適所で使いましょうという感じです。Xamarin もいいぞ。

因みに、私たちの登壇は2日目だったのですが初日のキーノートが終わった後に、ちょまどさんがキーノートで描いてた絵を、デモアプリでプッシュ通知受け取った人だけに送ろうという感じのことを思いついたので、せっせと実装してたりしました。参加者の方にインストールしてもらうということになるので、Xamarin で作った apk だと 20MB を超えてしまうので(これは仕組み上仕方ない)今回は Kotlin で作ったアプリの方を対象にしました。

Mobile Center の Push 通知に chomado という名前のプロパティをくっつけて送りつけると、プレゼント用のページに画面遷移するという仕組みで作りました。プレゼント画面は以下のような感じです。右下のボタンを押すとローカルに保存されます。

f:id:okazuki:20171109220409p:plain

あと、Visual Studio Mobile Center の一押し機能に Test 機能があるのですが、これは Microsoft が管理している様々な種類のデバイスに、自分のアプリをインストールして自動UIテストを実行するという類の機能なのですが、澤さんにレビューを受けた際に(本番前日に見てもらいました)機能の説明だけではなく、その機能があることで何が嬉しいのか?というのを伝えるために Before After があるといいというアドバイスを受けたので、急遽、前職のころを思い出しながら Excel 方眼紙で表紙などを作ったテスト仕様書を作りました。

f:id:okazuki:20171109184650p:plain

結構、SIer 心をくすぐるポイントをいろいろ詰め込んで頑張って作ったのでセッション中に、このテスト仕様書を表示したときに笑って頂いて嬉しかったです。久しぶりにテスト仕様書に従って画面のテストをしましたが、やっぱりつらいですね。

セッション後

Ask the speaker で何人かの方にご質問をいただけたので嬉しかったです。

Microsfot のセミナーではセッションの内容がよかったかどうかというのを NSAT という計算方式を使って数値化して評価するのですが、速報値で 190 というとても高い評価(満点が200)を頂いたのでとても嬉しかったです。

ちょまどさんが、スライドを速攻で公開してくれたので以下から参照して頂くことが出来ます。

www.slideshare.net

感謝!!

ということで、今回の話す機会をくださった TechSummit 2017 のアプリケーショントラックのトラックオーナーの 井上 章さんありがとうございました!

あと、私一人では、どうしても平坦な感じのセッションになりがちなところを、色々この機能はインパクトが大きいからこういう風に紹介したほうがいいとか、このデモはこうした方がもっと良くなるとか、人にわかりやすく伝えるという点と、セッションにメリハリを提供してくれた ちょまどさんありがとうございました!超感謝です。

澤円さんには資料のレビュー(キーノートや自分自身のブレイクアウトセッションを2日目の遅めの時間に持っている状態なのにも関わらず)と的確なアドバイスを頂きました。聴衆の人たちにとって「自分ごと」として感じてもらうという点は、澤さんのプレゼン本を読んだり、澤さんのセミナーを受けたりして頭ではわかっていたつもりになっていたのですが、実際に自分がやるプレゼンで具体例を示して頂いて座学とは違う学びを得ることが出来ました。ありがとうございました!

最後に、Microsoft TechSummit 2017 に参加して頂いて(安くないイベントですよね…)その中で、ちょまどさんと私のセッションを選択していただいたお客様に感謝です!ありがとうございました!

まとめ

Visual Studio Mobile Center はいいぞ。

Microsoft Tech Summit 2017 で Visual Studio Mobile Center について登壇してきました(方眼紙公開+スライド)

$
0
0

2017/11/08 ~ 2017/11/09 の二日間にわたり開催された TechSummit 2017 で @chomadoさんと共同登壇ということで「モバイルアプリの開発・運用・ユーザー分析をまとめて管理できる Visual Studio Mobile Center を使ってみよう」というテーマでお話しさせて頂きました。

Mobile Center

f:id:okazuki:20171109165609p:plain

何故、モバイルアプリの開発は大変なのか?Visual Studio Mobile Center を使うことで、その課題に対してどう手助けしてくれるのか?ということをデモを交えながら発表しました。

発表資料は、後程公式サイトから共有されると思いますが*1セッションのデモの中で使用した Excel による手動テストの仕様書はシェアされないのでここで公開しておきます。

f:id:okazuki:20171109184650p:plain

1drv.ms

では!よいモバイルアプリ開発を!!

追記

スライドをちょまどさんが公開してくれました!

ちょまどさんメインスピーカーのセッションでしたが結構私のためにデモ時間を割いてくれててありがたいことです。

*1:追記: ちょまどさんがアップロードしてくれました

Microsoft Tech Summit 2017 で Visual Studio Mobile Center について登壇してきました その2「感想編」

$
0
0

その1

blog.okazuki.jp

登壇の感想

5月に開催された de:code 2017 に続いての大型イベントでの登壇の機会を頂くことができました。 おそらく1000人規模のイベントになるかと思います。

セッション受講者

メインターゲットが IT Pro ということになっているのでアプリケーションをばりばり開発するタイプの人たちは、そんなに多くないという毛色のイベントになります。

実際にセッションに参加して頂いた方の分布も以下のような感じで(これ見れるのスピーカーとしてはとても有難いですね!欲を言えばセッションスケジュール情報に基づいて事前に知りたいけど。このイベントアプリを作成して頂いた JMASさんには感謝です!プログレスバーがかっこいい。)60% 以上の方がアプリケーション開発系ではないという感じでした。

f:id:okazuki:20171109212508p:plain

セッション開始まで…

共同登壇という形での登壇ははじめてだったので勝手がわからずに戸惑いました。 最初のころは、かけあい?みたいなこととか寸劇?みたいなこととかも検討していましたが、最終的にちょまどさんが説明パートで、私がデモパートという明確な役割分担を設けてやるという感じになりました。

日本マイクロソフト マイクロソフトテクノロジーセンター センター長 澤円さんからも共同登壇は難しいということと、かけあいする場合は劇団に入るくらいの本気度でやらないと失敗するという話しを聞いていたので、最終的にこの形に落ち着いてよかったと思ってます。

ちなみに、前日は夜遅くまでスライドやデモも作っていたりして終わらずに、当日も直前まで資料作成とかしてて結構ドタバタはしてました。

デモアプリケーション作成

デモ用にアプリケーションも作りました。コミットログを見ると 2017/10/14 から作り始めたみたいですね。

f:id:okazuki:20171109214007p:plain

デモアプリケーションは非常にシンプルなもので、#mstsjp17 のハッシュタグから画像を拾ってきて Microsoft Cognitive Services で分類わけと概要を生成しておいて CosmosDB で管理しておいて、モバイル端末から閲覧するといったものでした。

f:id:okazuki:20171109214137p:plain

TimerTrigger の Function から定期的に画像つきツイートの情報を収集して CosmosDB に登録します。CosmosDBTrigger を使って1ツイート単位で Cognitive Services を使って付帯情報を生成しています。そして、HttpTrigger の Function で WebAPI を作って、それをクライアント端末から参照しています。

画面はこんな感じです。

f:id:okazuki:20171109214514p:plain

サーバーサイドは CosmosDB + Azure Functions だけです。クライアントサイドは、最初は Xamarin.Forms で iOS / Android / UWP に対応した形で作りました。Prism と ReactiveProperty あたりを使っています。 考えたのが、Visual Studio Mobile Center が Xamarin のみにしか対応していないという風に思われるのは嫌だったので Android のネイティブでの開発もしてみようと思いました。その際に、Java ではなく Kotlin でやってみるか!!と思い立って Kotlin で、ほぼほぼ同じ機能を持ったものを作ってみました。

Android アプリのみを開発するなら、やっぱり Android 本家の開発方法でやるほうが楽だなというのが正直な感想ですね。Kotlin も正直 C# よりもモダンな雰囲気を感じます。関係ないですが、Kotlin で iOS アプリも開発できるようなものも発表されたり、Android では公式な言語として採用されたり、サーバーサイドも Kotlin で書けたたり、さらには JavaScript にもコンパイル出来たりと、なんだか強い…という感想を感じます。

ここら辺の Xamarin と Kotlin のクロスプラットフォーム開発については @amay077さんの以下の記事が詳しいです。

qiita.com

Kotlin かわいいよ。Kotlin。因みに、Kotlin インアクションはいい本です。

Xamarin も C# での既存資産を持っている人たちはノウハウや資産の一部を再利用できる点や、現時点でネイティブアプリと同等のパフォーマンスを持ったアプリケーションを作成できる実績のあるクロスプラットフォームである点や、Visual Studio / Microsoft Azure との高い親和性を持った点などなど、いい面がいっぱいあります。ただ、個人的に思うのは、きちんと特徴を知ったうえで適材適所で使いましょうという感じです。Xamarin もいいぞ。

因みに、私たちの登壇は2日目だったのですが初日のキーノートが終わった後に、ちょまどさんがキーノートで描いてた絵を、デモアプリでプッシュ通知受け取った人だけに送ろうという感じのことを思いついたので、せっせと実装してたりしました。参加者の方にインストールしてもらうということになるので、Xamarin で作った apk だと 20MB を超えてしまうので(これは仕組み上仕方ない)今回は Kotlin で作ったアプリの方を対象にしました。

Mobile Center の Push 通知に chomado という名前のプロパティをくっつけて送りつけると、プレゼント用のページに画面遷移するという仕組みで作りました。プレゼント画面は以下のような感じです。右下のボタンを押すとローカルに保存されます。

f:id:okazuki:20171109220409p:plain

あと、Visual Studio Mobile Center の一押し機能に Test 機能があるのですが、これは Microsoft が管理している様々な種類のデバイスに、自分のアプリをインストールして自動UIテストを実行するという類の機能なのですが、澤さんにレビューを受けた際に(本番前日に見てもらいました)機能の説明だけではなく、その機能があることで何が嬉しいのか?というのを伝えるために Before After があるといいというアドバイスを受けたので、急遽、前職のころを思い出しながら Excel 方眼紙で表紙などを作ったテスト仕様書を作りました。

f:id:okazuki:20171109184650p:plain

結構、SIer 心をくすぐるポイントをいろいろ詰め込んで頑張って作ったのでセッション中に、このテスト仕様書を表示したときに笑って頂いて嬉しかったです。久しぶりにテスト仕様書に従って画面のテストをしましたが、やっぱりつらいですね。

セッション後

Ask the speaker で何人かの方にご質問をいただけたので嬉しかったです。

Microsfot のセミナーではセッションの内容がよかったかどうかというのを NSAT という計算方式を使って数値化して評価するのですが、速報値で 190 というとても高い評価(満点が200)を頂いたのでとても嬉しかったです。

ちょまどさんが、スライドを速攻で公開してくれたので以下から参照して頂くことが出来ます。

www.slideshare.net

感謝!!

ということで、今回の話す機会をくださった TechSummit 2017 のアプリケーショントラックのトラックオーナーの 井上 章さんありがとうございました!

あと、私一人では、どうしても平坦な感じのセッションになりがちなところを、色々この機能はインパクトが大きいからこういう風に紹介したほうがいいとか、このデモはこうした方がもっと良くなるとか、人にわかりやすく伝えるという点と、セッションにメリハリを提供してくれた ちょまどさんありがとうございました!超感謝です。

澤円さんには資料のレビュー(キーノートや自分自身のブレイクアウトセッションを2日目の遅めの時間に持っている状態なのにも関わらず)と的確なアドバイスを頂きました。聴衆の人たちにとって「自分ごと」として感じてもらうという点は、澤さんのプレゼン本を読んだり、澤さんのセミナーを受けたりして頭ではわかっていたつもりになっていたのですが、実際に自分がやるプレゼンで具体例を示して頂いて座学とは違う学びを得ることが出来ました。ありがとうございました!

最後に、Microsoft TechSummit 2017 に参加して頂いて(安くないイベントですよね…)その中で、ちょまどさんと私のセッションを選択していただいたお客様に感謝です!ありがとうございました!

まとめ

Visual Studio Mobile Center はいいぞ。

Microsoft Tech Summit 2017 で Visual Studio Mobile Center について登壇してきました その3「未紹介機能編」

$
0
0

1つ前の記事

blog.okazuki.jp

ということで、速報的な記事と感想記事を書いたので、せっかくなんで技術的なことを少し書きたいと思います。

もっと Analytics

Visual Studio Mobile Center では Test 機能が見栄えがいいので印象に残りがちですしセッション構成もそういう感じになってます。

f:id:okazuki:20171110200810p:plain

ただ、サーバーに繋いだ状態でテストするとなると、Assertとかまできちんとかけようとするとちょっと大変なんですよね。 サーバーのデータ可変だったりするし…。

ということで、一番とっつきやすい Anaytics あたりをもう少しご紹介したいと思います!

Export

Analytics は、いい感じっぽいレポートを出してくれるので満足感は高いです。

f:id:okazuki:20171110202208p:plain

でも、そこにある以外のレポートを作りたかったら…?というか自分で TrackEvent に仕込んだカスタムなプロパティ情報をもとに、検索したかったら?とか出来ません。 ということで餅は餅屋という感じで Analytics のログは Application Insights に Export 出来たりします。

Mobile Center のアプリの Settings → Export → New Export → Application Insights で紐づけすれば完成です。

f:id:okazuki:20171110202601p:plain

ちょっとどれくらいのリアルタイムで反映されるのかは知らないですが、結構いい感じにログが溜まります。 Azure のポータルを開くとリソースグループに、どうみてもMobile Centerから来ましたみたいなやつが作られてます。

f:id:okazuki:20171110203022p:plain

Application Insights のポータルをぽちぽちしてるだけでも、そこそこ色々見れます。例えばセッションのところをいじってると、特定のユーザーの一連の操作の流れとか見れるし

f:id:okazuki:20171110203443p:plain

あとは特定バージョン使ってる人の分布とか

f:id:okazuki:20171110203928p:plain

特定のイベントがどれくらい発生してたとか

f:id:okazuki:20171110204245p:plain

ユーザーがどんな風に操作してるのかを俯瞰したり

f:id:okazuki:20171110204625p:plain

ぽちぽちしてるだけでもいろいろ見れるのですが、Application Insights の概要タブのところで上の方に分析という選択肢があります。

f:id:okazuki:20171110205758p:plain

これを押すと、自分で好きなクエリを書いて分析することが出来ます。 Visual Studio Mobile Center からは、customEvents というものが飛んでるみたいです。

なのでクエリのところに customEvents と書いて実行するとログがざざざ~っと表示されます。

f:id:okazuki:20171110210045p:plain

あとは | で区切って where とかでフィルタリングしたりします。例えば過去3日間の select image のイベントのみに絞るのはこうやります。

customEvents
| where timestamp >= ago(3d)
| where name == "select image"

こういう風になります。

f:id:okazuki:20171110210357p:plain

クエリは書いてると補間も効くし、そこまで難しくないです。ただ、自分が埋め込んだカスタムイベントのプロパティの中身を見るのがちょっと難しいです。 クエリの結果を展開していくと、こういう風に見えるので…

f:id:okazuki:20171110210601p:plain

customEvents
| project customDimensions.Properties.url

みたいにいけるかと思いますよね?(project は SQL でいうところの SELECT) 実はこれではだめで…なんと JSON 文字列が来てるみたいなので、こういう風に書きます。

customEvents
| extend p = parsejson(tostring(customDimensions.Properties))
| mvexpand p
| where p.url != ""
| project p.url

extend で文字列化した Properties を parsejson して変数につっこんで mvexpand すると使えるようになります。 これがわかるまで凄く時間かかりました。どうも dynamic な型だったりすると tostring しないといけないとかいろいろあるみたいです。

集計もできます。例えば、過去3日で一番見られた画像ってどれ?っていうのを見つけたかったらこういう感じです。

customEvents
| where timestamp >= ago(3d)
| where name == "select image"
| extend p = parsejson(tostring(customDimensions.Properties))
| mvexpand p 
| summarize count() by tostring(p.url)
| order by count_ desc nulls last 

f:id:okazuki:20171110211428p:plain

この画像っぽいですね。

ちなみに表形式の出力じゃなくてグラフもできます。render ってやるだけ。

customEvents 
| where timestamp >= ago(3d) 
| where name == "select image"
| extend p = parsejson(tostring(customDimensions.Properties))
| mvexpand p
| summarize count() by tostring(p.url)
| order by count_ desc 
| render piechart 

f:id:okazuki:20171110211922p:plain

あとは、怪しいログをみつけたら、その session_id でフィルタリングすればユーザーがどんな操作をしてたのかとかもクエリでさくっと書けるし、使い方は無限大。

Application Insights のクエリのリファレンスはこちらを参照してください。

Azure Log Analytics

その他に…

Mobile Center のビルドは凄く簡単なんだけどちゃんとカスタムも入れるポイントがあります。 こちらが詳しいです。

公式ドキュメント

Build Scripts | Microsoft Docs

実際にやってみた人の記事

qiita.com

ここで触れられている環境変数ないのつらたんっていうのは思ってたのですが、先日対応されたみたいです。(多分セッション当日朝起きたらふってきたアップデートだと思われる…)

まとめ

Visual Studio Mobile Center はいいぞ。

HoloLens emulator でアプリが起動時にクラッシュする

$
0
0

Visual Studio から HoloLens emulator に Unity からエクスポートしたプロジェクト経由でデプロイしようとするとアプリがスプラッシュスクリーンが表示される前にクラッシュして死ぬという現象にあいました。

ちなみに Unity 2017.1.2f でやっています。

回避策

HoloLens Emulator の右側にある >>ボタンを押します。

f:id:okazuki:20171119020848p:plain

Optional SettingsUse desktop accelerated graphicsのチェックを外して Applyをします。そうするとエミュレータが再起動するので待ちます。

そうすると、Visual Studio からデプロイしてもアプリがクラッシュしなくなります。

この設定はエミュレータを再起動すると吹っ飛ぶみたいなので毎回しないといけないっぽい?というかこれは何処のバグなんだろうか。


色々なプログラミング言語で JSON をパースするためのイカしたサービス quicktype

$
0
0

今日、マイクロソフト本社から来た David さんとお昼ご飯をしたときに教えてもらえた彼のプロダクトが凄かったので紹介したいと思います。

quicktype.io

quicktype

JSON をペーストするとシリアライズ・デシリアライズするためのコードを出力してくれるサービスです。

例えば、以下のような JSON があるとします。

{"name": "Kazuki Ota",
  "age": 36,
  "pets": [{"name": "hoge" },
    {"name": "foo" }]}

ページに張り付けるとこういうコードが生成されます。

// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:////    using Sample.Models;////    var data = Person.FromJson(jsonString);//namespace Sample.Models
{
    using System;
    using System.Net;
    using System.Collections.Generic;

    using Newtonsoft.Json;

    publicpartialclass Person
    {
        [JsonProperty("age")]
        publiclong Age { get; set; }

        [JsonProperty("name")]
        publicstring Name { get; set; }

        [JsonProperty("pets")]
        public Pet[] Pets { get; set; }
    }

    publicpartialclass Pet
    {
        [JsonProperty("name")]
        publicstring Name { get; set; }
    }

    publicpartialclass Person
    {
        publicstatic Person FromJson(string json) => JsonConvert.DeserializeObject<Person>(json, Converter.Settings);
    }

    publicstaticclass Serialize
    {
        publicstaticstring ToJson(this Person self) => JsonConvert.SerializeObject(self, Converter.Settings);
    }

    publicclass Converter
    {
        publicstaticreadonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
            DateParseHandling = DateParseHandling.None,
        };
    }
}

画面はこんな感じです。使い方に迷うことはないと思われる。

f:id:okazuki:20171122145434p:plain

Visual Studio にも組み込みで JSON からコードを生成する機能があるのですが、ルートのクラス名が決めれなかったり、プロパティ名が JSON のプロパティ名と同じになるので小文字から始まるプロパティになったりしてもんにょりするのですが、そこらへんがきっちり考えられてる!!

今回は、C# の出力コード例を示しましたが他の言語にも対応しています。

  • Swift
  • TypeScript
  • Go
  • C#
  • Java
  • etc...

f:id:okazuki:20171122145710p:plain

例えば TypeScript だとこういう感じになります。

// To parse this data:////   import { Convert, Person } from "./file";////   const person = Convert.toPerson(json);exportinterface Person {
    age:  number;
    name: string;
    pets: Pet[];}exportinterface Pet {
    name: string;}// Converts JSON strings to/from your typesexportmodule Convert {exportfunction toPerson(json: string): Person {return JSON.parse(json);}exportfunction personToJson(value: Person): string{return JSON.stringify(value,null,2);}}

quicktype は本当に賢くて、以下のように複数の型が入り混じった配列の JSON を渡すと…

{"items": ["a", "b", 3]}

ちゃんと型をいい感じにしてくれます。

// To parse this data:////   import { Convert, Person } from "./file";////   const person = Convert.toPerson(json);exportinterface Person {
    items: Array<number | string>;}// Converts JSON strings to/from your typesexportmodule Convert {exportfunction toPerson(json: string): Person {return JSON.parse(json);}exportfunction personToJson(value: Person): string{return JSON.stringify(value,null,2);}}

このパワーをローカルで

サイトの下の方に気になる1文が書いてあります。

npm i -g quicktype

ということで nodejs は導入済みなので、ターミナルを開いてうってみました。

C:\Users\xxxxx>npm i -g quicktype
C:\Users\xxxxx\AppData\Roaming\npm\quicktype -> C:\Users\xxxxx\AppData\Roaming\npm\node_modules\quicktype\quicktype.js
+ quicktype@3.3.0
updated 1 package in 2.711s

入った!quicktype と打ち込むと使い方が出てきます。共通のオプションと C# の部分だけ抜粋してみました。

Synopsis

  $ quicktype [--lang cs|go|c++|java|ts|swift|elm|schema|types] FILE|URL ...

Description

  Given JSON sample data, quicktype outputs code for working with that data in
  C#, Go, C++, Java, TypeScript, Swift, Elm, JSON Schema, Simple Types.

Options

  -o, --out FILE                                        The output file. Determines --lang and --top-level.
  -t, --top-level NAME                                  The name for the top level type.
  -l, --lang cs|go|c++|java|ts|swift|elm|schema|types   The target language.
  -s, --src-lang json|schema                            The source language (default is json).
  --src FILE|URL|DIRECTORY                              The file, url, or data directory to type.
  --src-urls FILE                                       Tracery grammar describing URLs to crawl.
  --no-combine-classes                                  Don't combine similar classes.
  --no-maps                                             Don't infer maps, always use classes.
  --quiet                                               Don't show issues in the generated code.
  -h, --help                                            Get some help.

Options for C#

  --namespace NAME                                 Generated namespace
  --csharp-version 6|5                             C# version
  --density normal|dense                           Property density
  --array-type array|list                          Use T[] or List<T>
  --features complete|attributes-only|just-types   Output features

なんとなくわかる。コマンドから動けばこっちのもんですよね。例えば Visual Studio 2017 で適当なプロジェクトを作ります。

そして、適当な JSON を準備します。ここら辺のを使ってみようかな。Swagger(Open API) のファイルっぽい。

github.com

プロジェクトの下に datasources フォルダを作って petstore.url というファイルを作って上記サイトの JSON の Raw データへの URL をぺたっと貼ります。プロジェクトはこんな感じになりました。

f:id:okazuki:20171122153156p:plain

プロジェクトのプロパティのビルド前イベントのコマンドラインに以下のようなコマンドを書いておきます。単純に qicktype コマンドを書いてるだけですね。フォルダを指定するだけで、そこにある json や url ファイルを対象にしてくれます。

quicktype $(ProjectDir)datasources -o $(ProjectDir)Entities\Petstore.cs --namespace QuickTypeDemo.Entities --csharp-version 6 --features complete

ビルドして、プロジェクトですべてのファイルを表示すると確かに出来上がってることが確認できます。

f:id:okazuki:20171122153430p:plain

プロジェクトに追加しておきましょう。こんなにたくさん(まだ下に続いてます)クラスを生成してくれました。

f:id:okazuki:20171122153547p:plain

JSON.NET を参照に追加して、以下のようなコードを書いてみました。

using QuickTypeDemo.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace QuickTypeDemo
{
    class Program
    {
        staticvoid Main(string[] args)
        {
            var json = new HttpClient().GetStringAsync("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v2.0/json/petstore.json").Result;
            var petstore = Petstore.FromJson(json);
            Console.WriteLine(petstore.Info.Title);
        }
    }
}

ブレークポイントで止めてみたら、ちゃんと読み込めてることがわかりますね。

f:id:okazuki:20171122154048p:plain

他にも

Xcode と VSCode で使う方法は公式の Blog に記事があります。

blog.quicktype.io

さらに、今回はコマンドをビルドアクションで叩く感じでやりましたが、IDE などのツールとのインテグレーションは考えられてるみたいです。素敵!!

blog.quicktype.io

IDE/editor integration

まとめ

JSON を格納するための型定義にお悩みの人は試してみるといいと思いました!凄い!賢い! 個人的に、今まで触ってきた JSON をパースしてクラス定義を出力してくれるほかのサービスと比べて断然使いやすいと思いました。ローカルコマンドが提供されてるのもあついですね。

IDE やエディタとの連携が本当にシームレスになるとやばいことになりそうな気がします。

quicktype.io

Vuforia で認識中のオブジェクトの位置をトラッキングしたい

$
0
0

Vuforiaで簡単に任意のマーカーを認識させることが出来るらしい。

かっこいい! しかも、カメラから見て、どれくらいの位置にあるのか?とかどれくらい傾いてるのか?という情報がとれるらしい。凄い。

開発で試すのには無料っぽいので登録してみましょう。あと、Unity 2017.2 あたりからは Unity に組み込まれてるので使うのも簡単!

Vuforia Developer Portal |

HoloLens でも使える!すごい!

azure-recipe.kc-cloud.jp

さて、実際に認識まではさくっといけるのですがオブジェクトがカメラから見てどの位置にいるのかを取得するときのポイントなどを…

  • ImageTargetのサイズは現実世界にあるマーカーのサイズと一致させる必要があります。これがあってないと、位置があわなかったりします。
  • ARCameraWorld Center ModeCAMERAにします。これで世界の中心はカメラ!ということで ImageTargettransformの各種プロパティから情報が引っこ抜けます。
  • 認識されてる間だけ情報を抜きたかったら、ITrackableEventHandlerを以下のような要領で実装したクラスを ImageTargetにアタッチしてあげればいい
publicclass TrackingHandler : MonoBehaviour, ITrackableEventHandler
{
    private GameObject target;

    private TrackableBehaviour trackableBehaviour;

    private TrackableBehaviour.Status currentStatus;

    privatevoid Start()
    {
        this.trackableBehaviour = this.GetComponent<TrackableBehaviour>();
        this.trackableBehaviour.RegisterTrackableEventHandler(this); // これ大事
    }

    privatevoid Update()
    {
        if (this.currentStatus == TrackableBehaviour.Status.TRACKED)
        {
            // ここでトラッキングできてるときの処理とか
        }
    }

    publicvoid OnTrackableStateChanged(TrackableBehaviour.Status previousStatus, TrackableBehaviour.Status newStatus)
    {
        this.currentStatus = newStatus;
    }
}

なかなか、面白いね!Vuforia!!

HoloLens と PC 間でのシェアリング?もしくは超簡易 Spectator View の代用品

$
0
0

Vuforia いいですよね。で、調べたらこんな記事を見つけたんです。

blog.d-yama7.com

通常のシェアリングが World Anchor を共通の原点として動作するような仕組みでやってるのですが、Vuforia のマーカーを原点にしてしまおうというやつですね。なるほど!!

んでもって、Vuforia は別に HoloLens に閉じたテクノロジーというわけでもないので、Vuforia のマーカーを認識できるものならシェアリングできるのでは?ということでやってみました。

仕掛け

UWP (Unity製) と HoloLens (Unity製) アプリ間で同じマーカーを認識させる。 そこからのローカル座標などをもとにオブジェクトの設置等を行う。通信はシェアリングサーバー立てるのめんどかったので UDP で無差別にばらまいてる。

とりあえず、PC のアプリの画面をキャプチャした動画を上げておきます。 マーカーは動画手前に移りこんでる赤っぽい宇宙服着た人の絵です。Vuforia の組み込みのやつですね。

www.youtube.com

部屋が狭いので、あんまりシェアしてる感がないですが…。 作ったアプリは、HoloLens で AirTap したら HoloLens の前方にリンゴが出現。そしてリンゴをジロジロ嘗め回すように見てる様子を記録して、後で頭の位置を再生できる(白い頭のオブジェクトが動いてるやつ)っていうものです。

PC から HoloLens で見てる世界をのぞき見で来てますね!やったね!!

まぁでも、まだ不安定だったりしますが…。

ソースとりあえず整理してないですが…。

GitHub に上げておきます。 UWP を立ち上げてマーカー認識、HoloLensアプリを立ち上げて同じマーカーを認識。あとは、適当にAirTapしてリンゴを置いたらボタンを押せばいいです。

Unity 2017.2 で作ってます。

github.com

CsvHelper でパースするときに NULL という文字列のセルを null として扱いたい

$
0
0

こんな csv を扱う必要がありまして。

Tanaka,38
Kazuki,NULL
Kazuakix,98
muu,NULL

null が入ってるところには丁寧に文字列で NULL と記載されています。 こういう csv を見るたびにデータ部分に NULL っていう文字列データつっこんだらどうするんだろうと思ってしまう今日この頃です。 今回の例は、数字の列なので、そういういたずらは出来ませんが。

ということで個人的に C# で CSV を扱う時によくつかってる CsvHelper でのやりかたです。

ドキュメント的にはここらへんですね。

joshclose.github.io

joshclose.github.io

ClassMap というクラスを使ってクラスと csv のマッピングをカスタマイズできるのですが、ここで TypeConverter というのをかませることが出来ます。 ということで、今回の場合はこういう TypeConverter を作って…。

class NullableIntConverter : ITypeConverter
{
    publicobject ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        return text == "NULL" ?
            null :
            (int?)int.Parse(text); // 数字じゃないデータきたら潔く死ぬ
    }

    publicstring ConvertToString(objectvalue, IWriterRow row, MemberMapData memberMapData)
    {
        thrownew NotImplementedException(); // 今回は読込だけなので、こっちは実装しない。
    }
}

そして、こんな感じにクラスと ClassMap を作ります。

class Record
{
    publicstring Name { get; set; }
    publicint? Age { get; set; }
}

class RecordMap : ClassMap<Record>
{
    public RecordMap()
    {
        this.AutoMap();
        this.Map(x => x.Age).TypeConverter<NullableIntConverter>();
    }
}

では、さっそく試してみましょう。

namespace CSVHelperLab
{
    class Program
    {
        staticvoid Main(string[] args)
        {
            var csv = @"Tanaka,38Kazuki,NULLKazuakix,98muu,NULL";
            using (var p = new CsvReader(new StringReader(csv)))
            {
                p.Configuration.HasHeaderRecord = false;
                p.Configuration.RegisterClassMap<RecordMap>();
                var records = p.GetRecords<Record>();
                foreach (var record in records)
                {
                    Console.WriteLine($"{record.Name}: {record.Age}");
                }
            }
        }
    }
}

実行するとこうなります。

Tanaka: 38
Kazuki:
Kazuakix: 98
muu:

いい感じですね。

最近のテンプレートメソッドパターンの実装方法

$
0
0

テンプレートメソッドパターン好きでした。割と。

Template Method パターン - Wikipedia

処理の流れは親クラスで定義しておいて、それぞれの処理の流れのポイントポイントでは、継承先のクラスで好きにしてねっていうスタンスですね。 テンプレートメソッドパターンと呼ぶには、ちょっと小ぶりかもしれませんが、そういう意味では1つ前の Blog 記事で書いた NULL という文字列だったら null を返して、そうじゃなかったら型変換して返すという処理もそういう風に書けますね。

blog.okazuki.jp

こんな風に抽象クラスを定義しておいて

abstractclass AbstractNullableConverter : ITypeConverter
{
    publicobject ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        return text == "NULL" ?
            null :
            this.Parse(text);
    }

    publicstring ConvertToString(objectvalue, IWriterRow row, MemberMapData memberMapData)
    {
        thrownew NotImplementedException();
    }

    protectedabstractobject Parse(string text);
}

こういう風に登場する型に応じて継承したクラスを作ると…。

class NullableIntConverter : AbstractNullableConverter
{
    protectedoverrideobject Parse(string text) => int.Parse(text);
}

まぁ、普通ですよね。でも、最近の言語はラムダ式とかサポートしてるわけなので、処理そのものを変数に格納することが出来ます。なので、処理をカスタマイズするためだけに継承するなんていう仰々しいことしなくてもいいですよね。

ということで、最近はこう。

class NullableConverter : ITypeConverter
{
    private Func<string, object> parse;

    public NullableConverter(Func<string, object> parse)
    {
        this.parse = parse ?? thrownew ArgumentNullException(nameof(parse));
    }

    publicobject ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        return text == "NULL" ?
            null :
            this.parse(text);
    }

    publicstring ConvertToString(objectvalue, IWriterRow row, MemberMapData memberMapData)
    {
        thrownew NotImplementedException();
    }
}

使う側で、パース処理を指定する感じ。

class RecordMap : ClassMap<Record>
{
    public RecordMap()
    {
        this.AutoMap();
        this.Map(x => x.Age).TypeConverter(new NullableConverter(x => int.Parse(x)));
    }
}

カスタマイズしたい処理が小ぶりな場合は、こっちのほうが個人的にクラスが増えなくて好きかも。処理が大きくなりがちなときは、継承するほうを選ぶかなぁ?その場合でも、渡す処理をラムダ式じゃなくてメソッドに切り出してやればいいかな?どっちがいいんだろうか。悩ましい。

デザインパターンが考案されてまとめられたときとは、言語が持ってる機能とかも変わってきたから、選択肢も増えましたね。 関数型言語で育てられた考え方が OOP 言語で取り込まれたところが個人的に大きいと思ってます。

最近見た、こちらの記事でも継承してポリモーフィズムするケースと、コールバックを渡す方法の両方が言及されていますね。

tech.quartetcom.co.jp

Y!mobile さんが展開している Android One 端末は最新バージョンである 8 にならない可能性「最新 OS とは?」

$
0
0

今 Y!mobile なんですよね。

www.ymobile.jp

で、先日こんなニュースを見かけました。

ascii.jp

こいつの OS が Android 8.0 なんですよね。通称 Oreo の。私のスマホは X1 というやつで数か月前に購入しました。 購入時に店員さんに伝えた要望としては以下の通りになります。

  • 今の Nexus 5 が OS バージョンアップしなくなったので最新の OS を長く使えるものがいい

そこで提案されたのが、今回のテーマである Android One のシリーズでした。Android One については Wikipedia にあるくらいの認識でした。

Android One - Wikipedia

オペレーティングシステムはAOSPに準拠した非カスタマイズAndroidが搭載されており、Googleによって最新のアップデートが提供される。そのため比較的古いモデルも、最新のAndroidバージョンへのアップデートが保証されている[4]。OSアップデートの保証期間は発売日から最長2年までとなっている[5]。

これならいいかな?と思い購入してみたのですが 2017年12月2日 時点で OS のバージョンは Android 7.1.2 になります。 ということで、軽い気持ちで購入した Y!mobile の店舗に聞きに行ってみました。いつ Android 8.0 になるの?って。

店員さんがどこかしらに電話をかけて聞いてくれた結果は悲しいものでした。

「現時点では Android 8.0 にいつなるかという情報はない。今後バージョンアップがあるかという確約もできない。」

Y!mobile のページを真面目に読み返してみよう

ということで、最初にやれよ!って話なのですが、Y!mobile さんのホームページを読み返してみます。Android One に関するページはこちらですね。

www.ymobile.jp

こちらを見るとこういう記載があります。

f:id:okazuki:20171202201128p:plain

常に最新のOS※1へアップグレードされるので、快適に使えます。

なるほど。そして、大事なことが書かれているであろう※1を見てみると

f:id:okazuki:20171202201326p:plain

※1発売から24カ月間に最低1回以上のアップデートを保証するものです。

このアップデートという部分を好意的解釈すると、Android 7 系の端末は 8 系にはなるかな?と感じるのですが、アップデートを文字通り何かしらの更新があればいいと解釈すると、Android 7 がプリインストールされた状態の Android One 端末に対して 2 年以内に 1 度でもセキュリティーパッチでもばらまけば、この条件は満たした!!となるかもしれませんね。

一応本家の Android One のサイト

こちらもチェックしておきましょう。

Android One: Google が常に最新のアップデートを提供

このページによると以下の心強い1文があります。

f:id:okazuki:20171202201757p:plain

Android One スマートフォンは、出荷時には最新バージョンの Android 7.0 Nougat を搭載し、少なくとも 1 つのメジャー アップグレードが保証されます。新しい Android がリリースされたらすぐにアップグレードでき、最新の革新的な機能をいち早く試すことができます。

なるほど!ここを見ると 8 になる可能性が高いというか、こう書いておいて 8 にならなければちょっと…という感じですね。

それにしても、Android 8 が 8月21日 に公開されて 3 ヵ月たってるのですが、すぐにの定義とはなんでしょうね。

まとめ

ということで、Google の公開している Android One の定義によると 8 に上がることが保証されているということなので、そこらへんを元に、Y!mobile さんに本当に確約されてないの?ということを聞いてみたいと思いました。

「世界最大のIT企業であり巨人と呼ばれるマイクロソフトへ転職するには?」を読んでみた

$
0
0

はてなブックマークを流し読みしてたら以下のような記事を見つけました。

www.worqlip.jp

非常に興味深く読んでみたのですが、ちょっと「ん?」って思うところがあったので見てみたいと思います。

マイクロソフトの名前を知らない人はいない?

たとえIT業界に興味がなくてもマイクロソフトの名前を知らない人はいないでしょう。

これは小ネタなんですが、私が日本マイクロソフトに転職が決まったということを母親に電話したのですが、そのときの会話が…

「マイクロソフト?お父さん、マイクロソフトって知っとる?」

でした。はい。これはどうでもいいですね!

Windows は PC 用の OS

代表的なPC用OC

多分、代表的なPC用OSの Typo ですね。 厳密にいうと、Windows 10 になると様々なプラットフォームで動くオペレーティングシステムになります。例えば電話(これは悲しい結末になりましたが…)、タブレット、デスクトップ コンピューターから Surface Hub、Xbox コンソール、HoloLensまでWindows 10が動いています。

Windows Explorer ?

web閲覧用ソフト「Windows Explorer」

Windows のエクスプローラーというとファイルを見るためのあれのことです。

f:id:okazuki:20171202204057p:plain

おそらく、Internet Explorer のことだと思われます。ただ、Windows 10 からは標準のブラウザは Edge になったので、今後は Edge で有名!って言われるようになると嬉しいなと思いました。

え?Xbox 死んだの!?

以前はXboxというゲーム機も開発していました。

私の認識ではまだ生きてます!現役よ!

www.xbox.com

細かい突っ込み

「Surface」「Surface PRO」などのWindows系タブレットを開発しています。

PRO は Pro じゃないとなんか違和感を感じる。

転職エージェント…?

非公開求人の有無は、私は人事関係のことには携わってないのでわからないですが、基本的こちらで検索できるものがマイクロソフトでやってる求人になると思ってます。

Microsoft Careers: Search jobs

例えば、私と同じロール?のプレミアフィールドエンジニアで検索をしてみると、こういう感じになります。

f:id:okazuki:20171202204911p:plain

ログインすれば、ここから履歴書を送ったりとかが出来るはず!


Azure Functions の Proxies が GA したので試してみよう!

$
0
0

こちらの記事は、Qiita に掲載した Microsoft Azure Tech Advent Calendar 2017 の企画に基づき、執筆した内容となります。 カレンダーに掲載された記事の一覧は、こちらよりご確認ください。

はじめに

みなさん Azure Functions 使ってますか? Visual Studio 2017 での開発ツールも強化されて段々といい感じになってきました。

blogs.msdn.microsoft.com

Azure Functions v2 に対応していたり、プロジェクト作成時に、どのストレージアカウント使うか選べたり、色々いい感じになってますね!

本題

ということで、先日 Azure Functions の Proxies が GA しました。

blogs.msdn.microsoft.com

Proxies の定義は Microsoft Azure Portal でグラフィカルに設定が出来るようになっています。

f:id:okazuki:20171206112859p:plain

このほかに CLI から proxy を追加したりできます。

例えばこんなコマンドをうつと…

func proxy create --name MyProxy --route hello --methods GET --backend-url https://www.bing.co
m

こういう proxies.json が作られます。

{"Proxies": {"MyProxy": {"matchCondition": {"methods": ["GET"
        ],
        "route": "hello"
      },
      "backendUri": "https://www.bing.com"
    }}}

その他に、Visual Studio で proxies.json を開くと、こんな感じにインテリセンスが効いてくれるので json で書くのも捗ります。

f:id:okazuki:20171206113548p:plain

f:id:okazuki:20171206113623p:plain

Azure Functions Proxies で出来ること

完全な説明は以下のドキュメントを見てください。

docs.microsoft.com

個人的に主な用途として以下のものが思いつきます。

  • とっちらった API を Proxies で綺麗に見せる
  • モック API を作る

ちょっと見てみたいと思います。Azure Functions 単体でも HttpTrigger を使って Http に応答する API は割と簡単に作ることが出来ます。例えば Function1 は GET リクエストを受け取って指定された id パラメータのオブジェクトをとってきて JSON で返すみたいなやつですね。

using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;

namespace DemoFuncApp
{
    publicstaticclass Function1
    {
        [FunctionName("Function1")]
        publicstatic async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]HttpRequestMessage req, TraceWriter log)
        {
            string id = req.GetQueryNameValuePairs()
                .FirstOrDefault(q => string.Compare(q.Key, "id", true) == 0)
                .Value;

            if (string.IsNullOrEmpty(id))
            {
                return req.CreateErrorResponse(HttpStatusCode.BadRequest, "id is required.");
            }

            return req.CreateResponse(HttpStatusCode.OK, new { id = id, name = $"sample data {id}" });
        }
    }
}

さらに Function2 は、POST メソッドを受け取って body の JSON の内容を元にリソースを作ってレスポンスで作った結果のオブジェクトを JSON 形式で返すみたいな。

using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;

namespace DemoFuncApp
{
    publicstaticclass Function2
    {
        [FunctionName("Function2")]
        publicstatic async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)]HttpRequestMessage req, TraceWriter log)
        {
            var name = (string) (await req.Content.ReadAsAsync<dynamic>()).name;
            if (string.IsNullOrEmpty(name))
            {
                return req.CreateErrorResponse(HttpStatusCode.BadRequest, "name is required.");
            }
            return req.CreateResponse(
                HttpStatusCode.Created, 
                new { id = Guid.NewGuid().ToString(), name = name });
        }
    }
}

これでもいいんですが、同じリソースに対してアクセスするなら /api/people みたいなエンドポイントに対する GET や POST で呼び分けたいところです。そういう時に Proxies が使えます。

{"$schema": "http://json.schemastore.org/proxies",
  "proxies": {"people-get": {"matchCondition": {"route": "/api/people/{id}",
        "methods": ["GET" ]},
      "backendUri": "https://%APP_NAME%.azurewebsites.net/api/Function1?id={id}"
    },
    "people-post": {"matchCondition": {"route": "/api/people",
        "methods": ["POST" ]},
      "backendUri": "https://%APP_NAME%.azurewebsites.net/api/Function2"
    }}}

matchCondition で同じエンドポイントなんだけど GET の場合と POST の場合で呼び出す backendUri を変えています。GET のほうでは、id を URL の埋め込む感じで受け取って、後ろに流すときにクエリ文字列に渡すようなこともしてます。 また、ここで使っている %APP_NAME% は、Function App のアプリケーション設定で APP_NAME 定義した値をひっぱってくるという書き方になります。こうすることで、例えばデプロイする Function App が変わっても proxies.json を変えずにアプリケーション設定をいじるだけで対応可能になります。 このほかには、アプリケーションを呼び出すときに必要な認証キーとかをアプリケーション設定からとってくるといった使い方があります。

これをデプロイして Postman あたりで叩いた結果が以下になります。

f:id:okazuki:20171206115208p:plain

f:id:okazuki:20171206115126p:plain

ちゃんと proxies.json で定義した URL に対しての呼び出しなのに結果は Function1 / Function2 で書いた処理の結果になっていることがわかりますね!こういった感じで、Function App の HttpTrigger で作った関数を REST API っぽくまとめあげることが出来ます。

このほかに、こういった REST API を開発するときってテスト用のモック API の準備とかが大変だと思うのですが、これも proxies.json で出来たりします。

例えば /api/mock でアクセスしたら、パラメータで受け取った値を使った適当な文字列を返すようなモック API は以下のように書けます。

{"$schema": "http://json.schemastore.org/proxies",
  "proxies": {"people-get": {"matchCondition": {"route": "/api/people/{id}",
        "methods": ["GET" ]},
      "backendUri": "https://%APP_NAME%.azurewebsites.net/api/Function1?id={id}"
    },
    "people-post": {"matchCondition": {"route": "/api/people",
        "methods": ["POST" ]},
      "backendUri": "https://%APP_NAME%.azurewebsites.net/api/Function2"
    },
    "mock": {"matchCondition": {"route": "/api/mock" },
      "responseOverrides": {"response.body": "Hello {request.querystring.name}",
        "response.headers.Content-Type": "application/json"
      }}}}

最後に追加されている mock という定義ですね。responseOverrides を書くことで任意のレスポンスを返すことが出来るようになっています。今回は単純な文字列を返していますが、ここを JSON のオブジェクトにすることで複雑な JSON も返すことができるようになっています。

やってみましょう。

{"$schema": "http://json.schemastore.org/proxies",
  "proxies": {"people-get": {"matchCondition": {"route": "/api/people/{id}",
        "methods": ["GET" ]},
      "backendUri": "https://%APP_NAME%.azurewebsites.net/api/Function1?id={id}"
    },
    "people-post": {"matchCondition": {"route": "/api/people",
        "methods": ["POST" ]},
      "backendUri": "https://%APP_NAME%.azurewebsites.net/api/Function2"
    },
    "mock": {"matchCondition": {"route": "/api/mock" },
      "responseOverrides": {"response.body": {"results": [{"id": 1,
              "name": "test1"
            },
            {"id": 2,
              "name": "test2"
            },
            {"id": 3,
              "name": "test3"
            }]},
        "response.headers.Content-Type": "application/json"
      }}}}

Postman で叩いてみると…

f:id:okazuki:20171206115955p:plain

ばっちりですね!

まとめ

Azure Functions Proxies が GA されたことで、Azure Functions での REST API の開発が捗りそうです!

この他に blob のファイルに転送するような proxy の定義を追加することで Function App + Blob で SPA なページとバックエンドの API がさくっと出来てしまいます。ここらへんはテクニカルエバンジェリストの牛尾さんも試されてます。

qiita.com

Durable Functions という面白い機能も Preview ですが追加されてきてて、よりたくさんのことが Functions で実現できるようになってきてますね!これについては、このアドベントカレンダーの初日の記事で今村さんが書かれてるので見てみてください。

[Advent Calendar 2017 Day1] Durable Functions ことはじめ – Japan Azure Cloud Integration Engineering

それでは、良い Azure Functions 生活を!

技術 Blog を書く理由

$
0
0

たまにポエムっぽいことを書くこともあるけれど(この記事は間違いなくポエム)基本的にこの Blog は技術 Blog です。

この Blog の現状は大体以下のような感じです。

項目 備考
作成日 2011/12/27 年末に何やってるんだろう
総 PV 4,478,761
月間 PV 100,000
平日の PV 4,500
土日祝日の PV 1,500
記事数 2,311

ということで300記事以上もポエム書いた記憶がないので、2,000記事以上書き溜めてることになります。

何故書くのか

大体、牛尾さんが書いてくれてます。

qiita.com

一番の目的は、なんといってもメモです。備忘録としてとても役に立ちます。 取り組んでいる最中は忘れることなんてないのですが、数年経つと下手したらやっていたことすら忘れてるくらいに覚えてないものもあったりします。

そんなとき Google で検索すると過去の自分の記事が出てくることもチラホラあります。

そんなシチュエーションで見返したときにわかるように、可能な限り説明するように書いています。

副次的な効果

こういう風に Blog を書いていると、ただ試してフムフムとやっているだけよりも頭に残ります。(さっきやったことすら忘れるって言ったばっかりだけど…)

本当かどうかは知りませんが学習ピラミッド(ラーニングピラミッド)というのがあって人に物を教えると 90% の知識の定着率だとか。

habi-do.com

Blog に書くということは、とりあえず人に教える風に書くというので、この学習ピラミッドの一番効率よく覚えるところにアプローチできるんだろうなということですね。

技術情報が無いなら作ればいいじゃない?

よく、日本語の技術情報がないっていう話しを聞くことがあるのですが必要なら作ればいいじゃない?ってことで、そういう目的で書いてるものも中にはあります。

例えばこれとか。

blog.okazuki.jp

UWP と Xamarin.Forms は、Blogに書かずに直接 PDF 化してしまったので Google 検索で見つけるということが出来ないのでちょっと後悔してるので、検索できるものとして残すことは大事だなと思ってます…。

www.slideshare.net

www.slideshare.net

書くコツ

わかりやすい記事だとか、はてぶに載ってバズる記事だとか、PVがばかみたいに高い記事だとかどうやって書くのか?という観点もありますが、私が一番気を付けているコツは、自分が書けるレベルにまでレベルを落として実践するのがいいと思っています。 無理すれば自分が簡単に出来るレベル以上のものは書けますが、無理は続かないので無理をしない範囲でやるのが書くコツというか継続的に書くコツだと思っています。

世間一般から見て低レベルだと思われるようなことしか書けなくても、それは自分が低レベルなんだから仕方ないので低レベルからやるしかないんですよね。私の好きな言葉は「継続は力なり」なので継続できるようにやるというのが凄く大事だと思っています。

続けてれば、そのうち段々と自分のレベルは上がっていくはずなので、いつまでも低レベルなことしか書けない!!っていう状態にはならないので出来る範囲で続けるのは本当に大事。

やっててよかったこと

今は日本マイクロソフトに転職してしまったので今は違いますが Microsoft MVP になれました。

マイクロソフト MVP アワード プログラムとは - マイクロソフト MVP

本を書く機会にも恵まれました。(声かけてくれた酢酸先生ありがとう) 本が出たときは Amazon で名前検索したら出てくる!!って感動しました。

ということで

人それぞれ勉強法とかあるけれど、特に自分にあう勉強法が無いなぁ…と思ってる人は問題を細分化して自分でハンドリング出来るレベルまで落として、それを Blog にまとめてアウトプットするというサイクルをお勧めします!

ではでは。

タスク管理何使ってる?私は Visual Stduio Team Services 使い始めました

$
0
0

ゴール

こんな風にタスクの状況を俯瞰したい。

f:id:okazuki:20171211114821p:plain

はじめに

複数のタスクが並行で進むの苦手なんですよね…。可能であれば1つのことに集中したい。

でも、なかなかそうもいかないケースがあります。 小さな仕事が複数平行で走る…つらい。

といってもやらなきゃいけないときは、きちんとタスク管理が必要です。ではやってみましょう。

世の中的には

seleck.cc

ここらへんを使うのでしょうか。

Visual Studio Team Services

5人まで無料。強い。

こいつはプログラムのソースコードのリポジトリとして使えたり、自動ビルドツールとして使えたり、リリース作業までいい感じにしてくれたりします。その中にプロジェクトのバックログを管理したり、それに紐づくタスクを管理したりとかいった機能も入っています。

今回はこれを使ってみようと思います。

色々なテンプレート

プロジェクトの進め方に合わせて、いくつかテンプレートが提供されています。Scrum あたりが今風でいいんですかね? でも、今回は単純にやらないといけないこと、それのステータス管理。そして備忘録と、状況の俯瞰がしたいというのが個人的なニーズです。単純に個人のタスクを管理したいってだけです。Scrum とかまではいらないんですよね。

そんな時には、テンプレートをベースにカスタマイズすることが出来ます。まずトップページの歯車をクリックします。

f:id:okazuki:20171211105805p:plain

そして Process

f:id:okazuki:20171211110012p:plain

すると Agile、Scrum、CMMI が表示されます。これらの3つをベースにカスタムが出来ます。個人的には Scrum のテンプレートには慣れ親しんでるので、これをベースにカスタムしていこうと思います。…を選んで Create inherited process を選びます。

f:id:okazuki:20171211110233p:plain

適当に名前をつけます。

f:id:okazuki:20171211110341p:plain

では早速編集しましょう。編集したいプロセスの名前をクリックで編集できます。Work item types でプロジェクトで管理するべきワークアイテムのタイプが出ます。いろいろありますね。ここらへんのはいらないので全部 Disable にしちゃいましょう。

そして、自分用の ToDo を管理するやつを作ります。New work item type を選びます。適当に埋めます。

f:id:okazuki:20171211111058p:plain

Layout 画面にうつります。Add a field で項目を追加したり、New group でページ内の項目のグルーピングをしたり、New page で新しいタブページを作ったりできます。フィールドはドラッグアンドドロップで移動させたりもできますね。いい感じ。

日付とかチェックボックスとか1行のテキストとか複数行テキストとかあって色々作れますね。適当に作りました。

f:id:okazuki:20171211111552p:plain

次に State タブです。このタスクの進捗具合を定義できます。Completed が Done から変えれないですが、まぁいいでしょう。Resolved で代用すれば。

f:id:okazuki:20171211112101p:plain

最後に、作った Work item type を Backlog levels で Tasks に追加しておきます。これでタスクとして認識してもらえる。

f:id:okazuki:20171211112656p:plain

出来たら、あとはプロジェクトを作るときに Work item process を自作したやつにすれば OK です。

Work item の New からぽちぽちと作成。Discussion でメモを履歴として残せるのでいいですね。

f:id:okazuki:20171211113118p:plain

Work item単位でどういうことがされたかのヒストリーも見れます。

f:id:okazuki:20171211113302p:plain

Sprint とかの使い方

例えば週単位で Sprint 切っておけば毎週何やったかの記録があとで見れます。

Query の使い方

これは、自分の見たいと思うタスクの切り口で探せるのでいいですね。

Dashboard

ここまで来たらあとは Dashboard 作れば自分用タスク管理も大詰めです。Shared Queries によくチェックしたいと思う検索条件のクエリを作っておいて Dashboard に配置します。

f:id:okazuki:20171211114821p:plain

まとめ

Dashboard 出来たらなんか満足感が出てきた。 これ、ちゃんとチームでも使ってみたいなぁ。

タスク管理何使ってる?私は Visual Studio Team Services 使い始めました

$
0
0

ゴール

こんな風にタスクの状況を俯瞰したい。

f:id:okazuki:20171211114821p:plain

はじめに

複数のタスクが並行で進むの苦手なんですよね…。可能であれば1つのことに集中したい。

でも、なかなかそうもいかないケースがあります。 小さな仕事が複数平行で走る…つらい。

といってもやらなきゃいけないときは、きちんとタスク管理が必要です。ではやってみましょう。

世の中的には

seleck.cc

ここらへんを使うのでしょうか。

Visual Studio Team Services

5人まで無料。強い。

こいつはプログラムのソースコードのリポジトリとして使えたり、自動ビルドツールとして使えたり、リリース作業までいい感じにしてくれたりします。その中にプロジェクトのバックログを管理したり、それに紐づくタスクを管理したりとかいった機能も入っています。

今回はこれを使ってみようと思います。

色々なテンプレート

プロジェクトの進め方に合わせて、いくつかテンプレートが提供されています。Scrum あたりが今風でいいんですかね? でも、今回は単純にやらないといけないこと、それのステータス管理。そして備忘録と、状況の俯瞰がしたいというのが個人的なニーズです。単純に個人のタスクを管理したいってだけです。Scrum とかまではいらないんですよね。

そんな時には、テンプレートをベースにカスタマイズすることが出来ます。まずトップページの歯車をクリックします。

f:id:okazuki:20171211105805p:plain

そして Process

f:id:okazuki:20171211110012p:plain

すると Agile、Scrum、CMMI が表示されます。これらの3つをベースにカスタムが出来ます。個人的には Scrum のテンプレートには慣れ親しんでるので、これをベースにカスタムしていこうと思います。…を選んで Create inherited process を選びます。

f:id:okazuki:20171211110233p:plain

適当に名前をつけます。

f:id:okazuki:20171211110341p:plain

では早速編集しましょう。編集したいプロセスの名前をクリックで編集できます。Work item types でプロジェクトで管理するべきワークアイテムのタイプが出ます。いろいろありますね。ここらへんのはいらないので全部 Disable にしちゃいましょう。

そして、自分用の ToDo を管理するやつを作ります。New work item type を選びます。適当に埋めます。

f:id:okazuki:20171211111058p:plain

Layout 画面にうつります。Add a field で項目を追加したり、New group でページ内の項目のグルーピングをしたり、New page で新しいタブページを作ったりできます。フィールドはドラッグアンドドロップで移動させたりもできますね。いい感じ。

日付とかチェックボックスとか1行のテキストとか複数行テキストとかあって色々作れますね。適当に作りました。

f:id:okazuki:20171211111552p:plain

次に State タブです。このタスクの進捗具合を定義できます。Completed が Done から変えれないですが、まぁいいでしょう。Resolved で代用すれば。

f:id:okazuki:20171211112101p:plain

最後に、作った Work item type を Backlog levels で Tasks に追加しておきます。これでタスクとして認識してもらえる。

f:id:okazuki:20171211112656p:plain

出来たら、あとはプロジェクトを作るときに Work item process を自作したやつにすれば OK です。

Work item の New からぽちぽちと作成。Discussion でメモを履歴として残せるのでいいですね。

f:id:okazuki:20171211113118p:plain

Work item単位でどういうことがされたかのヒストリーも見れます。

f:id:okazuki:20171211113302p:plain

Sprint とかの使い方

例えば週単位で Sprint 切っておけば毎週何やったかの記録があとで見れます。

Query の使い方

これは、自分の見たいと思うタスクの切り口で探せるのでいいですね。

Dashboard

ここまで来たらあとは Dashboard 作れば自分用タスク管理も大詰めです。Shared Queries によくチェックしたいと思う検索条件のクエリを作っておいて Dashboard に配置します。

f:id:okazuki:20171211114821p:plain

まとめ

Dashboard 出来たらなんか満足感が出てきた。 これ、ちゃんとチームでも使ってみたいなぁ。

Tokyo HoloLens meetup vol6 で発表してきました

Viewing all 1388 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>