开发者

What is the best (safest) way to augment the URL used by UIWebView?

We are developing a hybrid application for iOS. Most of the application is a WebApp running within a UIWebView. It is sometimes necessary for the native portion of the application to modify the URL, adding some parameters. I'm aware there are "alternate" solutions we could use (e.g. native app talks to our server independently of the webview); however, I'm primarily interested in a good & safe solution to URL augmentation.

I've been looking for the "best" technique to do this, and found two that appear to (mostly) work.

Technique #1 - re-initialize the URL

- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"GOTO: %@", [[request URL] absoluteString]);
    NSURL * oldurl = request.URL;
    [[request URL] initWithString:[NSString stringWithFormat:@"%@&newParam=dave", [oldurl absoluteString]]];
    return YES;
}

Technique #开发者_运维技巧2 - reject the 1st URL, and sub-in a new one

- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL * oldurl = request.URL;
    if ([self isFixed:oldurl]) {
        return YES;
    } else {
        NSURL * newurl = [NSURL URLWithString:[NSString stringWithFormat:@"%@&newParam=dave", [oldurl absoluteString]]];
        [theWebView loadRequest:[NSURLRequest requestWithURL:newurl]];
        return NO;
    }
}

Technique #2 seems to cause artifacts on some pages ("iFrame load interrupted", maybe other issues).

I'm curious if anyone else has done url replacement like this, or via another technique, or if anyone is is aware of problems with technique #1 (which I'll hopefully use).

I know method swizzling is not recommended, and Apple's document recommends against subclassing UIWebView.

Thanks!

UPDATE Whoops - technique #1 doesn't actually work. My actual code was doing more than I posted, and it only appeared to work... This is probably good news, since it was a little more evil that I'd like.


Never call an -init method on an object that has already been initialized. This is not defined behavior. It is quite likely that you are leaking memory here since the old request ivars are probably not released correctly.

Something similar to the second approach is generally preferred.

Another approach is to use NSURLProtocol to inject yourself into the URL loading process. Doing it that way, you can create your own NSURLConnection using a modified NSURLRequest.


Here's another way to try out. I was playing with the stringByEvaluatingJavaScriptFromString:, and found out I could do this:

- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *oldUrlString = [NSString stringWithFormat:"%@", request.URL.absoluteURL];

    if ([oldUrlString isEqualToString:@"http://www.google.com/"])
    {
        [webView stringByEvaluatingJavaScriptFromString:@"window.location = \"http://www.arstechnica.com\""];

        return NO;
    }

    return YES;
}

I managed to redirect using a javascript injection, the first request to www.google.com is rejected, and redirected to www.arstechnica.com (I just picked a random site).

I think it's slightly better than hot-swapping the URL on the fly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜