2015年8月12日水曜日

WinRT とタイムゾーン・夏時間の話

先日、北朝鮮が2015年8月15日を以て時制を現在のUTC+9から30分遅らせるよというニュースがありました。UTC+8:30になると。意図はさておき、とにかく一国の採用するタイムゾーンが変わる事になります。

で、この手の話はそれほど珍しい事ではなく、年に数回はどこかの国や地域でタイムゾーン・夏時間の変更が行われています。Windows の場合、その都度Windows Updateで対応するタイムゾーン・夏時間の情報が配信されます。


Windows のタイムゾーン・夏時間更新は、Technetのblogで通知されます。
普通に使っていればWindowsUpdateで自然と更新される感じです。
右のArchiveを見ると分かるように、結構頻繁に更新されます。


アプリ側は、上品に…自分の中にタイムゾーン情報等を持たず、OSのサービスから情報を取るようにしていれば、OSの更新に合わせて自動的に新しい情報を使えるようになるという仕組みです。

Wheel World Clock のタイムゾーン設定UI
これらのタイムゾーン(時間と名前)はアプリ内部で持っている訳ではなく、
OSの持っている情報を右から左に表示しているだけです。
北朝鮮用のタイムゾーン情報が配信されれば、ここにその旨が追加される…はず。


ただ、WinRT 上でタイムゾーン・夏時間の列挙・変換を行うには注意が必要です。

…この言い回しで、賢明なる読者様ならばあーはいはい大体わかったWinRT だからねだからなのね?とお分かりでしょう。はいそれで正解で、

WinRT API からは、「自分のローカルタイムゾーン」と、「UTC」 この二つしか見えない作りになっています。

  • OSのサポートするタイムゾーン・夏時間の列挙
  • 各タイムゾーン間の時間の変換

がバッサリ落ちてるんですね。困る。

※とはいいつつ、世界時計でも作るのでなければ…ローカルタイムとUTCだけで「大抵は」済む話かもしれません。

ただOS自体には機能があるので、それを叩くPCLがNuGetで公開されています。ありがたいことです。

WinRTTimeZones
https://www.nuget.org/packages/WinRTTimeZones/

ページにはWinRT, WinStore, WP8, WPA81, .NET4.5 がサポート環境として記載されていますが、試したところ Win10 UWP でも使えています。

拙作の世界時計アプリ Wheel World Clock も、このNuGet Packageを使ってタイムゾーンの列挙・時間の変換をWindows Phone 8.1 / Windows 8.1 / Windows 10 UWP 上で行っています。




※ 30分刻みのタイムゾーンは例が無い、けしからん!という論調のニュースが一部にはあるようですが、そんなことは無く…イラン、ネパール、中央オーストラリアのようにUTCから30分ずれたタイムゾーンを採用している国・地域は幾つか存在します。


2015年8月3日月曜日

Wheel World Clock UWP版 を公開しました


世界時計アプリ Wheel World Clock の Universal Windows Platform (以下UWP)版を公開しました。


Wheel World Clock
https://www.microsoft.com/store/apps/wheel-world-clock/9nblggh10zzn


今回の作業、UWP化の恩恵をフルに活用しよう!という訳では無く、この元々簡単な時計アプリをダシにしてアプリのUWP化・ビルド・ストアへの提出等の作業を一度全部通して試してみるのが目的です。

このため、UWPの売りであるところのAdaptiveなLayout変更やx:Bind等は全く使っていません。
Appとして破綻しない程度に動けばOK!くらいの簡単な実装です。



Win10 Desktop でWheel World Clock UWP が動いている様子



UWP対応でやったこと


Wheel World Clock(以下WWC)は元々「Win/WP8.1の」Universal アプリで、

  • Windows 8.1用Project
  • Windows Phone 8.1用Project、
  • 共用のShared Project

 から成るソリューションになっています。

今回、これに「Universal Windows」…UWP のProjectを追加し、3Project+Sharedのソリューションとする変更を行いました。


※今回は練習のため8.1 UniversalにUWPを追加する形にしていますが…今後特にWin/WP8.1用をメンテする予定がないのなら、素直にUWPだけのソリューションにしたほうが話は早いと思います。


UWP Project の追加


追加時にはフォルダ作成先に気を付け、三つ仲良く並ぶように作成。

Project三つ+Shared一つ


フォルダはこんな感じに並びます
ソリューション .sln ファイルは一つ上のフォルダ


8.1 Sharedは、各々のProjectの名前空間を共通にすることでSharedのソースを共通に参照する、という仕掛けになっています。
このため、UWP Projectをその名前空間に変更します。

  • Main.xaml / cs
  • PackageManifestのスタートアップを指定してるとこ


そして、参照にShared Projectを追加します。

Shared.projitem を参照に追加


最後に、App.xaml / cs を削除 (App.xaml / cs を共用している場合)。

ここで一発Appをビルドし、実行されAppのWindowが出てきたらソリューション・プロジェクトの枠組み作成はとりあえず成功です。

Project Unique な部分の変更


ここから先はApp Specificな部分が多いのですが、その中でもある程度アプリ共通な部分を挙げてみます。




備考…WWCの構成

WWCの構成を簡単に説明します(以降のUWP化作業理解の助けのため)


アプリが持っているページは二つ


  • Main.xaml  メイン。時計を表示するページ。
  • Cities.xaml  表示するタイムゾーンをカスタマイズするページ。

Win8.1用のCities ページ

WP8.1 用のCities ページ





そして、ぐるぐる回る時計はユーザーコントロールとして作ってあります。

Win8.1/WP8.1 Universal では、Main・CitiesをそれぞれのProject用、ユーザーコントロールは共通として作っていました。
今回のUWPも、MainとCitiesのみ別持ち、時計は共通のユーザーコントロールをそのまま使うという方針です(このためコード変更があんまり無い…)



SuspensionManager, NavigationHelper等のテンプレート部分


このあたり、今回UWPはBlankで作ったため初期状態では何もありません。

そこで、Microsoft が Githubに上げているSample集から当該ファイルをパチっ(持ってきて)使います。
今回、名前空間だけ変更しました(そのままでも別にいいですが…使う人のUsingが変わるだけ)

Commonに置くファイル 最低限これだけあればなんとか


一つ注意なのは、これらのSourceは8.1と異なりUWP用であるため、中でMobile DeviceFamilyのExtensionを参照しています。このため、参照にMobile Extensionを追加する必要があります。


App.xaml.cs の変更


WWCでは Application Insights を使っています。今回、UWP用を別集計としたいので…#ifdefで分け、UWP用のInstrumentation Keyを指定します。


Windowの最小サイズ変更・タイトルバーの色変更


UWPではAppの最小サイズを縦・横で指定できます。
指定はManifestでは無くコードで行います。
また、タイトルバーの色もここで変更します。OS標準の白は正直見づらいので。

App.xaml.cs で指定している様子
App.xaml.cs はShared コードであるため、UWP用の部分はIFDEFで分けます。


Main.xaml の変更


WWCでは、Windows用に三点リーダのAppBar引きずり出しボタンを自作して使っていました。UWPでは同じ物がCommandBarに組み込まれているため、そちらを利用しました。

広告

困ったことに、UWP 用のMicrosoft Advertising SDK はまだリリースされていません。無いものは仕方ないので、今回UWP版には広告を出さないことに決め、関連コードをコメントアウトしました。

Cities.xamlの変更


WWCでは、

  • 電話用 Pivot
  • PC用 Hub

で、UIを作り分けていました。

今回のUWP版ではPC・電話両方で動くわけですが…Hubは電話では使いづらいため、電話用に作ったPivot版をそのまま持ってくることにしました。 PCで動かすと見た目は少し悪いです。

UWP用のCities ページ
PC・電話ともにこれが表示されます
上のWP8.1用と構成が同じなのが見て分かります



また、元の電話UIにはバックボタンをつけていませんでした。これは電話では常にバックボタンがOS(またはハードウェア)で用意されているため、アプリ側では(特に処理が無いのなら)何もしなくてもよかったためです。

今回はそうもいかないので…タイトルバーに表示するバックボタンを使うことにします。
これはよくできていて、
Window表示…タイトルバーにバックボタン表示
フルスクリーン表示…タスクバーにバックボタン表示

という切り替えをOSが勝手にやってくれます。ありがたい。


バックボタンの追加
Cities.xaml.csのコンストラクタで行っています


タイトルバーのバックボタン


Win2D


WWCでは文字盤に貼り付ける画像の切り出しにWin2Dを使っているのですが、このライブラリがVS2015RTMのタイミングでWin8.1用とUWP用に分かれました。
このため、UWP版を使用するよう変更しました。



画像リソースの追加


これが一番面倒なんですが… UWP用にアイコン・タイル・スプラッシュ画面等の画像リソースを作成します。
UWPではベースのスケールが200になっているので、そのままではWin/WP8.1用の画像は使えないです。諦めて一個一個リサイズしましょう…
(.csprojでスケールを指定する方法も一応あるのですが、今回はUWP標準に揃えました)

また、UWPは電話・PC共通ですが…特に電話ではタイルを透明にすると見栄えが大変良いので、タイルはなるべく背景を透明で作ると良いです。

UWP用画像リソース


ストアへのアップロード用パッケージのビルド


本来なら引っかかる所では無いのですが…8月3日現在のWin10 SDKには問題があり、私のPackageはこれに引っかかってしまいました。
詳しくはMSDN Forumの当該スレッドを見て頂ければと(私も書いてます)。このスレの通り、更新版の.targets fileを使う事でBuildに成功しました。

RTM Known Issue: Release configuration fails to build on using Desktop and Mobile Extension SDKs in a Universal Windows app
https://social.msdn.microsoft.com/Forums/en-US/2887e169-348d-4d97-a359-aee413b5fa26/

この問題、鍵になっているのは.NET Native 用のFileです。
既定の設定では、UWP Projectは

  • Debug Build .NET Native Off
  • Release Build .NET Native On

になっています。
このためリリースビルドのアップロードパッケージ作成で問題が発覚した感じです。
私のようにリリース直前にエラー出て慌てるのもなんなので、開発中も「たまには」リリースビルドを行い様子を見るのをお勧めします。
私の経験では….NET Nativeに対応するためにコード変更が必要になった事は無いのですが、有るときは有るので(凝ったSerializerを自作してるとか)…その意味でもたまにリリースビルドを行い動作を確認するといいよ!とBuildでMSのエンジニアが言っていました。

なお….NET Native をOnにするとコンパイル・ビルドに偉く時間がかかります。私のポンコツマシン(Core2Duo 2GHz, Memory 4GB, SSD)だと、ARM/x86/x64 全部ビルドするのに17,8分。

ストアへのアップロード


ここはWebの言うとおりに進めることができ、特に引っかかる所は無かったです。
WWCは既にWin8.1とWP8.1用のパッケージがアップロード済みで、それに今回ビルドしたWin10 UWP パッケージが追加される形になります。
Win8.1/WP8.1用アプリが独立していた頃とは異なり、ストア上のエントリ…登録の扱いは一つ、その中に各OS用のパッケージが格納される感じです。

Win10 / Win8.1 / WP8.1 それぞれのパッケージが並んでいる様子


ユーザーがストアにアクセスし「インストール」ボタンを押すと、システムに応じたパッケージのみがDLされます(Win10に無理くりWin8.1用を入れる、とかは無し)。


最後に…


VS2015RTM+Win10SDK、出たばかりという事もあり中々スリリングでして…私のポンコツマシンだと、Win10 をクリーンインストールした上にVSをインストールした環境でも頻繁にフリーズが発生し、若干使い物にならない感じ(マイルドな表現)です。特にスタートアッププロジェクトを変更すると100発100中で死ぬんですが。困った。

そんな中でも今回の作業や画像掲示板ブラウザ F10の開発を続けられているのは、Azure VM上に安定したWin10+VS2015の仮想環境を確保できているのが大変大きいです。
本来なら使用料が発生する所ですが、昨年 Microsoft Taiwan が主催したアプリコンテスト「MSCC」の参加賞として3年分の「AzureとVisualStudio Enterpriseをタダで使える権」を頂いたので無償で使えています。本当に、Microsoft Taiwan には感謝しか無いです。有難うございます。




2015年8月1日土曜日

暑中お見舞い申し上げます


Sunset of Kashiwazaki, 柏崎の夕日


お暑うございます。つらい。重力すら感じさせる日差しに脳天から貫かれる日々が続いています。皆様は御無事にお過ごしでしょうか。


(この項、暑中見舞いにかこつけて今年前半をざっくり振り返ろうという趣旨です)


//Build と Universal Windows Platform

5月頭にMicrosoftの開発者イベント Build があり、Universal Windows Platform の情報が沢山出ました。PC / Phone / IoT ./ XBOX 等、Win10 が動く環境ならアプリを1バイナリで揃えてしまおうぜという。

ここでも記事を幾つか書きました。

Windows 10 UAP お勉強メモ
http://ddlgjp.blogspot.jp/2015/04/windows-10-uap.html
Win10 UWP メモ
http://ddlgjp.blogspot.jp/2015/05/win10-uwp.html
Win10 UWP 文書リンク&小ネタ
http://ddlgjp.blogspot.jp/2015/06/win10-uwp.html

Build2015 Day1 Session 視聴メモ
http://ddlgjp.blogspot.jp/2015/05/build2015-session.html
Build2015 Day2 Session 視聴メモ
http://ddlgjp.blogspot.jp/2015/05/build2015-day2-session.html
Build2015 Day3 Session 視聴メモ

(Session視聴メモは自分でいうのも何ですが、かなり便利なのでお勧め。PowerPointのDeck見るだけでは分からん事多いです。)

Win10 と言っても、PCと電話で同じOSが走る…訳ではないです。電話用のは「for Mobile」で別物であり、Windows Phone 8.1から進化させたOSです。これで1バイナリほんとに行けるんかなぁ?と若干怪しんでいた処はあります。

が、Win10 MobileのPreview Buildが進むにつれ…同じバイナリでPC・電話ほんとに一緒に動くなこれ!というのが分かってきて、これ面白いなーと。
8.1時代の共有ソース形式「ユニバーサル」も結構便利ではあったのですが、バイナリ1つ、ソース1つ、パッケージも1つというのは諸々の手間が圧倒的に違う。少ない。楽。これも下のF10をいじってて日々実感してるところです。


F10

この4月から、「F10」という画像掲示板ブラウザを作っています。

特徴は

  • Universal Windows Platform アプリ … Win10 PC / タブレット / スマホ …で動作します。
  • futaba, 4chan, 8chan 対応
  • PC / 電話等、共通のマイクロソフト アカウントで使っているシステム間での未読・今読んでるスレの同期


これ、Win8.1用画像掲示板ブラウザ futa8のUWPへの移植ではなく、新規に書き起こしているので結構時間が掛かっています。

進捗は…今のペースだと、9月中に出せるかな?無理かな?くらいな感じです。


写真は新潟県・柏崎の夕日です。
猛暑はまだ続くようです。どうぞご自愛下さい。


以下は開発中のF10 スクリーンショットです。動作確認用にUIを並べているだけなので、最終版と大いに異なるのは確実です。


F10を電話で動かしている様子・スレ表示画面
右・左でPivot(タブ)移動、右上のハンバーガーで下のカタログがうにょっと出てくる感じ


カタログ画面
ここで右・左で板を切り替え

同じF10をPCで動作させた場合の様子