send a notification from javascript in UIWebView to ObjectiveC

前端 未结 4 1711
太阳男子
太阳男子 2020-12-01 02:05

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,

相关标签:
4条回答
  • 2020-12-01 02:43

    Swift Version

    class ViewController: UIViewController,UIWebViewDelegate{
    
        @IBOutlet weak var webviewInstance: UIWebView!
        override func viewDidLoad() {
            webviewInstance.delegate = self
            super.viewDidLoad()
    
        }
    
    
        func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
            let requestString: String = (request.URL?.absoluteString)!
            var components: [AnyObject] = requestString.componentsSeparatedByString(":")
            // Check for your protocol
            if components.count > 1 && (String(components[0]) == "myapp") {
                // Look for specific actions
                if (String(components[1]) == "myaction") {
                    // Your parameters can be found at
                    //   [components objectAtIndex:n]
                }
                return false
            }
            return true
        }
    }
    
    0 讨论(0)
  • 2020-12-01 02:49

    zourtney's answer is correct , but forgot to mention one thing .. needed to register delegate to webview by

    - (void)viewDidLoad {
        [super viewDidLoad];  --- instantiate _webview next .. then 
    
        _webview.delegate = self;  //important .. needed to register webview to delegate
    }
    

    hope this helps .....

    0 讨论(0)
  • 2020-12-01 02:53

    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.

    0 讨论(0)
  • 2020-12-01 03:03

    Actually for timing in iOS (maybe not for OSX?), if a second window.location call is made before the previous window.location call executes, then the first window.location call gets lost. I think the window.location call executes asynchronisely with the JavaScript after it is called, and if another call is made it before it executes, it cancels the first.

    For example, when capturing touch events, I have seen ontouchstart not get sent via window.location, if an ontouchmove event occurs to quickly afterwards (such as in a fast finger swipe). Thus your Objective-C doesn't get the ontouchstart event. This is more of a problem on the original iPad than the iPad2, I assume because of processing speed.

    0 讨论(0)
提交回复
热议问题