Setting UIDelegate for UIWebView - ios

I read somewhere to read javascript console messages using the
- (void)webView:(WebView *)webView addMessageToConsole:(NSDictionary *)message
delegate method from the UIDelegate. But how/where do I need to set the delegate of the WebView (not the UIWebView) to my custom delegate?
I know Apple doesn't allow this in the AppStore, but I just want to implement this for debugging purposes.
What I tried so far:
- (void)webView:(id)sender didClearWindowObject:(id)windowObject forFrame:(WebFrame*)frame
{
[webView setUIDelegate:[[MyCustomUIDelegate alloc] init]];
}
and
-(void) webView:(id)webView windowScriptObjectAvailable:(id)newWindowScriptObject
{
[webView setUIDelegate:[[MyCustomUIDelegate alloc] init]];
}

This post may help you:
How can my iPhone Objective-C code get notified of Javascript errors in a UIWebView?
You can hook UIWebView control to hidden WebKit framework and get all exceptions, executed functions and similar.
Another way is posted here: Inject javascript code into the response that invoke to a objecie-c function.
NSString* path = [[NSBundle mainBundle] pathForResource:#"script"
ofType:#"js"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
[sender stringByEvaluatingJavaScriptFromString:content];
for exapmle the javascript code may be like:
console = new Object();
console.log = function(log) {
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "ios-log:#iOS#" + log);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
console.debug = console.log;
console.info = console.log;
console.warn = console.log;
console.error = console.log;
and the objective-c code like:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *requestString = [[[request URL] absoluteString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
//NSLog(requestString);
NSLog(#"Request: %#", requestString);
if ([requestString hasPrefix:#"ios-log:"]) {
NSString* logString = [[requestString componentsSeparatedByString:#":#iOS#"] objectAtIndex:1];
NSLog(#"UIWebView console: %#", logString);
return NO;
}
return YES;
}

Related

iOS Tracking URL change in UIWebView and grabbing the data it gives back

I'm pretty new to iOS development, and can't find an answer that helps my problem anywhere.
I'm making an app where the user must first login, using a UIWebView.
Once the user logs in, they are taken to the app, but in the background the server has passed a unique authentication key for each user.
Example
The user logs in at the URL www.example.com/login.
on a successful login the URL changes to www.example.com/key/jsaeglihndzlgaskn with the end bit being the key I need to get.
I have a method which gets the last segment of the URL but it takes the starting URL not the one that changes.
NSString *absoluteString= _webView.request.URL.absoluteString;
NSArray* foo = [absoluteString componentsSeparatedByString: #"/"];
NSUInteger arrsize = [foo count];//count the size of array
NSString* bar = foo[arrsize-1];//get last element
Any help would be massively appreciated
Edit
This is how my code now looks, but It still doesn't function as I need it to, any help getting this to work would be greatly appreciated.
NSString *urlString = #"https://probablyrational.com/alpha/dashboard/register/?callback=inline";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[_webView loadRequest:urlRequest];
NSString* absoluteString = [url absoluteString];
NSArray* foo = [absoluteString componentsSeparatedByString: #"/"];//explode() .split()
NSUInteger arrsize = [foo count];//count the size of array
NSString* bar = foo[arrsize-1];//get last element
NSLog(#"bar %#", bar);
//bar = "?callback=inline"
if ([foo[arrsize-2] isEqualToString:#"key"]) {
// user is authenticated
NSLog(#"bar %#", bar);
- (BOOL)_webView:(UIWebView *)_webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *URLString = [[request URL] absoluteString];
if ([URLString isEqualToString:#"https://probablyrational.com/alpha/key"]) {
// The user reached step 3!
}
return YES;
}
EDIT 2
My code is now running but still not tracking the URL change..
NSString *urlString = #"https://probablyrational.com/alpha/dashboard/register/?callback=inline";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[_webView loadRequest:urlRequest];
NSString* absoluteString = [url absoluteString];
NSArray* foo = [absoluteString componentsSeparatedByString: #"/"];//explode() .split()
NSUInteger arrsize = [foo count];//count the size of array
NSString* bar = foo[arrsize-1];//get last element
NSLog(#"bar %#", bar);
//bar = "?callback=inline"
if ([foo[arrsize-2] isEqualToString:#"key"]) {
// user is authenticated
NSLog(#"bar %#", bar);
}
}
- (BOOL)webView:(UIWebView *)webView didFinishLoading:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *absoluteString = [[request URL] query];
if ([absoluteString isEqualToString:#"https://probablyrational.com/alpha/key"]) {
// The user reached step 3!
( NSLog(#"this is the code you're looking for"));
return YES;
}
else
{
( NSLog(#"this is not code you're looking for"));
return 0;
}
}
Any clue how I can get this to work would be life saving, i'm stuck at this point
you can use [foo lastObject]; to get the last component.

How to get url which I hit on UIWebView?

NSString *testString =[NSString stringWithFormat:#" Google"];
[webView loadHTMLString:testString baseURL:nil];
I want to get the URL when I click on this UIWebView content in
-(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if ( inType == UIWebViewNavigationTypeLinkClicked ) {
[[UIApplication sharedApplication] openURL:inRequest.mainDocumentURL];
return NO;
}
return YES;
}
delegate method.
When I click google hyperlink in webview it gives
URL: applewebdata://
Please help me.
You question is not very clear if you want to get the tapped url on webview or the webview's loaded page url ,
If you want to get webview loaded page url you can use NSURLRequestObject,something like
NSString * url = [request URL];
If you want to get the clicked link url , you will have to use this java script
NSString *url = [webView stringByEvaluatingJavaScriptFromString:#"window.location"];
you can do like this way
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if ([request.URL.absoluteString rangeOfString:#"www.google.com"].location!=NSNotFound)
{
[[UIApplication sharedApplication]openURL:request.URL];
return NO;
}
return YES;
}
For Swift:
Whenever your webpage is loaded you can use this, I use it for a label in this case:
webUrlLabel.text = webView.request.URL.absoluteString
For Objective-C:
NSString *currentPage = [NSString stringWithFormat:#"%#", webView.request.URL.absoluteString];
webUrlLabel is a UILabel
webView is my UIWebView
You already have NSURLRequest object. Access url from that.
inRequest.URL
way 1:
NSString *currentURL = myWebView.request.URL.absoluteString;
Way 2:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
//CAPTURE USER LINK-CLICK.
NSURL *url = [request URL];
yourTextBox.text = [url absoluteString];
return YES;
}
Please let me know if it works. Thanks

How to get this into code form (if statement)

How to make this statement into an actual "if statement" in Xcode?
This is what i want in the form of an "if statement" :
"if a certain link is shown in UIWebView, then image.hidden = NO;"
The UIWebView is currently showing another website, but it has a page in that website that is the certain link I mentioned in the if statement.
The code for the UIWebView is this:
.h:
IBOutlet UIWebView *Name;
NSURL *NameURL;
.m
NameURL = [NSURL URLWithString:#"mywebname.com"];
NSURLRequest *Request = [NSURLRequest requestWithURL: NameURL];
[Name loadRequest: Request];
To access the actual page content within UIWebView, you need to use
stringByEvaluatingJavaScriptFromString: to invoke some JavaScript snippet. Once the page finishes loading, the idea is to loop through all a elements and check for its href attribute, comparing it to the 'certain site' that you mentioned.
Rough implementation:
JS Code
for (var i = 0; i < document.getElementsByTagName('a').length; i++)
{
if (document.getElementsByTagName('a')[i].href.match(/google/) return 'YES';
}
return 'NO';
Obj-C Code
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *test = [webView stringByEvaluatingJavaScriptFromString:aboveJSString];
if ([test isEqualToString:#"YES"]) image.hidden = NO;
}
Hope it helps.
According to Anh Do's answer stringByEvaluatingJavaScriptFromString isn't reliable for me.
Instead you should use:
currentURL = currentWebView.request.URL.absoluteString;
So the code will be likeā€¦.
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSLog(#"HELLO DID GET CALLELDLLL LL LL LL ");
//get the url you webView called "Name" is displaying...
NSString *currentURL = Name.request.URL.absoluteString;
//Check if that url is "mywebname.com"
if ([currentURL isEqualToString:#"mywebname.com"])
{
image.hidden = NO;
}
}
PS. Don't for get to add delegate to you webview
By setting delegate do this..
In ViewDidLoad:
[Name setDelegate:self];
In .h file
#interface "nameofyourviewcontroller" : UIViewController<UIWebViewDelegate>

XCDYouTubeVideoPlayer opens and close

I've start working with XCDYouTubeVideoPlayer. It does seem to have, some small issues. When I use the method (like below) to call the player it opens it and close it right away.
I've imported following frameworks:
mediaplayer
AVfoundation
and added the `XCDYouTubeVideoPlayerViewController.h and .m
In the viewController.m I've added this method:
- (IBAction) play:(id)sender
{
[self.view endEditing:YES];
NSString *link = #"m01MYOpbdIk";
XCDYouTubeVideoPlayerViewController *videoPlayerViewController = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:link];
[self presentMoviePlayerViewControllerAnimated:videoPlayerViewController];
}
At the moment its opening and closing the XCDYouTubeVideoPlayer right a way. What am i doing wrong?
I not understand why, but for me , in iOS8 the line
XCDYouTubeVideoPlayerViewController.m at #79
was calling the method :
- (id) initWithContentURL:(NSURL *)contentURL
{
#throw [NSException exceptionWithName:NSGenericException reason:#"Use the
` initWithVideoIdentifier:` method instead." userInfo:nil];
}
I just comment it and works!
XCDYouTubeVideoPlayer library build the youtube "streaming link", by appending the url with the signature provided. It seems that the "url" now has the signature along with it and the "sig" key comes null, which thereby negates the if statement in the function
(NSURL *) videoURLWithData:(NSData *)data error:(NSError * __autoreleasing *)error
Goto file
XCDYouTubeVideoPlayerViewController.m at #248
you will see a for-loop
for (NSString *streamQuery in streamQueries)
{
NSDictionary *stream = DictionaryWithQueryString(streamQuery, queryEncoding);
NSString *type = stream[#"type"];
NSString *urlString = stream[#"url"];
NSString *signature = stream[#"sig"];
if (urlString && signature && [AVURLAsset isPlayableExtendedMIMEType:type])
{
NSURL *streamURL = [NSURL URLWithString:[NSString
stringWithFormat:#"%#&signature=%#",
urlString,
signature]];
streamURLs[#([stream[#"itag"] integerValue])] = streamURL;
}
change it to this (remove the signature variable from if statement and modify the URLWithString)
for (NSString *streamQuery in streamQueries)
{
NSDictionary *stream = DictionaryWithQueryString(streamQuery, queryEncoding);
NSString *type = stream[#"type"];
NSString *urlString = stream[#"url"];
if (urlString && [AVURLAsset isPlayableExtendedMIMEType:type])
{
NSURL *streamURL = [NSURL URLWithString:urlString];
streamURLs[#([stream[#"itag"] integerValue])] = streamURL;
}

control is not returned from web view shouldstartload delegate method

In my application i am using Uiwebview for displaying vimeo authorization page, after the user has authorized it, i have to parse the url for OAtoken and dismiss it, for that i am using should startLoad delegate method, but after the process is over and when i am returning NO, the control is not transferred back...
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSURL *url = [request mainDocumentURL];
NSString *str1 = [url absoluteString];
NSString *str = #"https://vimeo.com/oauth/confirmed";
//[webView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"bg_cork.png"]]];
if([str isEqualToString:str1])
{
//removing the webview after the user approves.
//[webView removeFromSuperview];
return YES;
}
//parsing the redirected url to get the oauth_verifier.
URLParser *parser = [[URLParser alloc] initWithURLString:str1];
Oauth_verifier = [parser valueForVariable:#"oauth_verifier"];
//getting the final access token by giving the oauth verifier.
NSURL *url_access = [[NSURL alloc] initWithString:#"https://vimeo.com/oauth/access_token"];
OAMutableURLRequest *reques_access = [[OAMutableURLRequest alloc]initWithURL:url_access consumer:consumer token:acessToken realm:nil signatureProvider:nil];
OARequestParameter *p2 = [[OARequestParameter alloc] initWithName:#"oauth_verifier" value:Oauth_verifier];
NSArray *params2 = [NSArray arrayWithObject:p2];
[reques_access setParameters:params2];
[reques_access setHTTPMethod:#"GET"];
OADataFetcher *fetcher_access = [[OADataFetcher alloc]init];
[fetcher_access fetchDataWithRequest:reques_access delegate:self didFinishSelector:#selector(acessTokenTicket:didFinishWithData:) didFailSelector:#selector(acessTokenTicket:didFailWithError:)];
//if the access token is successfully generated then the control transferrd to acessTokenTicket did finish with data
// Return YES if you want to load the page, and NO if you don't.
NSLog(#"at return yes");
if (i==1) {
NSLog(#"returning no");
[webView removeFromSuperview];
return NO;
}
return YES;
}
i am sure that it is going to return no because the statement "returning no" is printed, but the control is not returned,i have given the statement
NSLog(#"returned from web view delegate");
in the main function to know whether the control is returned it is not returned and also the operations below are not performed.

Resources