iPhone/memo_adv

Last-modified: 2010-12-20 (月) 14:00:16

UIViewのアニメーションに一時停止を埋め込む方法

UIViewのアニメーションは、一時停止などの機能がないようだ。
http://blog.livedoor.jp/tek_nishi/archives/3508878.html

※ImageViewのanimationImagesの一時停止ではないです。

iPhoneの動画について

http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1316953858

iPhone対応形式

音楽形式

ビデオファイル形式
H.264 (Baseline Profile Level 3.0)
MPEG-4 (Simple Profile)

エリカ本244には
MP3, AIFF, M4A MOV, MP4, MPV, M4V, 3GPなども含むらしいが、
やってみたところ、フルスクリーンでプレイヤーが表示されるが、
中身が表示されなかった。
再生秒数は取れているようだが。
ネットから落としたMP4の再生には成功した。
本当に、このサンプルの音楽ファイルを動画に変えるだけでOKだ。

注意点

仕様変更について

MPMoviePlayerは、iOS 3.2から仕様変更があり、
多くのメソッドやプロパティに "iOS 3.2 and later" と書かれている。

以前との違いで特に目立ったのは

動画はフルスクリーン以外で再生できるのは、iOS3.2から。
それ以前は、フルスクリーンでなければ再生できない。


http://kitajima-antenna.seesaa.net/article/164018501.htmlにて
iOS3.1以下は全画面でしか表示できないという情報を発見

動かなかった・・・

http://www.saturn.dti.ne.jp/~npaka/iphone/MovieEx/index.html
にコードがあるが、iOS3.2以降でないとだめ
現在の実機(iPhone3GS,iOS3.1.3)でテストすると、アプリが落ちてしまった

参考

http://sarudeki.maiway.jp/forum/topic/181
動画再生に関して。

大きな画像の一部分を表示する方法

 1.マスク画像で切り取る方法
 http://d.hatena.ne.jp/KishikawaKatsumi/20090419/1240147321
 http://q.hatena.ne.jp/1265111808
 
 2.CGImageCreateWithImageInRectを使う
 http://amaterasu4.seesaa.net/article/116142296.html

 ただし、ゲームなどで毎フレーム使うと結構重いとのこと。
 あらかじめ、切り取って用意しておくとよい

さらに、画像を指でスライドして表示させる方法

 スライドを検出する方法は、touchesMovedメソッドで取得することが可能。
 座標の検出は、locationInViewを使うことで可能。
 
 座標ではなく、スライドした量を検出するには、
 タッチ開始時の座標を保存しておいて、後で引き算して…とすることも可能だが、
 previousLocationInViewというメソッドを発見した。
 
 これを使えば、スライドのメソッドで処理が閉じて見やすくなる。 
 
 なお、斜めにスライドした際、縦方向のスライドがはみ出しても、
 横方向のスライド成分は有効になるように配慮するとよい。
 
 ちなみに、画像の範囲外を切り取って表示しようとすると、
 画像そのものが表示されない状態になる(NULLを返してくるため)
 はみ出さないように、スライド範囲を管理すること。

Twitterへの投稿

ユーザー名

「ツイッター」を使う人を特定する身分証明(=ID)に使います。
アカウントと呼ぶこともあります。
最大15文字の半角英数字か、_(アンダーバー)を組み合わせて作ってください。
ここでは、全角の英数字、ひらがな、カタカナ、漢字は使えませんのでご注意を。

取得できるユーザー画像のサイズ

48x48

実は、直接webからxmlを引っ張り出すことができる

TwitterのタイムラインはHTTPから取得することが可能
http://api.twitter.com/1/statuses/user_timeline/(ユーザーID).xml

タイムラインの取得は200件まで。

 200以上を指定しても200件までしか取得できない。

 ちなみに、Twitterを見たときに最初に見られる表示件数が20件のため、
 200件ならば、十分すぎる量(10ページ分)といえる。

xAuthとOAuth

どちらも、http://twitter.com/apps
から登録必要。これは、各人に用意されている領域で、自由に登録できる。
 
OAuthでAPIを使用するためには各ユーザーにそのOAuthアプリを認証してもらって
access_token, access_token_secretを取得する必要があるのだけど、
最初の方に書いたとおり、普通の方法だとその認証にはブラウザを経由する必要があり面倒。
 
OAuthは、登録直後に得られるkeyを使えば実装完了。
xAuthは、メールでの申請が必要。
 
デスクトップアプリなら、便利なxAuth
インターネット上のアプリなら、パスワードをやり取りしないOAuthが適切。
http://written.4403.biz/archives/2010/03/twitter-xauth.html
のように、インターネットアプリでも、xAuthを使っている例もあるが、
メール申請を拒否られる可能性は高くなる。
 

xAuthアプリ申請テンプレ

 http://tinypaste.com/3d7b1
 http://d.hatena.ne.jp/nakaji999/20100623/1277306203 

使えるライブラリ

xAuthTwitterEngineを使った。
内部で、MGTwitterEngineを使っているらしい。
 
現在は、MGTwitterEngine自体もxAuthに対応しているらしく、
xAuthTwitterEngineに微バグが存在することから、
こちらを使った方がいいのではないかという意見も聞かれる。
やり方は知らない。
 

導入方法

http://tanaka-project.biz/?p=78

注意事項

・なぜか、タイムラインが20件までしか取得できないバグに遭遇

 ⇒20件というのは、取得数(count)を指定せずにタイムラインを取得した場合に
  取得される件数なので、ライブラリ側でcountが無効になっていると予測

 ⇒http://tanaka-project.biz/?tag=iphone に解決法があった
 >MGTwitterEngineの問題点。デフォルトでは、
 >TwitterAPIのカウントパラメータ(?count=100など)が使えない
 >コメントになっているコードが間違っています。

 注意点としては、MGTwitterEngineの問題点とあるが、
 実際には、MGTwitterEngine.mと同じ関数が
 xAuthTwitterEngine.mで上書きされており、
 こちらを修正しなければ、修正が反映されない

タイムライン取得

http://www.srcw.net/wiki/index.php?MGTwitterEngine
http://newbiztask.blog69.fc2.com/blog-category-13.html
http://www39.atwiki.jp/dev_iphone/pages/15.html
下のURLは色々と中身に詳しい。
Twitterからのデータは1発で取得できないってのは、常識らしい。

 
どこかほかの場所で、

[self.twitterEngine getFollowersIncludingCurrentStatus:YES];

を実行し、

- (void)userInfoReceived:(NSArray *)userInfo forRequest:(NSString *)connectionIdentifier{
	NSLog(@"userInfoReceivedに反応");
    for (NSDictionary *status in userInfo) {
        NSLog(@"Tweet Text: %@", [status objectForKey:@"screen_name"]);
    }

}

のようにして、結果を受け取る。
ちなみに、[status objectForKey:@"text"]とすると、各フレンドの最新のつぶやきを取得することができる。

どのメソッドを使えばいいのか?

xAuthTwitterEngineは、どのメソッドでどの情報を取り出せるかというのがわかりにくいが、
たとえば、「statuses/followers.」
など、TwitterのAPIでプロジェクト内を探せば、
大体、どれを使えばいいかわかるだろう。
 
TwitterのAPIはここを見られたし。
http://watcher.moe-nifty.com/memo/docs/twitterAPI.txt

処理判定の結果判定

Q.
statusesReceivedが delegate するクラスに一個しか書けない以上,
どうやってタイムラインとリプライの取得を判定したら良いのか?
 
非同期でリクエストに対するレスポンスが返ってきて、しかも、
同じメソッドが呼ばれてしまうのだが・・・?
 
A.
source_api_request_typeが異なっているので、それで判別できる。
case 1: //タイムライン取得時
case 5: //ツイート投稿時
case 7: //mention取得時
あとは、未調査。

同期呼び出ししたいとき

xAuthTwitterEngineのメソッドは非同期処理であるが、
これを同期にしたいときは以下のようなコードがある。
http://www39.atwiki.jp/dev_iphone/pages/16.html

参考サイト

http://d.hatena.ne.jp/yoneapp/20100619/1276955481
 
http://matteocaldari.it/2009/10/mgtwitterengine-status-id
http://tanaka-project.biz/?p=78
にあるように、long longを扱えるようにしないと、status IDで変なことが起きるらしい。
MGTwitterEngineの問題点についても、下のURLに乗っかっているので、チェックせよ。
 
http://www39.atwiki.jp/dev_iphone/pages/15.html
にとれる情報の一覧がある。

XMLパーサ

iPhoneの開発環境には、libxml2というXMLパーサー用の
ライブラリが付属しているようだ。
http://journal.mycom.co.jp/column/iphone/007/index.html
 
他にもNSXMLParserというパーサーがある。
調べたところ、libxml2の方がかなり軽いらしいが、
正直、
http://d.hatena.ne.jp/thata/20100626/1277610541
がわかりやすく、NSXMLParserの方が使いやすい印象を受けている。
 
libxml2⊂NSXMLParserという包含関係があった気がする。

試しに、TwitterのタイムラインのXMLをパースし、
正しく動作することを確認した(※)。


TwitterのタイムラインはHTTPから取得することが可能
http://api.twitter.com/1/statuses/user_timeline/(ユーザーID).xml
というアドレスを打ち込むことで、タイムラインのつぶやきを
XML形式で取得できる

Twitpicへの投稿

POSTで指定のアドレス(http://twitpic.com/api/uploadAndPost)へデータを送ればOK
以下のサンプルでは、ポストのためにASIHTTPRequestライブラリを使っているので、インストール必要。
レスポンスには、アップロードした画像のアドレスが返ってくる。

-(void)twitPicUploadSample{
	NSURL *url = [NSURL URLWithString:@"http://twitpic.com/api/uploadAndPost"];
	ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];

	[request setPostValue:@"(ユーザー名)" forKey:@"username"];
	[request setPostValue:@"(パスワード)" forKey:@"password"];

	NSString* filepath = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"jpg"];
	NSLog(@"filepath=%@", filepath);

	[request setFile:filepath forKey:@"media"];
	[request setPostValue:@"Hello twitpic!" forKey:@"message"];
	[request startSynchronous];

	NSError* error = [request error];
	if (!error) {
		NSString* response = [request responseString];
		NSLog(@"%@", response);
	} else {
		NSLog(@"error: %@", error);
	}

}

上記は、つぶやきと画像が同時に投稿されてしまうようになっていて、
messageを空にしても、画像のアドレスが投稿されてしまうので、Twitterへの投稿を無効にはできない。
画像だけ送るアドレスもあるのかもしれないが、調査中
http://d.hatena.ne.jp/tomute/20100109/1263097546
http://iphone.longearth.net/2010/08/05/twitpic%e3%81%aeoauthecho%e5%af%be%e5%bf%9c/
などが参考になるかも?
 
ただ、前のアドレスのやつだと、
 ASIHTTPRequestという謎クラスの説明が乗ってない。

 http://xcatsan.blogspot.com/2010/03/keychain-services-21-twitpic.html
 
 http://xcatsan.blogspot.com/2010/03/keychain-services-22-twitpic-asi-http.html
 http://xcatsan.blogspot.com/2010/03/keychain-services-23-twitpic.html

 を参考にして実装する。
 
ASIHTTPRequest自体は、HTTP通信をするライブラリで、POSTでのパラメータ送信などを
使いやすくしたライブラリである。

text入力について

textFieldは1行しか入力できない、複数行ならUITextViewを使え。

以下によると、shouldChangeTextInRangeは、UItextViewにも用意されているようだ。
(APIレファレンスに乗ってないのに・・・・)
http://ja.efreedom.com/Question/1-2012190/とのようにUITextView-のテキストの長さを修正てきますか
※このURLはミスタイプではなくて、英語の直訳と思われる

//パスワード入力 ●●●●表示
_textField.secureTextEntry = YES;
//英字限定キーボード
_textField.keyboardType = UIKeyboardTypeASCIICapable;
//大文字入力回避
_textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
//自動補完回避
_textField.autocorrectionType = UITextAutocorrectionTypeNo;

//キーボードのENTERをDoneに変える
_textview[TEXTVIEW_TWEET].returnKeyType = UIReturnKeyDone;
//スクロール禁止
_textview[TEXTVIEW_TWEET].scrollEnabled = NO;
//テキスト変更時に_TextViewから呼ばれる
//メイン側に<UITextViewDelegate>とsetDelegateを忘れずに。
//このメソッドのイメージは、「このテキストが入力されますがいいですか?」で、NOを返せばテキストは入力されない。
//ここで文字制限をしてしまうと、日本語ではうまくいかないようだ。
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{

	//改行ならば、入力終了とみなす(実はこれ、超貴重なノウハウ)。
	//textviewには、textfieldのような- (BOOL)textFieldShouldReturn:(UITextField*)sender {
	//に相当する口がないから。
	if ([text isEqualToString:@"\n"]) {
		[textView resignFirstResponder];
        return NO;
    }
	return YES;
}
//テキストが変化したときに_TextViewから呼ばれる
- (void)textViewDidChange:(UITextView *)textView{

	//_label[LABEL_TWEET_MODE].text = [NSString stringWithFormat:@"いまどうしてる?(残り%d文字)", 139-textView.text.length];
	if( 140-textView.text.length > 140 ){
		textView.text =  [textView.text substringWithRange:NSMakeRange(0, 140)];
	}
	_label[LABEL_TWEET_MODE].text = [NSString stringWithFormat:@"%d", 140-textView.text.length];
	//NSLog(@"かわったよ%@",textView.text);
}
//編集終了時に_TextViewから呼ばれる。
//メイン側に<UITextFieldDelegate>とsetDelegateを忘れずに。
- (BOOL)textViewShouldEndEditing:(UITextView *)textView
//- (BOOL)textViewShouldReturn:(UITextView*)textView
{
	[textView resignFirstResponder];
    return YES;
}

 
参考:
http://alug.blog.shinobi.jp/Category/8/
http://www.hirano-dept.com/blog/2010/04/iphone-uitextview.html
http://r-force.seesaa.net/article/169734986.html

SAFARIをアプリから起動する方法

ウェブビューを使った開発サンプルを扱ったが、SAFARIを起動するだけならば、

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"サイトURL"]];

でOK

iPodをアプリから起動する方法

以下のコードをviewcontrollerにおけばOK
外部クラスにしようとしたが、うまくいかなかったorz

//iPod関連処理。changeMusicを呼び出せば、iPodが呼び出せる
- (void)changeMusic:(UIButton*)sender
{
	MPMediaPickerController* mpc = [[[MPMediaPickerController alloc]
									 initWithMediaTypes: MPMediaTypeMusic] autorelease];
	if (!mpc) return;
	mpc.delegate = self, mpc.allowsPickingMultipleItems = NO;
	[self presentModalViewController: mpc animated: YES];
}

- (IBAction)playMusic:(UIButton*)sender
{
	MPMusicPlayerController* ipod = [MPMusicPlayerController iPodMusicPlayer];
	if (!ipod) return;
	if (!ipod.nowPlayingItem) {
		[self changeMusic: sender];
		return;
	}
	bool play = ipod.playbackState != MPMusicPlaybackStatePlaying;
	if (play) [ipod play];
	else [ipod pause];
}

- (void)mediaPicker:(MPMediaPickerController*)mediaPicker
  didPickMediaItems:(MPMediaItemCollection*)mediaItemCollection
{
	[self dismissModalViewControllerAnimated: YES];
	MPMusicPlayerController* ipod = [MPMusicPlayerController iPodMusicPlayer];
	[ipod setQueueWithItemCollection: mediaItemCollection];
	[ipod play];
}

- (void)mediaPickerDidCancel:(MPMediaPickerController*)mediaPicker
{
	[self dismissModalViewControllerAnimated: YES];
}
//ここまでiPod関連

iPodライブラリアクセスプログラミングガイドも見とけ。
http://developer.apple.com/jp/devcenter/ios/library/japanese.html

プレイリストの取得

http://d.hatena.ne.jp/tasanobu/20100408
エリカ本にも載ってるけど、面倒だし、
凝ったプレイヤにしたいとかじゃなきゃ、iPodに任せてしまった方がいいと思う。

MPMediaQuery* playlists = [MPMediaQuery playlistsQuery];
playlists.groupingType = MPMediaGroupingPlaylist;

for( MPMediaPlaylist *plist in [playlists collections] )
{
	// Playlist名の表示
	NSLog(@"%@", [plist valueForProperty: MPMediaPlaylistPropertyName]);
}

アプリからのカメラの使い方

UIImagePickerControllerを使えば、カメラ系は簡単に使える。

//カメラ
	sourceType = UIImagePickerControllerSourceTypeCamera;
	// 使用可能かどうかチェックする (ipod touchはじき)
	if (![UIImagePickerController isSourceTypeAvailable:sourceType]) {
		return;
	}

	// イメージピッカーを作る
	imagePicker = [[UIImagePickerController alloc] init];
	[imagePicker autorelease];
	imagePicker.sourceType = sourceType;
	//imagePicker.allowsImageEditing = YES;
	imagePicker.delegate = self;

	// イメージピッカーを表示する
	[self presentModalViewController:imagePicker animated:YES];
//アルバム
//UIImagePickerControllerSourceTypeSavedPhotosAlbumなら、Camera Rollが
//UIImagePickerControllerSourceTypePhotoLibraryなら、Photo Albumsが表示される
	//sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
	sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
	// 使用可能かどうかチェックする (ipod touchはじき)
	if (![UIImagePickerController isSourceTypeAvailable:sourceType]) {
		return;
	}

	// イメージピッカーを作る
	imagePicker = [[UIImagePickerController alloc] init];
	[imagePicker autorelease];
	imagePicker.sourceType = sourceType;
	//imagePicker.allowsImageEditing = YES;
	imagePicker.delegate = self;

	// イメージピッカーを表示する
	[self presentModalViewController:imagePicker animated:YES];
}
//UIImagePickerController(カメラ関連)のdelegate 
// カメラ画像撮影後の処理
// ただし、camera rollで画像を選択したときにも呼ばれるようだ。
- (void)imagePickerController:(UIImagePickerController*)picker
        didFinishPickingImage:(UIImage*)image
				  editingInfo:(NSDictionary*)editingInfo
{
	takenImage = [image retain];

	switch (sourceType) {
		case UIImagePickerControllerSourceTypePhotoLibrary:
			//ここではなにもしていないが、takenImageが変更されていることに注目
			break;
		case UIImagePickerControllerSourceTypeCamera:
			// 撮影画像を保存
			UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);
			break;
		default:
			break;
	}

    // イメージピッカーを隠す
    [self dismissModalViewControllerAnimated:YES];
}
//cancelが押されたとき
- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker
{
    // イメージピッカーを隠す
    [self dismissModalViewControllerAnimated:YES];
}

参考資料:
https://sites.google.com/a/gclue.jp/iphone-app-docs/iphoneapurinyuumon--camera

iPhoneアプリのリネームの方法

(今回の例ではAAA→BBBとしてiPhone上に表示させる)

 http://5039.jp/blog/2009/10/iphone-xcode.html
 http://d.hatena.ne.jp/zariganitosh/20080523/1211531912
 の手順を踏むことにより解決(ローカルでの正常動作を確認)

 設定漏れがあると、以下のような弊害が起こった。

 ①プロジェクト名を変えたのに、インストールしたら、変更前のままになっている
   →Finderなどで「BBB」にリネームしても、インストールすれば「AAA」になってしまう
 ②プロダクト名を変えたのに、同一アプリとみなされる
   →今回であれば、有料版と無料版の共存が不可能になる。
   →どうも、アプリが同一か否かは、バンドル識別子の文字列を見ているようだ。

 具体的な変更点は後述の 変更点の概要 以下に記述

 もしアプリが起動しないならば、Bundle identification(識別子)の値に
 他アプリと重複するような文字列を入れているというのが原因の1つとして疑われる。

 http://d.hatena.ne.jp/shunsuk/20090522/1242997423
 などが参考になるかも?

変更点の概要

Finderでの作業

 ①プロジェクトファイル名の変更
  AAA.xcodeproj → BBB.xcodeproj
 ②buildフォルダを削除

Xcodeでの作業

 プロジェクトウィンドウの「グループとファイル」リストから
 「ターゲット >> AAA」を選択し、青い情報ボタンを押す。

 ①「一般」タブ
  ・「名前:」AAA → BBB
 ②「ビルド」タブ
  ・「パッケージング >> プロダクト名」AAA → BBB
  ・「GCC 4.0 - 言語 >> プレフィックスヘッダ」 AAA__prefix.pch → BBB__prefix.pch
 ③「プロパティ」タブ
  ・「識別子:」 プロビジョニングのApp IDの文字列 → BBB
  ・プロジェクトウィンドウの「グループとファイル」リストから
   「Other Sources >> AAA__prefix.pch」を右クリックして名称変更(BBB__prefix.pchに変更)
 ④「ビルド >> すべてのターゲットをクリーニング」を実行

 ※
 ③の識別子の変更において、「!」を含めるとビルドエラーになるので注意

 ※
 この識別子が異なれば、名前が同じであろうと、違うアプリとして認識され、
 同名のアプリを複数インストールすることも可能になる。(誤って重複しないような値にする必要がある)

 ※
 AAA-info.plistのBundle identifierと内容が同期している。ただし、セーブしないと同期されない。

 ※
 現時点でBundle identifierは、
 iPhone Dev Centerに存在するAppIDのDescriptionの欄にある文字列と等しくなっている。
 

iPhoneでGoogleMapを使う方法

直接アドレス指定で読んでしまう方法

http://maps.google.co.jp/?ie=UTF8&z=16&om=1&ll=35.675,139.759765
google mapの緯度と経度を指定したやり方の例
z=の値が増えるほど、拡大マップになるようだ。
(om=1の意味がわからないが)

iPhoneでも正しく、表示されることを確認した。

似てるものに、Google Latitudeがあるが、これは本人の確認+APIキーがいるらしい。
http://www.google.com/latitude/apps/badge/api?user=-1417031090526478935&type=iframe&maptype=roadmap&z=9&hl=ja

画像として取得する方法

Google Static Maps APIというものを使う方法。
とても簡単な方法。
<img src="http://~~~~">
のようにして、アドレスを指定して、地図を取得する方法。
余談だが、http://~~~~の部分をブラウザに直打ちしてもアクセスできない。
 
WEBViewなどでロードしてあげれば、簡単に地図が表示できるだろう。
意外と経路を表示するなど高度な機能も備わっている。
また、特にAPIキーなども必要ない。
 
使い方は、以下のアドレスが詳しい。
http://www.ajaxtower.jp/googlestaticmaps/

 
難点は
1)当然、画像の地図なので、ユーザーの操作には反応しない
2)上と左に8ピクセル程度の白い背景が入ってしまう
3)一日、ユニークな画像は1000件までしか取れない(2010年10月)
 
たぶん、地図自体に課金とかしなければ、商用にも使っていいはず。
(Googleとかで間違って本サイトを踏んでしまった諸兄は、各自、チェックされたし)
 
ズームレベルによる、見え方の違いは↓こんな感じ
http://www.ajaxtower.jp/googlestaticmaps/para/index4.html

 

JavaScriptを使う方法

Google maps API V2

APIキーが必要。
機能的には、V3より充実しているが、すでに正式に廃止の方向へ向かっている。
http://ascii.jp/elem/000/000/424/424032/

 
資料として詳しいのはココ
http://www.ajaxtower.jp/googlemaps/

Google maps API V3

添付にtxt形式で例をアップロードしておいた。
txt形式だが、クリックすれば、HTMLが表示されるので、見てみるべし。
 
v3はAPI keyなしで使える。
http://ascii.jp/elem/000/000/424/424032/index-2.html
 
Google maps APIはV3からAPIキーがいらない!
しかも、iPhoneなどでの使用で最適化されているらしい。
 
ピンチ操作で拡大縮小もできるが、
ダブルタップでズームイン、両指でズームアウト、などのiPhone付属のマップ操作はできない。
 
難点は、
1)重い
2)戻り値を受け取るために、少しJavaScriptの使い方を工夫しないとだめ。
3)ソースはテキスト形式か何かで持っておかないとだめ
4)引数を渡すのも結構大変(3)の一部を置換してみたりしたが
5)以降が終了してないのか、V2で使えた機能の一部がまだ使えない?
  例)バルーンに文字を表示する機能がない(普通、バルーンにAとか書けるはずだが、その口が見当たらない)
    バルーン自体はあるだけどね?
6)一日のジオコーディングは2500件まで
7)フルサイズで使うならばいいのだが、ウェブビューが小さい場合、利用規約へのリンクの文字がでかくて、
  iPhoneのフルサイズでないウェブビューで使うには致命的に邪魔!

 
また、拡大していくと、ストリートビューにつなぐことができるが、
iPhoneの回線では、重すぎて使い物にならない。
 
公式ページの説明
http://code.google.com/intl/ja/apis/maps/documentation/staticmaps/

ズーム レベルに関する公式の説明
Google マップの各地図には、現在のビューの解像度を定義する整数の「ズーム レベル」があります。
デフォルトの道路地図表示では、0(最小のズーム レベル、全世界が 1 つの地図に表示される)と、
21+(個々の建物が識別できる)の間のズーム レベルが指定可能です。
 
地球全体を表示するには、Google マップのズーム レベルを 0 に設定します。
ズーム レベルを 1 つ上げると、縦と横の精度が 2 倍になります。
これを行っている方法については、Google Maps API ドキュメントを参照してください。
 
注: 地球上のすべての場所を、すべてのズーム レベルで表示できるわけではありません。
  場所によって画像データの粒度が異なるため、使用できるズーム レベルも異なります。
 
マップ タイルが存在しないズーム レベルのリクエストを送信した場合、Static Maps API は代わりに空白の画像を返します。

MKMapviewクラスを使う

事実上、これが、一番無難だと思う。
基本的な使い方は、生成するだけ。
 
IBは知らないけど、ソースからなら、
alloc -> initWithFrameとするだけ。

 
これだけで、
1)地図のスライド
2)拡大縮小
  2-1)ピンチ操作
  2-2)両指ズームアウト、ダブルタップズーム
がついてくるスグレモノ
 
中心座標のセットやズームのやり方は
http://d.hatena.ne.jp/uosoft/20090703/1246548056
http://ameblo.jp/k-power2/entry-10505935168.html
などを参考に

 
注意点として、ズームと緯度経度の指定は、
1)ズーム
2)緯度経度の指定
の順番で行うということ。
 
サンプルで、逆の順番になってるのもあるけど、
試しに東京都庁を、緯度経度の指定⇒ズームの順番で指定したら、
表示されたのは、海だった。
どうも、グローバル視点だと、マップの緯度経度が荒いみたい。
 
関数一覧はここ
http://webbuilders.wordpress.com/2009/04/10/open-source-objective-c-library-that-mimic-google-map-apis/

機能について

1)マップにピンを立てる機能 ⇒ ある
  ※マップのピンをアノテーションと呼んでおり、正確には、MKMapviewの機能ではなく、
   アノテーション(MKAnnotationView)の機能である。
 
2)マップのピンをタップすると吹き出しが表示される機能 ⇒ ある
  ※- (NSString*)titleで、returnに指定した文字列が表示されるという謎仕様。
   空テキストをreturnすると、タップ時のポップアップを殺すことができる。
   殺すだけなら、 setCanShowCallout:NO でも殺せる。
 
3)吹き出しに複数行表示させる機能 ⇒ ない(たぶん)。1行だけしかはいらない…numberOfLinesみたいのはないのかー
  ※JavaScriptを使ったときに表示できる吹き出しには、自由にHTMLコードを書くことができた 
  ただし、吹き出しの右端か、左端にボタンなどのコントロールを追加することができるので、
  そのボタンをタップしたら、LABELを表示するなどして対応せよ。
  ちなみに、このコントロールをアクセサリといって、タップすると、
  calloutAccessoryControlTappedが呼ばれるようになっている。
 
4)マップのピンを任意の画像に変える機能 ⇒ ある
  マップにアノテーションが追加されたときに、(追加された回数分)viewForAnnotationが呼ばれる
  そこで、annotationView.image = img;をかませばいい。
  imgは、[UIImage imageNamed:@"Images/hogehoge.png"]みたいな感じのヤツ
 
5)ピンをバルーンに変える機能 ⇒ これはちょっと見つからなかった。ないのかも?

注意事項

(1)
ピンのアノテーションを画像をアノテーションにする方法もあるが、
http://blog.s21g.com/articles/1604

1.あたり判定がなんかでかい??
2.アイコンをクリックするとピンの画像に戻ってしまう。
  #ピンをドラッグしたときに赤く光るのだけれど、それのせいで、アイコンがぴんに戻ってしまう。

 
MKPinAnnotationViewにはすでにピン画像が設定されている為、あとから画像を変更すると変になります。
設定は出来るんですけど、タッチして吹き出しを出すと、ピンに戻ったりします。
なのでやるんだったら、MKAnnotationViewを使うか、それを継承したユーザクラスを使う方がいいです。
 
(2)
タップに反応するメソッド(didSelectedAnnotationView)は
iOS4.0からでiOS3.0では機能しない。
シミュレータでは動作するが、実機では動作しないのだ!
タップに反応するメソッドに代わるものを用意する。

参考資料  

図形を書く:http://d.hatena.ne.jp/glass-_-onion/20100623/1277246927
タップ位置の取得:http://kinsentansa.blogspot.com/2010/02/mkmapview.html
アノテーション関連:http://blog.ps-ax.info/2009/08/page/2/
ピンの色変更:http://appteam.blog114.fc2.com/blog-entry-107.html
http://blog.ps-ax.info/2009/08/iphone-mapkit%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/