2014年4月5日土曜日

Universal App に備えたい(なるべくお金をかけずに)

(追記 2014/10/25 ... Nokia RDA が2014年8月に終了した件を追記しました)

build 2014 で発表されたuniversal Windows app。
Windows Phone 8.1でWinRT API が動くようになることから、Windows 8.1、 Windows Phone 8.1、 将来的にはXbox ONE でも同じストアアプリを展開することが可能になります。



ただ勿論、同じXAMLのUI 部品にしてもWin8とWPでは中身が違う部分が多いので、UIレイヤについては別コードとなる部分が多いです。別バイナリを1パッケージにまとめて出す感じ。

細かい文句はありつつ全体としては超Welcomeなので、是非やってみたい。のですが、一つ障壁がありまして、

開発に必要なWindows Phone 8.1 エミュレータを動かすには、割と最近のCPUが必要

仮想化を使っているため、Corei3,5,7あたり以降のCPUが必要です。
我が家のCore2Duoは基本×、ダメ、動作しません。酷い。

じゃあ開発マシンをリプレースすればいいじゃない、とマリーアントワネットみたいな事を言える環境には居ないので、どうしようか、というのが以下の話です。

1. WP8の実機を買う


これが実は結構安いです。Amazon.comだとLumia520 が$59で売ってます。開発マシンリプレースより安い。
ただし、この$59のLumia, GSM Onlyなので日本で安いSIM挿して使う、事は出来ないです。完全に開発検証専用ですね。

安!!
これについてはストアアプリ 2ch Sankaを作っているIkuさんに教えて頂きました。有難う。
日本でも使える…W-CDMAなんかが使えるモノについてはExpansysあたりで売ってますが、そこそこのお値段なので今回は除外。
それと、今売っているのは「まだ」Windows Phone 8です。Windows Phone 8.1へのUpdateはもう少し先になります。


2. Nokia RDA - Remote Device Access を使う


※Nokia RDA は2014年8月に終了しました。
端末のカメラを起動するとラボ内の様子が写ったりして、面白いサービスだったのですが。
以降はサービスが運用されていた頃の話です。

――――――――

Nokiaが開発者向けに行っているサービスです。
Nokia社内のラボに設置してある多数のNokia端末に、JavaのRemote Access Appを介して接続できる、という物です。無料。

Nokia RDA
http://developer.nokia.com/resources/remote-device-access

Nokia RDA で端末にリモート接続している様子

左のブラウザに沢山表示されているのが、ラボ内で接続Readyになっている端末。Lumia以外にもAndroidのNokia X等が数十台あります。
JavaのClientで接続し、端末に自分のアプリをインストールして動作を確認する、という感じです。

VS2012 for WP8でビルドしたアプリを、
リモートのLumiaにインストール・実行している様子

ただ、リモート故、パフォーマンスはそれほど良いものではありません。
これ「だけ」で開発を行うのは正直かなり厳しいと思います。
上に挙げた安Lumiaでごりごり開発しつつ、こちらで様々な端末での動作を確認する、という使い方になるでしょうか。

また、こちらもまだWP8.1機は入っていないようです。


2014年4月1日火曜日

従量制接続設定の勧め

この記事のまとめ
  • モバイルルータ+Win8 タブで運用している人は、接続を「従量制接続」に設定しておくと転送量を抑えられるのでお勧め
  • 転送量の多いアプリを作っている人は少し気を付けてあげるといいかも

Win8.1では、ネットワーク接続毎(無線LANならばSSID毎)に、この接続が「従量制」か「定額制」かを設定できます。

  • 「定額制」では、通信量を特に気にしない普通のネットワークの動作をします。
  • 「従量制」では、OS・アプリは「なるべく転送量を減らす」方向でその動作を変えます。

例を挙げると、以下の様な感じです。

定額制
従量制
Windows Update
ごっそり
「必要なものだけ」
デバイスドライバの自動ダウンロード
行う
行わない
ストアアプリの自動更新
行う
行わない
Futa8のカタログ画面
大きいサムネイルをダウンロード
小さいサムネイルをダウンロード

さて、この「従量制」「定額制」ですが、例えば・・・モバイルルータに接続すると、OSがそれを見分けて自動で従量制にしてくれる…所まで親切では無いです。

以下が既定の設定です。


既定値

有線LAN
(定額制固定)
変更不可
無線LAN (宅内無線LAN、モバイルルータや携帯への無線LAN接続等)
定額制接続
変更可
WWAN(PC内蔵の3G/LTE Modem)
従量制接続
変更可

つまり、何が言いたいのかというと…
3GLTE, WiMax なモバイルルータに既定の設定のまま無線LAN接続していると、Windows Update やストアアプリの更新を裏でごっそりやられて転送量的に泣きを見る可能性が高い
というお話です。


ストアアプリの更新をごっそりやられている様子
4月1日にどかんと来ましたね…


接続を従量制に変更するには

設定変更は簡単で、
設定チャーム→ネットワーク→接続 を開き、

設定チャーム→ネットワーク→接続


設定を行う接続をクリックし、「従量制課金接続として設定する」をオンにします。

接続→「従量制課金接続として設定する」
 また、「ネットワーク一覧に概算データ使用量を表示する」設定もオンにしておくのがお勧めです。
設定によってどれくらい転送量を減らせたかがなんとなく分かります。

アプリを従量制対応にする

※ 2014年4月 現在のストアアプリの規約では、従量制対応はNice to have で, 以前のようなmandatoryでは無くなっています。

ネットワークのコスト設定は適宜変わるので、変更のイベントハンドラを作っておき、それをアプリローカルに持っておいて適宜参照、的な感じになるかと思います。
以下は futa8 で使っているコードです。
MSさんのSDKのサンプルコードを改変して使っています。
取得できるconnectionCost を、UsageModel的には3タイプ…OptIn / Conservative / Normal に読みかえて動作を変える、というのが期待値のようです。

  //どこぞの初期化コードで
      // ネットワーク状態変更イベントハンドラの登録
                NetworkInformation.NetworkStatusChanged += OnNetworkStatusChange;
                // 初期状態を一発取得しておく
                OnNetworkStatusChange(null);

  .....

        void OnNetworkStatusChange(object sender)
        {
            try
            {
                string connectionProfileInfo = string.Empty;

                // 今使ってる接続プロファイルを取得
                ConnectionProfile InternetConnectionProfile = NetworkInformation.GetInternetConnectionProfile();

                if (null == InternetConnectionProfile)
                {
                    return;
                }

                // 接続コストを取得
                var connectionCost = InternetConnectionProfile.GetConnectionCost();

                if (null == connectionCost)
                {
                    return;
                }

                // connectionCost を 3種類…OptIn / Conservative / Normal に読みかえる
                // SDKにあった解釈のパクリ
                
                if (connectionCost.Roaming || connectionCost.OverDataLimit)
                {
                    // Roaming 又は 使用量超過 の場合
                    // OptIn - ユーザーの許可が必要
                    // futa8では未実装 (Conservativeと同じ動作)
                    futaDataView.futaDataSource.NetCost = DataModel.FutaDataSource.FutaNetworkCostType.OptIn;
                }
                else if (connectionCost.NetworkCostType == NetworkCostType.Fixed
                    || connectionCost.NetworkCostType == NetworkCostType.Variable)
                {
                    // 転送量に上限あり 又は 従量制接続 の場合
                    // Conservative - 保守的
                    // 転送量をなるべく抑える方向
                    // futa8ではカタログ画面でつかうサムネイルのダウンロードサイズを減らす
                    futaDataView.futaDataSource.NetCost = DataModel.FutaDataSource.FutaNetworkCostType.Conservative;
                }
                else
                {
                    // その他 == 無制限
                    // Normal
                    // ノーリミットなアクセス
                    futaDataView.futaDataSource.NetCost = DataModel.FutaDataSource.FutaNetworkCostType.Normal;
                }

            }
            catch (Exception e)
            {
                e.GetType();
                // 特にやる事無い
            }
        }