UIWebView + JavaScript

This topic is UIWebView and JavaScript.
We can use HTML page in UIWebView. This is useful to create application.
But, sometimes we need switch native application and this UIWebView action.
How to do it?

Idea

Objective-C calls Javascript

Use stringByEvaluatingJavaScriptFromString 

Javascript hook Objective-C

Use page transition.
When the page transition in javascript, shouldStartLoadWithRequest of UIWebViewDelegate is called.
Parse schema or path, and add Objective-C code in here.

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
}

Sample

This sample includes above 2 ideas.

js.html

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=yes" />
    <title>Title</title>
    <script type="text/javascript">
    var msg = "Hello World";
    function hello(){
        alert(msg);
    }
    function warp(){
        location.href = "index.html";
    }
    </script>
</head>
<body>
    <h1>JavaScript</h1>
    <p id="test">This is Test</p>
    <input type="button" value="click me!" onClick="warp()"/>
</body>
</html>

index.html

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=yes" />
<title>Title</title>
</head>
<body>
<h1>Smart Phone Web</h1>
<p>This is Test</p>
</body>
</html>

JavaScriptTesterViewController.h

@interface JavaScriptTesterViewController : UIViewController<UIWebViewDelegate>
@end

JavaScriptTesterViewController.m

@interface JavaScriptTesterViewController ()

@property (nonatomic) UIWebView *web;
@property (nonatomic) IBOutlet UIButton *button;

@end

@implementation JavaScriptTesterViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	
    // Web view
    CGRect rect = CGRectMake(self.view.bounds.origin.x,
               self.view.bounds.origin.y,
               self.view.bounds.size.width,
               self.view.bounds.size.height - 30);
    
    CGRect rectBtn = CGRectMake(self.view.bounds.origin.x,
                             self.view.bounds.size.height - 28,
                             200,
                             28);
    
    
    self.web = [[UIWebView alloc] initWithFrame:rect];
    self.web.scalesPageToFit = YES;  // Enable pinch out or not
    self.web.delegate = self;
    self.web.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;  // This is key
    [self.view addSubview:self.web];
    
    self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    self.button.frame = rectBtn;
    [self.button setTitle:@"Click Me!" forState:UIControlStateNormal];
    [self.button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.button];
    
    // Load web page
    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"js" ofType:@"html"]];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];
    [self.web loadRequest:req];
}
#pragma mark - Click
-(void)btnClick:(id)sender {
    [self.web stringByEvaluatingJavaScriptFromString:@"hello();"];
    //NSString *js = @"alert('ok');";
    //[self.web stringByEvaluatingJavaScriptFromString:js];
}

#pragma mark - UIWebViewDelegate
-(void)webViewDidStartLoad:(UIWebView*)webView {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;  // Indicator on
}

-(void)webViewDidFinishLoad:(UIWebView*)webView {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;   // Indicator off
}

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    NSURL *URL = [request URL];
    NSLog(@"URL %@", [URL path]);
    if ([[URL path] contains:@"index.html"]) {
        NSLog(@"Index");
    }
    return YES;
}
@end

Result

Click HTML “click me!”, just call javascript and do transition from js.html to index.html
, and finally call NSLog in Objective-C
Click bottom button “Click me”, call javascript from Objective-C

javascript