Tuesday, December 7, 2010

UIWebViewのページ遷移を監視

目的

UIWebViewで専用サイトをブラウズ、特定のファイルへのリンクを踏んだらそれをバックグラウンドでダウンロードしたい。

今回はその前段階として、UIWebViewのページ遷移を監視する方法を模索します。

調査

ググるといい感じの記事がありました。

検証

さっそく試してみます。

下準備

今回はView-based Applicationで作成。View ControllerにUIWebViewを置いています。

hogehogeViewController.h (抜粋)
@interface WebViewTestViewController : UIViewController {
  IBOutlet UIWebView *webView;
}

@property(nonatomic,retain) UIWebView *webView;
hogehogeViewController.m (抜粋)
@synthesize webView;

-(void)viewDidLoad {
  [super viewDidLoad];
  // Google.co.jpを表示
  [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.co.jp"]]];
}

これをビルドして実行してみると、アプリ起動後にgoogle.co.jpが開かれます。

今回の主役
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

このデリゲートメソッドが定義されていると、UIWebViewはページ遷移などでのリクエスト送信前にこのメソッドを呼び出し、その返り値が真(YES)ならリクエストを送信、偽(NO)なら中止するという挙動になっているそうです。

とりあえず書いてみよう
hogehogeViewController.m に追加
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
  if (navigationType == UIWebViewNavigationTypeLinkClicked || navigationType == UIWebViewNavigationTypeOther) {

    // about:~は通過させる
    NSString* scheme = [[request URL] scheme];
    if([scheme compare:@"about"] == NSOrderedSame) {
      return YES;
    }

    // ~google.co~を含まないURIへのアクセスは弾く
    NSRange range = [[[request URL] absoluteString] rangeOfString: @"google.co"
                                                          options: NSCaseInsensitiveSearch];
    if (range.location == NSNotFound){
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle: @"Not Permitted"
                                                      message: @"Google以外のサイトへはアクセスできません。"
                                                     delegate: self
                                            cancelButtonTitle: nil
                                            otherButtonTitles: @"Dismiss", nil];
      [alert show];
      [alert release];
      return NO;
    }
  }
  return YES;
}

これで動くかなー!

ビルドして実行!

…機能してない

普通にGoogle以外のサイトへ飛べてしまいました。

メソッドが呼ばれてないんでしょうか。…冷静に考えたらメソッドを定義するだけじゃだめですよね、ええ。

どうも考える限り「デリゲート」メソッドってのがミソなんじゃないかと思ってきました。が、

そもそもデリゲートって何をすればいいの

Σそんなレベルの疑問!? という話ですが。Objective-Cのデリゲートとかプロトコルってのをまだいまいち理解できてないという←

というわけでググってみて、どうやらwebViewのdelegateってのにオブジェクトを代入、そのオブジェクトにデリゲートメソッドを定義しておけばいいんじゃないか、という所に辿り着きました。今回はデリゲート先をself(この場合ViewController?)にしてやればいいんじゃね、ということでやってみます。

hogehogeViewController.h (抜粋)
@interface WebViewTestViewController : UIViewController <UIWebViewDelegate> {
  IBOutlet UIWebView *webView;
}
hogehogeViewController.m (抜粋)
-(void)viewDidLoad {
  [super viewDidLoad];
  // デリゲートする
  webView.delegate = self;
  // Google.co.jpを表示
  [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.co.jp"]]];
}

…これでいいんだろうか。ビルドして実行ー!

できた

おー!ちゃんと警告でた!止まった!

今後の課題

  • デリゲートとプロトコルをもう少し調べる
  • 当初の目標の、バックグラウンドダウンロードの方法を調べる。
  • というかダウンロードしたファイルを保存するためのファイルアクセスってどうやるんだろう。そのへんも要調査。

No comments:

Post a Comment