Obj-C decidePolicyForNavigationAction not being triggered - ios

decidePolicyForNavigationAction is not being triggered when the webview loads a new page. It works when everything is initially loaded but then never gets triggered after that.
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSLog(#"decidePolicyForNavigationActionnavigationAction.request.URL.absoluteString:%#|", navigationAction.request.URL.absoluteString);
if (kTestLocalHTML == 1) {
decisionHandler(WKNavigationActionPolicyAllow);
return;
}
NSURL *url = navigationAction.request.URL;
if (url != nil) {
//
// TODO: Trim the url string below as well?
// No, because this is being trimmed already in the AppManager methods related to web view URL
//
NSString *urlString = url.absoluteString;
WKNavigationType navType = navigationAction.navigationType;
//
// Display the club mobile native login page and log the user out
// if the webview is about to load the blazor login page URL
//
if ([urlString isEqualToString:[AppManager getMobileLoginUrl]]) {
self.appManager.userLoginDetails = nil;
[self displayLoginPage];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
//
// Check if link is tapped from webview and if URL string contains the
// prepended identifier within the JavaScript injection which can be found in
// "webViewDidFinishLoad" delegate method of webview
//
if (navType == WKNavigationTypeLinkActivated && [AppManager isWebViewURL_containsTargetBlank:urlString]) {
//
// Make sure to ignore the prepended identifier on the URL string
// before opening it on an external browser
//
NSInteger targetBlankIdentifierLength = kIdentifier_TargetBlank.length;
NSURL *url = [NSURL URLWithString:[urlString substringFromIndex:targetBlankIdentifierLength]];
[[UIApplication sharedApplication] openURL:url];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
//
// Check if url has custom scheme other than "http" & "https" (If is either one of the tags for Telephone "tel", Mail "mailto", SMS "sms", Web Calendar "webcal", etc.)
//
// Solution Reference: https://stackoverflow.com/questions/47040471/wkwebview-not-opening-custom-url-scheme-js-opens-custom-scheme-link-in-new-wind
// - (Answers of both "hstdt" & "mattblessed")
//
// NOTE: It seems loading telephone and mail links do not work when testing on an iOS simulator.
//
NSString *urlScheme = url.scheme;
BOOL isCustomURLscheme = ( ! [urlScheme isEqualToString:#"http"] && ! [urlScheme isEqualToString:#"https"]);
if (isCustomURLscheme) {
NSURL *url = [NSURL URLWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
//
// Get reference to the current URL being requested so that if there
// will be failure in loading the webview, we have a reference to that URL.
//
self.currentUrlRequest = navigationAction.request;
// Check if web view URL contains a calendar file to download
if ([AppManager isWebViewURL_containsCalendarDownload:urlString]) {
//
// Download and process calendar file either from Events or Dining module
// and display "New Event" page where user can view its details, edit and save to device calendar
//
[self processCalendarFileAndDisplayEventPageWithURLrequest:self.currentUrlRequest];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
// Check if web view URL contains a PDF file attachment to download
else if ([AppManager isWebViewURL_containsPDFAttachmentDownload:urlString]) {
// Display document viewer page and pass few parameters for page customization (initial URL to load, navigation bar title)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:kStoryboardName bundle:nil];
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:kStoryboardID_OverlayBrowserNavigationController];
OverlayBrowserViewController *vcOverlay = (OverlayBrowserViewController *)[navigationController topViewController];
vcOverlay.initialURLtoLoad = urlString;
vcOverlay.navigationBarTitle = [self getPDFDocumentNameFromURLString:urlString];
[self presentViewController:navigationController animated:YES completion:nil];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
decisionHandler(WKNavigationActionPolicyAllow);
}
This function is supposed to trigger and detect if the webview is loading the web login page and if that is the case it will logout the user and instead show the apps native login page. However the function is never triggered after the main screen is loaded initially.

"Are you sure the web page is actually performing a redirect and is not a SPA like Angular which may not be updating the URL? Also how are you setting self.wkWebMain? – RunLoop"
Thanks for this, you were correct and the webpage was acting as an SPA which was the reason the function would call at first on the initial load but not after.

Related

Tweetbot URL Scheme not opening user

I've been trying to get Tweetbot to open a user account when a table row is tapped by the user. However, although Tweetbot opens, it doesn't show the user account. I've been using the Tweetbot URL Scheme page as a reference.
Below is my code:
if (indexPath.row == 1) {
// Removed the actual username
self.destViewURL = #"http://twitter.com/dummyusername";
self.destViewTitle = #"Twitter";
// URLs to try
NSURL *twitterURL = [NSURL URLWithString:#"twitter://user?screen_name= dummyusername"];
NSURL *tweetbotURL = [NSURL URLWithString:#"tweetbot://dummyusername/timeline"];
// Check if Tweetbot is available to open it
if ([[UIApplication sharedApplication] canOpenURL:tweetbotURL]) {
[[UIApplication sharedApplication] openURL:tweetbotURL];
}
else {
// Check if Twitter is available to open it
if ([[UIApplication sharedApplication] canOpenURL:twitterURL]) {
[[UIApplication sharedApplication] openURL:twitterURL];
}
// Otherwise open it in the web view
else {
[self performSegueWithIdentifier:#"showWebView" sender:nil];
}
The URL schemes page for Tweetbot 3 is here
All of the supported URLs begin with tweetbot://<screenname>, which suggests that you need to know the user's existing twitter screen name to link to a profile.
However, my testing has shown that you could link directly to a profile by using the same value for tweetbot://<screenname>/user_profile/<profile_screenname>
Swift e.g.
/* Tweetbot app precedence */
if let tweetbotURL = NSURL(string: "tweetbot://dummyusername/user_profile/dummyusername") {
if UIApplication.sharedApplication().canOpenURL(tweetbotURL) {
UIApplication.sharedApplication().openURL(tweetbotURL)
return
}
}
/* Twitter app fallback */
if let twitterURL = NSURL(string: "twitter:///user?screen_name= dummyusername") {
if UIApplication.sharedApplication().canOpenURL(twitterURL) {
UIApplication.sharedApplication().openURL(twitterURL)
return
}
}
/* Safari fallback */
if let webURL = NSURL(string: "http://www.twitter.com/dummyusername") {
if UIApplication.sharedApplication().canOpenURL(webURL) {
UIApplication.sharedApplication().openURL(webURL)
}
}

Phonegap iOS: InAppBrowser opens but clicking on link sometimes does not open the page and event "falls through" to main webView

I'm developing an iOS app using phonegap and HTML5.
After launchImage in app, I open InAppBrowser, which opens promptly.
But, tapping on links in it sometimes does not open the desired page and event "falls through" to main webView.
i.e., InAppBrowser is closed on tapping the link.
Please do help me out as I'm stuck with this for the past two days.
Try this one
Put this code in your MainViewController.m before #end tag
- (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = [request URL];
// Intercept the external http requests and forward to Safari.app
// Otherwise forward to the PhoneGap WebView
if ([[url scheme] isEqualToString:#"http"] || [[url scheme] isEqualToString:#"https"]){
[[UIApplication sharedApplication] openURL:url];
return NO;
}
else {
return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
}
}
Resolved this issue by bypassing the error code. It is a bit of dirty workaround but couldn't help it. In "CDVInAppBrowser.m", modified as below and InAppBrowser loads my url successfully.
- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
{
//By passing error code
if(error.code == -999)
return;
// log fail message, stop spinner, update back/forward
NSLog(#"webView:didFailLoadWithError - %i: %#", error.code, [error localizedDescription]);
self.backButton.enabled = theWebView.canGoBack;
self.forwardButton.enabled = theWebView.canGoForward;
[self.spinner stopAnimating];
self.addressLabel.text = NSLocalizedString(#"Load Error", nil);
[self.navigationDelegate webView:theWebView didFailLoadWithError:error];
}

External google search link open in browser

I want to open the google search link like 'https://www.google.co.in/#q=adam+scott' in sencha touch hybrid ios app. I tried to use var ref = window.open(url, '_blank','location=yes'); but it is not loading the page and if I change the _blank to _system it is loading the page but not showing done button to move to previous page.
Please let me know if some body has done it.
I think this is what you are looking for:
navigator.app.loadUrl('https://www.google.co.in/#q=adam+scott', { openExternal:true } );
open your MainViewController.m class and add this line of code before #end
- (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = [request URL];
// Intercept the external http requests and forward to Safari.app
// Otherwise forward to the PhoneGap WebView
if ([[url scheme] isEqualToString:#"http"] || [[url scheme] isEqualToString:#"https"]){
[[UIApplication sharedApplication] openURL:url];
return NO;
}
else {
return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
}
}

"facebook login_sucess.html" not give access token through Graph API in iOS

I'm using Graph API in my iOS project. The problem is that after entering login credential in Facebook login webview it not give me access token with the redirect URI. I'm facing this problem with 2 days. Before 2 days my app working fine.
Code which called after login in Graph API is :
- (void)webViewDidFinishLoad:(UIWebView *)_webView {
/**
* Since there's some server side redirecting involved, this method/function will be called several times
* we're only interested when we see a url like: http://www.facebook.com/connect/login_success.html#access_token=..........
*/
//get the url string
NSString *url_string = [((_webView.request).URL) absoluteString];
//looking for "access_token="
NSRange access_token_range = [url_string rangeOfString:#"access_token="];
//looking for "error_reason=user_denied"
NSRange cancel_range = [url_string rangeOfString:#"error_reason=user_denied"];
//it exists? coolio, we have a token, now let's parse it out....
if (access_token_range.length > 0) {
//we want everything after the 'access_token=' thus the position where it starts + it's length
int from_index = access_token_range.location + access_token_range.length;
NSString *access_token = [url_string substringFromIndex:from_index];
//finally we have to url decode the access token
access_token = [access_token stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//remove everything '&' (inclusive) onward...
NSRange period_range = [access_token rangeOfString:#"&"];
//move beyond the .
access_token = [access_token substringToIndex:period_range.location];
//store our request token....
self.accessToken = access_token;
//remove our window
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window) {
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}
[self.webView removeFromSuperview];
//tell our callback function that we're done logging in :)
if ( (callbackObject != nil) && (callbackSelector != nil) ) {
[callbackObject performSelector:callbackSelector];
}
//the user pressed cancel
} else if (cancel_range.length > 0) {
//remove our window
UIWindow* window = [UIApplication sharedApplication].keyWindow;
if (!window) {
window = [[UIApplication sharedApplication].windows objectAtIndex:0];
}
[self.webView removeFromSuperview];
//tell our callback function that we're done logging in :)
if ( (callbackObject != nil) && (callbackSelector != nil) ) {
[callbackObject performSelector:callbackSelector];
}
}
[activityindicatorview stopAnimating];
}
Can anyone tell me what is the problem. Thanks in advance.
Facebook has changed his policies.
Item 4. Native iOS and Android apps must not use custom web views for
Login (Effective October 2, 2013)
You should use Facebook Official SDK.

fetching yahoo contacts in iphone

I am following this link: https://github.com/yahoo/yos-social-objc for retrieving yahoo contacts.
After providing all the credentials (i.e secret key, consumer key, app id) it is going to browser for login. But after logged in, it's displaying this message:
To complete sharing of yahoo! info with xxxx, enter code xxxx into xxxx
So, I am not getting that where I should enter this code? And how will it redirect to my application.
Any help will be appreciated.
CloudSponge has an iOS widget for its contact importer. Visit our test drive page from your iOS device to see how it works.
I work for CloudSponge, please let me know if you have any questions.
You need to specify your callback url. By default it's "oob" and will give you the verifier code. It will be better if you present your own web view and monitor the verifier code through webview delegates. Here's how you do it.
YOSSession *yahooSession; //instance variable
- (IBAction)yahooButtonAction:(UIButton *)sender {
yahooSession = [YOSSession sessionWithConsumerKey:YAHOO_CONSUMER_KEY
andConsumerSecret:YAHOO_CONSUMER_SECRET
andApplicationId:YAHOO_APP_ID];
// try to resume a user session if one exists
BOOL hasSession = [yahooSession resumeSession];
if(hasSession == FALSE) {
[self fetchSession];
}else{
[self sendRequests];
}
}
-(void)fetchSession{
// create a new YOSAuthRequest used to fetch OAuth tokens.
YOSAuthRequest *tokenAuthRequest = [YOSAuthRequest requestWithSession:yahooSession];
// fetch a new request token from oauth.
YOSRequestToken *newRequestToken = [tokenAuthRequest fetchRequestTokenWithCallbackUrl:#"http://localhost"];
// if it looks like we have a valid request token
if(newRequestToken && newRequestToken.key && newRequestToken.secret) {
// store the request token for later use
[yahooSession setRequestToken:newRequestToken];
[yahooSession saveSession];
// create an authorization URL for the request token
NSURL *authorizationUrl = [tokenAuthRequest authUrlForRequestToken:yahooSession.requestToken];
[self presentWebViewForYahooWithAuthURL:authorizationUrl];
//present it in webview
} else {
// NSLog(#"error fetching request token. check your consumer key and secret.");
}
}
-(void) presentWebViewForYahooWithAuthURL:(NSURL *)url{
_yahooWebView = [[UIWebView alloc] initWithFrame:self.view.frame];
_yahooWebView.delegate=self; //so that we can observe the url for verifier
[_yahooWebView loadRequest:[NSURLRequest requestWithURL:url]];
[self.view addSubview:_yahooWebView];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *requestString = request.URL.absoluteString;
if ([requestString rangeOfString:#"http://localhost"].length>0) {
NSRange verifierRange = [requestString rangeOfString:#"oauth_verifier="];
if (verifierRange.length>0) {
verifierRange.location =verifierRange.location+verifierRange.length;
verifierRange.length = requestString.length-verifierRange.location;
NSLog(#"Verifier => %#", [requestString substringWithRange:verifierRange]);
yahooSession.verifier=[requestString substringWithRange:verifierRange];
[self sendRequests];
}
return NO;
}
else{
return YES;
}
}

Resources