Flickr APIのエンドポイントは「http://api.flickr.com/services/rest/」です。これに、いろいろなパラメータを付けてアクセスすることで、APIをコールできます。ユーザー認証を必要とする機能もありますが、今回のように、Web全体に公開された写真を検索するだけなら、ユーザー認証は不要です。
「指定した緯度経度の周辺の写真を取得する」場合は、次のようなURLになります(青文字の部分は、適宜書き換えてください)。
コーディングを始める前に、取りあえずWebブラウザのURL欄に入れて試してみるといいでしょう。このURLに含まれる各パラメータの意味を簡単に説明します。
機能を指定します。検索や投稿などさまざまな機能があります。今回は「画像の検索」を行う「flickr.photos.search」メソッドを利用します(参考:Flickr Servicesメソッド一覧)。
アプリケーションのAPIキーです。先ほど取得した値を必ず明記しなければいけません。
検索の基準地点の緯度です。緯度経度は世界測地系です(ちなみに、日本発のサービスでは、世界測地系と日本測地系を選べるもの、デフォルトで日本測地系が選ばれるものもあります。iOS SDKでは、位置情報は全て世界測地系を使います。マッシュアップの際には測地系をチェックしてください)。
デフォルトでは、画像のタイトルやIDなど、写真の最低限の情報しか含まれていません。さらに詳しい情報を取得したい場合は、欲しい情報の種類をカンマ区切りで指定します。今回は、サムネイルのURLの「url_t」と、位置情報の「geo」、そして投稿者の名前の「owner_name」を指定しました。
このURLにHTTPリクエストを送信すると、次のようなXML形式のレスポンスが得られます。
では、このXMLデータをパースして、地図上に表示してみます。
まずは、写真情報を格納する「Photo」というクラスを作ります。
Photoクラスは、6つのプロパティを持ったシンプルなクラスです。MKMapViewにそのまま追加できるように、「MKAnnotation」というプロトコルを実装しました。アノテーションのタイトルとして写真のタイトルを、サブタイトルとして投稿者の名前を返すようにしています。
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
@interface Photo : NSObject <MKAnnotation> {
NSString *title; //写真のタイトル
CLLocationCoordinate2D coordinate; //座標
NSString *owner; //投稿者ーナーID
NSString *ownerName; //投稿者名
NSString *photoId; //写真のID
NSString *thumbUrl; //サムネイル画像のURL
}
@property (nonatomic, retain) NSString *title;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, retain) NSString *owner;
@property (nonatomic, retain) NSString *ownerName;
@property (nonatomic, retain) NSString *photoId;
@property (nonatomic, retain) NSString *thumbUrl;
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate;
- (NSString *)title;
- (NSString *)subtitle;
- (NSString *) url ;
@end
#import "Photo.h"
@implementation Photo
@synthesize title;
@synthesize coordinate;
@synthesize owner;
@synthesize ownerName;
@synthesize photoId;
@synthesize thumbUrl;
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate {
coordinate = newCoordinate;
}
- (NSString *)title {
return title;
}
- (NSString *)subtitle {
return ownerName;
}
- (NSString *) url { //……【1】
return [NSString stringWithFormat:@"http://www.flickr.com/photos/%@/%@",
owner, photoId];
}
@end
【1】の「url」メソッドは、Flickrのサイト上で写真を見るためのURLを返すものです。写真を閲覧するには、以下の形式のURLにアクセスします。
http://www.flickr.com/photos/【投稿者のID】/【写真のID】
次に、XMLパーサを作りましょう。「FlickrPhotoParser」という名前のクラスを新規作成します。
XMLのパースには、iOS SDK標準のXMLパーサである「NSXMLParser」というクラスを利用します。このNSXMLParserは、「SAX」と呼ばれるタイプのXMLパーサです。XMLパーサは、大きく分けると、DOMとSAXの2種類があります。
XMLを先頭から順に読んでいき、「タグの開始」「タグの中身の検出」「タグの終了」などを検出したら、その都度イベントとして通知するもの。開発者は、それらのイベントをハンドルするコードを書かなければなりません。
文字列をパースし、それを木構造のオブジェクトに一気に変換してくれます。詳細は、以下を参照してください。
NSXMLParserはSAXタイプなので、「タグの開始」などの通知を受けて適宜処理を行うイベントハンドラを実装します。イベント通知を受け取る側のクラスは、「NSXMLParserDelegate」プロトコルを実装します。
#import <Foundation/Foundation.h>
#import "Photo.h"
@interface FlickrPhotoParser : NSObject <NSXMLParserDelegate> {
NSMutableArray *list;
}
@property (nonatomic, retain) NSMutableArray *list;
- (NSArray*) fetchNearbyPhotos: (CLLocationCoordinate2D) centerCoordinate;
@end
【1】の個所には、アプリのAPIキーを入れてください。
【2】の「fetchNearbyPhotos」メソッドは、緯度経度を受け取り、画像を検索し、Photoインスタンスを格納したNSMutableArrayを返すメソッドです。【3】の個所でURLを指定してNSXMLParserインスタンスを生成し、【4】の個所で実際にリクエストを送信し、パースを開始します。
【5】の「parserDidStartDocument」は、「ドキュメントの開始」のイベントをハンドルするメソッドです。ここでは、NSMutableArrayインスタンスを生成しています。生成したPhotoインスタンスはこのNSMutableArrayインスタンスに順次追加していくことにします。
【6】は、「タグの開始」の通知をハンドルします。引数「elementName」は、タグの名前です。写真の情報を含んだ「photo」タグを見つけたら、その属性「attribute」を読み、生成したPhotoインスタンスのプロパティとしてセットしていきます。
<photo>タグは、以下のように、属性値として写真の情報が含まれています。
<photo
id="◯◯◯◯◯" owner="◯◯◯◯◯" secret="◯◯◯◯◯"
server="2654" farm="3" title="つけめん並盛 味玉つき"
ispublic="1" isfriend="0" isfamily="0"
latitude="35.XXXXXX" longitude="139.XXXXX" accuracy="16"
place_id="◯◯◯◯◯" woeid="◯◯◯◯◯" ownername="◯◯◯◯◯"
geo_is_family="0" geo_is_friend="0" geo_is_contact="0" geo_is_public="1"
url_t="http://farm3.static.flickr.com/2655/◯◯◯◯◯_t.jpg"
height_t="100" width_t="100"/>
NSDictionary型のパラメータ「attributeDict」は、これらの属性を含んだ辞書(キーと値のペアを含んだハッシュテーブルのようなもの)となっています。上記のようなタグを読み込んだ場合、以下の戻り値は「@"つけめん並盛 味玉つき"」というNSStringになります。
[attributeDict objectForKey:@"title"]
次ページでは、パースした情報を基に、地図に表示する方法と、アノテーションをボタンに変える方法をコードを交えて解説します。
Copyright © ITmedia, Inc. All Rights Reserved.