Bing Maps iOS Control を試してみた。

Bing Maps iOS Controlというものがリリースされていたので試してみました。

APIキーの取得

Bing Mapsをつかったアプリを作るためには、APIキーを取得しなくてはなりません。Bing Maps Account Centerへアクセスします。

今回は新規登録だったので、Createを。Live IDのログインを要求されます。

名前とメールアドレスを登録します。

その後、Create or view keysへいって、新しいAPIキーを登録します。

キーができるので、どこかにメモしておきます。

プロジェクトの初期設定

Xcode 4でのやりかたです。

まず、Bing Maps iOS Controlのダウンロードページからダウンロードします。

次に、Bing Maps iOS Controlを使いたいプロジェクトを新規作成するか開き、ダウンロードされたDMGファイルにはいっているMapControlフォルダをFinderからそのフォルダのままでXcodeファイルツリーのプロジェクトの直下にドロップします。そして出てきたダイアログで「Copy items...」のチェックをオンにします。

次に、プロジェクトを選択してプロジェクトの設定画面を開き、PROJECT->Build Settingsを開きます。

「Header Search Pathes」に「MapControl」を追加します。

「Other Linker Flags」に「-ObjC」「-all_load」を追加します。

次にTARGETSからアプリのビルドターゲットを選択し、「Build Phases」を開きます。「Link Binary with Libraries」をひらいて、以下のフレームワークを追加します。

  • CoreData.framework
  • CoreLocation.framework
  • OpenGLES.framework
  • QuartzCore.framework
  • SystemConfiguration.framework
  • libxml2.dylib
  • libz.dylib

最後に、Info.plist に BingMapsKey を定義して完了です。

Bing Maps Controlを配置する。

Interface BuilderでBing Maps Controlを配置してみます。

まず、適当にUIViewを配置します。

次に、インスペクタのカスタムクラスで、BMMapViewに変更します。

画面右上、Editorの切り替えでAssistant Editorへ変更します、右側にヘッダファイルが現れます。BMMapViewにしたViewをcontrolキー押しながらヘッダファイル側へドロップするとアウトレット接続の入力になるので、mapView と名前をつけます。

さらに、このヘッダファイルに #include と、クラスの定義にプロトコルの設定を入れます。最終的にはこんな感じです。

#import <UIKit/UIKit.h>
#import "BingMaps/BingMaps.h"

@interface BingMapViewController : UIViewController <BMMapViewDelegate> {
    
    BMMapView *mapView;
}
@property (nonatomic, retain) IBOutlet BMMapView *mapView;

@end

次に、viewDidLoadでデリゲートの接続を書きます。*1

- (void)viewDidLoad
{
    [super viewDidLoad];

    mapView.delegate = self;
    
    // 現在地マーカーの表示設定
    mapView.showsUserLocation = YES;
}

これで実行すると、Bing Mapsが表示されます。

モバイルでのBing Mapsというと、今現在でのWindows Phone 7の残念地図が思い出されますが、これが出てこなくて一安心でした。(Windows Phone 7でGoogle Map on Bing Map Controlを実現する - 酢ろぐ!から勝手に引用)

マーカーを配置する

Bing Maps Controlでは、表示位置や位置に関連する住所などの情報を表すBMMarkerと実際に情報を表示されるBMMarkerViewは分離されて考えられています。特にMarkerViewに関してはUITableViewと同じようなreuseIdentifierのアーキテクチャで実装されていて、メモリに優しい作りになっています。

また、BMMarkerはプロトコルであり、これを実装さえすれば任意のクラスをBing Maps Controlへマーカーとして追加することができます。一般的な実装としてはBMEntityが用意されています。

また、実際に表示させるマーカーはBMMarkerViewを基底にして、BMPushpinViewがあります。

実際にこれを配置するには、まずMarkerを追加します。

CLLocationCoordinate2D loc = CLLocationCoordinate2DMake(0, 0);
BMEntity* entity = [[[BMEntity alloc] initWithCoordinate:loc bingAddressDictionary:nil] autorelease];
[mapView addMarker:entity];

その後、このマーカーの位置が描画される際にMarkerViewの要求がデリゲートに渡されますので、MarkerViewをつくって返します。

- (BMMarkerView *) mapView:(BMMapView *)aMapView viewForMarker:(id< BMMarker >)marker {
    static NSString* markerIdentifier = @"PushPin";

    BMMarkerView* markerView = [mapView dequeueReusableMarkerViewWithIdentifier:markerIdentifier];
    if (markerView == nil) {
        markerView = [[[BMPushpinView alloc] initWithMarker:marker reuseIdentifier:markerIdentifier] autorelease];
    }
    else{
        markerView.marker = marker;
    }
    
    return markerView;
}

実行すると、指定した位置にマーカーが設置されます。

まだあえて選択する理由はないけど

ここまで、Bing Maps iOS Controlの使い方をみてきましたが、見ての通りMap Kitと比べて初期設定が面倒ですし、iOS4で追加されたような線や円の描画クラスもないので、今の段階ではあえて機能の見劣りするBing Maps Controlを選択する理由が見いだせません。

ただ、今後独自の方向性で機能拡張をする可能性や、地図がGoogle Mapsにくらべて情報が多い地域もあるかもしれませんし、Map Kitのデータ提供元であるGoogle Mapのポリシーと合わないけど、Bing Mapなら合うという場合もあるかもしれません。

そういった意味では、選択肢が増えるというのはいいことだと思います。Azure方面でも超絶めんどくさいAPNSまわりをなんとかしたりできるWindows Azure Toolkit for iOSとか出てきていて、いい流れではないかなーっと。

*1:ただ、デリゲートの接続もぜひInterface Builderでやらせてほしかったなあ。