Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
421 views
in Technique[技术] by (71.8m points)

objective c - send a notification from javascript in UIWebView to ObjectiveC

I need to know what should be done to use JavaScript in a HTML sitting in UIWebView to notify Objective-C that something has happened?

To be more exact, I'm playing some JavaScript animation in HTML and I need to alert the Objective-C code that the animation has ended.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There seems to be no official method of doing this. However, the standard workaround involves reading and parsing incoming URL requests, basically rolling your own serialized messaging protocol. The message handling should be done in the webView:shouldStartLoadWithRequest:navigationType method of your view controller.

Note: there are several free libraries (PhoneGap, QuickConnect, JS-to-Cocoa Bridge) which wrap this functionality (plus do a whole lot more). To reinvent the wheel (or know why it's round, so to speak), read on.

From JavaScript, you will invoke the callback by attempting to navigate to a new URL:

// In JavaScript
window.location = 'myapp:myaction:param1:param2'; // etc...

In Objective-C, implement the UIWebViewDelegate protocol in your .h file:

// In your header file
@interface MyAppViewController : UIViewController <UIWebViewDelegate> {
  ...
}
@end

Next, implement the method in your .m file:

// In your implementation file
-(BOOL)webView:(UIWebView *)webView2
       shouldStartLoadWithRequest:(NSURLRequest *)request
       navigationType:(UIWebViewNavigationType)navigationType
{
  // Break apart request URL
  NSString *requestString = [[request URL] absoluteString];
  NSArray *components = [requestString componentsSeparatedByString:@":"];

  // Check for your protocol
  if ([components count] > 1 &&
      [(NSString *)[components objectAtIndex:0] isEqualToString:@"myapp"])
  {
    // Look for specific actions
    if ([(NSString *)[components objectAtIndex:1] isEqualToString:@"myaction"])
    {
      // Your parameters can be found at
      //   [components objectAtIndex:n]
      // where 'n' is the ordinal position of the colon-delimited parameter
    }

    // Return 'NO' to prevent navigation
    return NO;
  }

  // Return 'YES', navigate to requested URL as normal
  return YES;
}

Two important notes:

  1. Context: navigating to myapp:whatever will (of course) fail under any other context. Keep this in mind if you're loading cross-platform pages.

  2. Timing: if a second window.location = call is made before the first returns, it will get 'lost.' So, either lump your calls together, manually delay execution, or implement a queue which combines the above with JS queries into Objective-C objects.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...