Google Data API を iphoneで使う(Picasaの実装例)

Google Data APIを使って、まずiPhoneでのPicasaのViewerを作ってみようかとおもい調査。
準備は前回したので、実装例を作成。

Google Data APIの基本的なAPIの使用手順

Google Data APIでは、サービスオブジェクトを使用してGoogleのサーバーへ非同期でのリクエストを実行。通知用の定義したコールバックメソッドにより結果を取得するというのが、基本的な使用方法となる。

Google Data APIの基本的なAPIの使用手順 - リクエストの実行

    1. サービスオブジェクト(Picasaの場合は、GDataServiceGooglePhotos)を作成。
    2. GoogleのサーバーにリクエストするURLを作成する。サービスオブジェクトのURL生成メソッド(photoFeedURLForUserIDなど)を使用して作成。または、Queryオブジェクト(Picasaでは、GDataQueryGooglePhotos)を使用しての生成を行う。Picasaの場合は、基本的なパラメータとして、ユーザIDが必須。アルバム以下の情報がほしい場合はAlbumIDを、さらに下位であるPhoto以下の情報がほしい場合は、PhotoIDを指定する。また、下位の一覧(Entries)としてどのような情報がほしいかをkindで指定できる。kindはalbum,photo,comment,tagが指定できる(指定しないとDefaultの情報???)。
    3. (必要な場合は)サービスオブジェクトに対して認証情報を設定する。[setUserCredentialsWithUsername:password]メソッドによって行う。
    4. サービスオブジェクトのメソッドによって、GoogleへのサーバーへのHttpリクエストを実行する。結果は、didFinishSelectorで指定したコールバックメソッドへ通知される。

Google Data APIの基本的なAPIの使用手順 - リクエスト結果の通知

    1. サービスオブジェクトのリクエストのさいに指定したメソッド([fetchFeedWithURL:delegate:didFinishSelector:]のdidFinishedSelectorで指定したメソッド)、結果を受け付ける。このメソッドは[ticket:finishedWithFeed:error:]の形式となる。各パラメーターは以下のような内容となる。
      • ticket - GDataServiceTicketインスタンス。認証情報
      • finishedWithFeed - GDataFeedBaseの継承クラスのインスタンス。リクエスト時に指定したURLによって違いクラスのインスタンスとなる(Userだけを指定した場合は、GDataFeedPhotoUser, Albumまで指定した場合は、GDataFeedPhotoAlbum,写真までならGDataFeedPhoto ...)。これは、Googleサーバーから返ってきたXMLをマッピングしたもので、各要素の値が格納されている。また、下位の情報の配列(NSArray)がentriesメソッドで取得できたりする。これの要素はGDataEntryBaseの継承クラスとなっている(Userの結果のentriesであれば写真情報を格納したGDataEntryPhotoAlbum...など)。
      • error - NSErrorのインスタンス

その他

リクエストするさいには、基本的なパラメーター(Picasaの場合は、ユーザID, AlbumID,PhotoID)のほか、さまざまなパラメーターを指定できる。今回一部しか試していないが、一応付記。

    1. kind - どういう種類のデータを取得するか。Picasaの場合は、album,photo,comment,tagなど
    2. access - 取得対象のプライバシーレベル。 all, public, privateなどを指定
    3. max-results - 結果の最大件数
    4. その他 - picasaの場合thumbsize, imgmax, q(テキスト検索)などなど..

まず、ユーザの情報の取得を開始。

/*
 ユーザーの情報の取得を開始。
 結果はuserWithTicket:finishedWithUserFeed:error:コールバックで取得する。
 */
- (void) queryPhotoUser:(NSString *)user {
  GDataServiceGooglePhotos *service = [[GDataServiceGooglePhotos alloc] init];
  
  // アカウント設定
//  [service setUserCredentialsWithUsername:@"****" password:@"****"];
  
  NSURL *feedURL = [GDataServiceGooglePhotos photoFeedURLForUserID:user 
														   albumID:nil
														 albumName:nil
														   photoID:nil
															  kind:@"album"
															access:nil];
  NSLog(@"%@", feedURL);
  [service 	fetchFeedWithURL:feedURL
					delegate:self 
		   didFinishSelector:@selector(userWithTicket:finishedWithUserFeed:error:) ];
  [service release];

}

ユーザー情報のレスポンス情報を取得するコールバック。下位のentryとしてアルバムの情報も取得できている。

/*
 ユーザ情報取得コールバック
 GDataFeedPhotoUserのインスタンスとして情報が得られる。このインスタンスには、Albumエントリ一覧
 が含まれる。
 */
- (void)userWithTicket:(GDataServiceTicket *)ticket
finishedWithUserFeed:(GDataFeedPhotoUser *)feed
		 error:(NSError *)error {
  if (error == nil) {  
	NSArray *entries = [feed entries];
	if ([entries count] > 0) {
	  NSLog(@"the user has %d alblums", [[feed entries] count]);
	  
	  for (int i = 0; i < [entries count]; ++i) {
		GDataEntryPhotoAlbum *album = [entries objectAtIndex:i];
		NSLog(@"album - title = %@, ident=%@, feedlink=%@",
			  [[album title] contentStringValue], [album GPhotoID], [album feedLink]);
        [self queryPhotoAlbum:[album GPhotoID] user:[album username]];
	  }
	} else {
	  NSLog(@"the user has no albums");
	}
  } else {
	NSLog(@"fetch error: %@", error);
  }
}

次に、アルバムの情報取得のリクエスト

  GDataServiceGooglePhotos *service = [[GDataServiceGooglePhotos alloc] init];
  
  // アカウント設定
//  [service setUserCredentialsWithUsername:@"****" password:@"****"];
  
  NSURL *feedURL = [GDataServiceGooglePhotos photoFeedURLForUserID:userId
														   albumID:albumId
														 albumName:nil
														   photoID:nil
															  kind:@"photo"
															access:nil];
  GDataQueryGooglePhotos *query = [GDataQueryGooglePhotos queryWithFeedURL:feedURL];
  NSLog(@"url for album %@", [query URL]);
  [service 	fetchFeedWithURL:[query URL]
					delegate:self 
		   didFinishSelector:@selector(albumWithTicket:finishedWithAlbumFeed:error:) ];
  [service release];

アルバム情報のレスポンス情報を取得するコールバック、下位のentryとして写真の情報も取得できている。

- (void)albumWithTicket:(GDataServiceTicket *)ticket
finishedWithAlbumFeed:(GDataFeedPhotoAlbum *)feed
		 error:(NSError *)error {
  
  if (error == nil) {  
	NSArray *entries = [feed entries];
	if ([entries count] > 0) {
	  NSLog(@"the album has %d photos", [[feed entries] count]);
	  for (int i = 0; i < [entries count]; ++i) {
		GDataEntryPhoto *photo = [entries objectAtIndex:i];
		NSLog(@"photo - title = %@",
			  [[photo title] contentStringValue]);
		if([[[photo mediaGroup] mediaThumbnails] count] > 0) {
		  GDataMediaThumbnail *thumbnail = [[[photo mediaGroup] mediaThumbnails]  
										  objectAtIndex:0];
		  NSLog(@"URL for the thumb - %@", [thumbnail URLString] );
		}
		if([[[photo mediaGroup] mediaContents] count] > 0) {
		  GDataMediaContent *content = [[[photo mediaGroup] mediaContents]  
										objectAtIndex:0];
		  NSLog(@"URL for the photo - %@", [content URLString] ); 
		}
		if(i == 0) {
//		  [self queryPhoto:[photo GPhotoID] album:[feed GPhotoID] user:[feed username]];
		}
	  }
	} else {
	  NSLog(@"the album has no photos");
	}
  } else {
	NSLog(@"fetch error: %@", error);
  }
}