相关文章推荐
逆袭的高山  ·  KeyChain.GetCertificat ...·  1 年前    · 
从容的米饭  ·  c# - Pcap.net vs ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I would like to get user approval before opening a link using WKWebView. (Objective C) I am using decidePolicyForNaviagationResponse.

When it encounters a link in the HTML it should ask using a UIAlertController if it is OK to follow the link or not (in the simplest implementation).

However it appears to be running asynchronously, so first it opens the link and then eventually gets around to popping up the alert.

How do I encounter the link, pop up the alert and THEN either open the link or not. I’m guessing either something about blocks that I don’t understand like a completion handler or perhaps using semaphores, although my modest attempts at them didn’t work.

I have simplified the code to make it clear what’s happening.

Thank you!

static bool launchPermission = false;
@property (strong, nonatomic) WKWebViewConfiguration *theConfiguration;
@property (strong, nonatomic) WKWebView *webView;
_webView.navigationDelegate = self;
[_webView  loadRequest:nsrequest];
[self.view addSubview:_webView];
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
        [self askPermissionForExternalLink];
        if (launchPermission)
            decisionHandler(WKNavigationResponsePolicyAllow);
            decisionHandler(WKNavigationResponsePolicyCancel);
- (void) askPermissionForExternalLink
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Open external Web Conten?" message:@"Link is embedded with other content" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancelAction = [UIAlertAction
                                   actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action")
                                   style:UIAlertActionStyleCancel
                                   handler:^(UIAlertAction *action)
                                       NSLog(@"Cancel action");
                                       [self cancelMethod];
                                       //return;
    UIAlertAction *okAction = [UIAlertAction
                               actionWithTitle:NSLocalizedString(@"OK", @"OK action")
                               style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction *action)
                                   NSLog(@"OK action");
                                   //[self launchURL];
                                   [self OKMethod];
    [alert addAction:cancelAction];
    [alert addAction:okAction];
    [alert show];
- (bool) cancelMethod
    launchPermission = false;
    return false;   
- (bool) OKMethod
    launchPermission = true;
    return true;    

You can try it in this way using blocks first in decidePolicyForNavigationResponse make decideAction inside the block

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
       void (^ launchPermission)(BOOL) = ^(BOOL isAllow)
            if(isAllow)
                decisionHandler(WKNavigationActionPolicyAllow);
                decisionHandler(WKNavigationActionPolicyCancel);
            return;
        [self askPermissionForExternalLink];

here based on user choice send YES or NO to launchPermission block

- (void) askPermissionForExternalLink
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Open external Web Conten?" message:@"Link is embedded with other content" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancelAction = [UIAlertAction
                                   actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action")
                                   style:UIAlertActionStyleCancel
                                   handler:^(UIAlertAction *action)
                                       NSLog(@"Cancel action");
                                       launchPermission(NO);
                                       return;
    UIAlertAction *okAction = [UIAlertAction
                               actionWithTitle:NSLocalizedString(@"OK", @"OK action")
                               style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction *action)
                                   NSLog(@"OK action");
                                   launchPermission(YES);
                                  return ;
    [alert addAction:cancelAction];
    [alert addAction:okAction];
    [alert show];
                Thank you this works!  I have a syntax question though, because there is one thing I don't understand.  How do you get the launchpermission() into the right scope to be used in - (void) askPermissionForExternalLink?  I had to embeded the code from askPermmisionForExternalLInk right into the webView code (sorry, I don't know how to post the whole code into this short comment field), see next comment for fragment.
– user938797
                Feb 16, 2019 at 21:47
                void (^launchPermission)(BOOL) = ^(BOOL isAllow) 	{ 		if(isAllow) 		{ 			decisionHandler(WKNavigationResponsePolicyAllow); 		} 		else 		{ 			decisionHandler(WKNavigationResponsePolicyCancel); 		} 		return; 	}; 	//[self askPermissionForExternalLink]; 	 	UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Open external Web Conten?" message:@"Link is embedded with other content" preferredStyle:UIAlertControllerStyleAlert]; 	 	UIAlertAction *cancelAction = [UIAlertAction 								   actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action")  ETC.
– user938797
                Feb 16, 2019 at 21:49
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.