使ってみよう! Bing API/SDK

第5回 Hello, Bing Map App!──Silverlightで作るBing Mapsアプリケーション(5)

この記事を読むのに必要な時間:およそ 6 分

はじめに

今回はネットワークアクセスを行うMap Appを作ってみましょう。Silverlightアプリケーションで画像やWebページダウンロードなどのWebアクセスは,.NET Frameworkと同様にSystem.Net.WebClientクラスを使用すると簡単にできますが,Map App SDKには,ネットワークアクセス用の機能が提供されています。クラスが用意されているだけでドキュメント類は皆無なのですが,今回はこれを使用してネットワークアクセスに挑戦してみましょう。

Webアクセス

NetworkManagerContract

ネットワークアクセスにはNetworkManagerContractを使用します。このContractで提供される機能を使用すると,WebClientに似たPrioritizedWebClientクラスを使えます。特徴は,名前にあるようにWebアクセスのとき優先順位を設定可能になっています。地図の隠れている周辺部分の情報を低優先で先行して情報を取得しておくなどの用途が想定されているのではないかと思われます。また,このContractを使用するとネットワークアクセスが発生していないアイドル状態を知ることができます。

コードは,これまでと同様にContractの機能を使用するため,次のようにプロパティを宣言します。

[ImportSingle("Microsoft/NetworkManagerContract", ImportLoadPolicy.Synchronous)]
public NetworkManagerContract NetworkManagerContract { get; set; }

プラグインクラス

上記のプロパティの宣言を含む,今回作成する プラグインの元となるコードは次のようになります。これまでの内容を参考にプラグインクラスとレイヤークラスを作成してください。

NetworkSamplePlugin.cs:

namespace NetworkSampleMapApp
{
    using Microsoft.Maps.Core;
    using Microsoft.Maps.Plugins;
    using Microsoft.Maps.Network;
    using Microsoft.Maps.MapControl;
    using System;
    using System.Xml;
    using System.Windows.Controls;

    public class NetworkSamplePlugin : Plugin
    {
        [ImportSingle("Microsoft/MapContract", ImportLoadPolicy.Synchronous)]
        public MapContract DefaultMap { get; set; }

        [ImportSingle("Microsoft/LayerManagerContract", ImportLoadPolicy.Synchronous)]
        public LayerManagerContract LayerManagerContract { get; set; }

        [ImportSingle("Microsoft/PushpinFactoryContract", ImportLoadPolicy.Synchronous)]
        public PushpinFactoryContract PushpinFactoryContract { get; set; }

        [ImportSingle("Microsoft/ModalDialogContract", ImportLoadPolicy.Synchronous)]
        public ModalDialogContract ModalDialogContract { get; set; }

        [ImportSingle("Microsoft/NetworkManagerContract", ImportLoadPolicy.Synchronous)]
        public NetworkManagerContract NetworkManagerContract { get; set; }

        private CityLayer mainLayer;

        public override void Initialize()
        {
            base.Initialize();
            this.mainLayer = new CityLayer(this.Token, this);
        }

        public override void Activate(System.Collections.Generic.IDictionary<string, string> activationParameters)
        {
            if (LayerManagerContract.ContainsLayer(this.mainLayer))
            {
                LayerManagerContract.BringToFront(this.mainLayer);
            }
            else
            {
                LayerManagerContract.AddLayer(this.mainLayer);
            }
        }
    }
}

CityLayer.cs:

namespace NetworkSampleMapApp
{
    using Microsoft.Maps.Core;
    using Microsoft.Maps.Plugins;
    using System;

    public class CityLayer : Layer
    {
        private NetworkSamplePlugin plugin;

        public CityLayer(PluginToken pluginToken, NetworkSamplePlugin plugin)
            : base(pluginToken)
        {
            this.plugin = plugin;
            this.Title = "Network sample";
        }
    }
}

以上のコードを元に,追記していきます。

PrioritizedWebClient

それでは,PrioritizedWebClientクラスを使ってWebアクセスしてみましょう。PrioritizedWebClientクラスは直接インスタンスを生成するのではなく,CreatePrioritizedWebClientメソッドによって取得します。

var client = NetworkManagerContract.CreatePrioritizedWebClient();

Webページを文字列としてダウンロードするには,PrioritizedWebClientクラスのDownloadStringAsyncメソッドを使います。優先順位を指定する場合,Priorityプロパティを使用します。

client.Priority = NetworkPriority.Low;
client.DownloadStringCompleted += new EventHandler<PrioritizedDownloadStringCompletedEventArgs>(client_DownloadStringCompleted);
client.DownloadStringAsync(new Uri("http://gihyo.jp/"));

非同期メソッドのため,ダウンロードが完了したときのメソッドを用意する必要があります。ここでは,前回に紹介したダイアログを使ってダウンロードした文字列を表示するようにしています。

void client_DownloadStringCompleted(object sender, PrioritizedDownloadStringCompletedEventArgs e)
{
    if (e.Error != null)
    {
        ModalDialogContract.Open("Error", new TextBox() { Text = e.Error.ToString() });
    }
    else
    {
        ModalDialogContract.Open("Success", new TextBox() { Text = e.Result });
    }
}

Webページダウンロード部分をメソッド化して,以上のコードをまとめると以下のようになります。

private void DownloadString()
{
    var client = NetworkManagerContract.CreatePrioritizedWebClient();
    client.Priority = NetworkPriority.Low;
    client.DownloadStringCompleted += new EventHandler<PrioritizedDownloadStringCompletedEventArgs>(client_DownloadStringCompleted);
    client.DownloadStringAsync(new Uri("http://gihyo.jp/"));
}

void client_DownloadStringCompleted(object sender, PrioritizedDownloadStringCompletedEventArgs e)
{
    if (e.Error != null)
    {
        ModalDialogContract.Open("Error", new TextBox() { Text = e.Error.ToString() });
    }
    else
    {
        ModalDialogContract.Open("Success", new TextBox() { Text = e.Result });
    }
}

作成したDownloadStringメソッドを,Activateメソッド内で呼んでみましょう

public override void Activate(System.Collections.Generic.IDictionary<string, string> activationParameters)
{
    if (LayerManagerContract.ContainsLayer(this.mainLayer))
    {
        LayerManagerContract.BringToFront(this.mainLayer);
    }
    else
    {
        LayerManagerContract.AddLayer(this.mainLayer);
        DownloadString(); // ← 追加
    }
}

そして,プラグインを実行してみます。結果は図1のようになったのではないでしょうか。

図1 実行結果(エラー)

図1 実行結果(エラー)

エラーが発生し例外の内容が表示されてしまったのではないかと思います。Silverlightアプリケーションでは,アプリケーションとは異なるドメインへ(ここでは,アプリケーションはwww.bing.com,アクセスしようとした先は,gihyo.jp)のアクセスは,セキュリティのため許可がない場合できません。

著者プロフィール

松江祐輔(まつえゆうすけ)

日本システムウエア株式会社 勤務。現在,ハードウェア設計・検証業務を担当。大学生・大学院生時代はベンチャー企業 有限会社ミレニアムシステムズにプログラマーとして従事。趣味はプログラミング。好きな言語はVisual Basic。Microsoft MVP for Windows Live Platform(Jul 2010 - Jun 2011),Windows Live(Jul 2011 - Jun 2013)。

URL:http://katamari.jp

コメント

コメントの記入