How to fill a HTML form using Objective-C - ios

I would like to load a web page (containing a form: username and password) in a UIWebView, but I would like the web page to be filled when the UIWebView is loaded. I read so much stuff and tried so many things, but nothing works.
here is my code :
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://login.live.com"]];
// Specify that it will be a POST request
request.HTTPMethod = #"POST";
// This is how we set header fields
[request setValue:#"application/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"username" forHTTPHeaderField:#"session[email]"];
// Convert your data and set your request's HTTPBody property
NSString *stringData = #"some data";
NSData *requestBodyData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = requestBodyData;
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[self.webView loadRequest:request];

Let's say you have a form field defined like this:
<input type="text" id="mytext">
Then you can assign a value to this field as follows:
NSString *javascript = #"document.getElementById('mytext').value = 'new value'";
[webView stringByEvaluatingJavaScriptFromString:javascript];
The above code needs to run after your page has fully loaded. For example, you can make your view controller implement UIWebViewDelegate, declare the method - (void)webViewDidFinishLoad:(UIWebView *)webView and do it there.

EDITED: 20/03/2014 -: I added how to get the code from the UIWebView
If you want know when the page did finish loading, you should implement UIWebViewDelegate in your UIViewController:
Then you can detect when the page finish loading by implementing this method:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
UIApplication* app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = NO;
[_activityIndicator stopAnimating];
_activityIndicator.hidden = TRUE;
}
In you case, you want to modify the code when the page it's loaded, so in the method (void)webViewDidFinishLoad:(UIWebView *)webView you should do the next to get the code as a NSString:
NSURL *requestURL = [[yourWebView request] URL];
NSError *error;
NSString *page = [NSString stringWithContentsOfURL:requestURL encoding:NSASCIIStringEncoding error:&error];
For more details take a look to this answer.
I hope this help you.

Related

UIWebView not getting next Url to Load

I am working on a native cum web iOS app. When i try to load Urls in UIWebView on any button press inside WebView i am unable to get the next URL to be loaded. Can anyone suggest anything for this? Thanks in advance.
Here is my Code:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *myString = [[request URL] absoluteString];
[myString lowercaseString];
NSLog(#"%#",myString)
NSDictionary *headers = [request allHTTPHeaderFields];
BOOL hasReferer = [headers objectForKey:#"X"]!=nil;
if (hasReferer)
{
return YES;
}
else
{
// relaunch with a modified request
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSURL *url = [request URL];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setValue:X forHTTPHeaderField:#"X"];
[request setValue:Y forHTTPHeaderField:#"Y"];
[loadingWebView loadRequest:request];
});
});
return NO;
}
return 0;
}
set delegate
- (void)webViewDidStartLoad:(UIWebView *)webView;
- (void)webViewDidFinishLoad:(UIWebView *)webView;
- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error;
see in this method what it returns
and make sure you are passing correct url ie stringByAddingPercentEscapesUsingEncoding

How To Get Key Of goDaddy

Actually I want to created application of shortening URL , i have used GoDady by creating account at http://app.x.co/ But My URL doesnot get shorten.
This is my key
#define kGoDaddyAccountKey #"b201137c009311e6984efa163ee12fa9"
This is actually The method that do work for Shortening URL
- (IBAction)shortenURL:(id)sender
{
NSString *urlToShorten = self.webView.request.URL.absoluteString;
NSString *urlString = [NSString stringWithFormat:#"http://api.x.co/Squeeze.svc/text/%#?url=%#",kGoDaddyAccountKey,
[urlToShorten stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
shortURLData = [NSMutableData new];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
shortenURLConnection = [NSURLConnection connectionWithRequest:request
delegate:self];
}
But I get error like This.
Quite Interesting, Please Help.

Objective-C getting mime type of url file before webview loads it

I'm facing a problem building a web browser with download functionality, here's my code:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = request.URL;
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
[conn start];
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if ([[response MIMEType] rangeOfString:#"video"].location != NSNotFound) {
// Do something with that video
}
}
This is currently working as intended, video files will be handled correctly but the webview will also load it, what i need to do is capture the mime type of the file before returning YES in shouldStartLoadWithRequest and return NO if it's a video.
I tried the sendSynchronousRequest method but it slows the app, I also tried:
#import <MobileCoreServices/MobileCoreServices.h>
NSString *fileExtension = [myFileURL pathExtension];
NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, NULL);
NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);
But I often get wrong myme types, last thing, I dont want to detect type by the file extension since urls can be formatted as aliases.
Thank you for your help.
NSURLConnection is dead so stop using it. Switch to NSURLSession. NSURLSession gives you a data task delegate method that lets you examine the response header and bow out.

IOS Creating Utility Class For NSURL

I have a project I am working on that has a number of different news feeds and announcement boards that displays post from various sources. Currently I have the code for the like, delete and flag buttons in methods contained in each class file for the views that display the feeds. I have been trying to craft a utility class that allows me to place the code for the three functionalities listed above in one object to be used throughout the project. I have done the exact same type of thing in C++ or Java, but am having issues reproducing it in objective-c. The like, delete and flag buttons use the NSURL libraries to interact with the web service. Bellow is an example of one of the methods I am trying to implement in the utility class, and is the code used to be implemented in the like buttons:
+ (void)btnLikeAction:(UIButton *)btnLike userIdString:(NSString *)userId contentSource:(NSString *)sourceId cellUsed:(NewsfeedCell *)cell dataForCell:(Post *)post
{
BOOL hasLiked = post.hasLiked;
UILabel *likeLabel = cell.likeCount;
NSString *pId = post.postId;
if (hasLiked)
{
[btnLike setEnabled:NO];
NSString *url = [NSString stringWithFormat: #"http://192.155.94.183/api/v1/likes/unlike/%#/%#/%#/", sourceId, pId, userId];
NSURL *URL = [NSURL URLWithString:url];
NSURLRequest *request = [NSURLRequest requestWithURL:URL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
int localCount = [likeLabel.text intValue];
localCount--;
likeLabel.text = [NSString stringWithFormat:#"%i", localCount];
post.likeCount = [NSString stringWithFormat:#"%i", localCount];
post.hasLiked = NO;
[btnLike setEnabled:YES];
}
else
{
[btnLike setEnabled:NO];
NSError *err = nil;
NSDictionary *likeData = [NSDictionary dictionaryWithObjectsAndKeys:
userId, #"user_id",
pId, #"source_id",
sourceId, #"source",
nil];
NSData *JSONLike = [NSJSONSerialization dataWithJSONObject:likeData options:NSJSONWritingPrettyPrinted error:&err];
NSString *url = #"http://192.155.94.183/api/v1/likes.json";
NSURL *URL = [NSURL URLWithString:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:30.0];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [JSONLike length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:JSONLike];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
int localCount = [likeLabel.text intValue];
localCount++;
likeLabel.text = [NSString stringWithFormat:#"%i", localCount];
post.likeCount = [NSString stringWithFormat:#"%i", localCount];
post.hasLiked = YES;
[btnLike setEnabled:YES];
}
}
This code uses a web service to update the number of likes for a specific piece of content. It works when the method is placed into the individual ViewController class files, but when I try to make a utility class with the individual methods I run into issues with the didReceiveAuthenticationChallenge, didReceiveResponse, didReceiveData and connectionDidFinishLoading methods not being called. Originally, I assumed that the delegate methods would be called in the file that that the utility methods were called in. But that was not the case. When I implemented the method definitions in the actual utility class, the methods still weren't called. I did some research on the topic and looked into this article but found I was unable to find substantial resources that helped my specific situation. How do I set up my utility class? I can post the full code of the utility if needed.
As #serrrgi already said, the problem is that btnLikeAction:... is a class method, so that self is the class itself. You have the following options:
Make all delegate methods class methods, e.g.
+ (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"didReceiveResponse");
}
Create an instance of your Utility class and use that as delegate:
YourClass *u = [[self alloc] init];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:u];
Use sendAsynchronousRequest:..., which does not need a delegate:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (data != nil) {
NSLog(#"success");
} else {
NSLog(#"error: %#", error);
}
}];

Why is -stringWithContentsOfURL: returning nil for my JSON communication here?

On the server side, I have code like this to provide JSON to my iOS application:
$val = array("a", "b", "c","d");
return json_encode($val);
Within that application, I try to communicate with the server using the following code:
NSError *error = nil;
NSString *szURL =#"http://192.168.1.159/return.php";
NSURL *url = [NSURL URLWithString:szURL];
NSString *strData = [NSString stringWithContentsOfURL:url
encoding:NSUTF8StringEncoding
error:&error];
NSArray *appLists = (NSArray *)[strData JSONValue];
However, strData is always nil. Why is this happening, and what can I do to prevent it?
I would recommend, unless you want your requests to occur synchronously and block up the UI, to perform an asynchronous request using NSURLConnection or a third party solution. I like TTURLRequest from http://three20.info because it makes it very easy to specify headers, gets the JSON value from the data, etc. An example call would look like this:
TTURLRequest *request = [[TTURLRequest alloc] initWithURL:#"http://192.168.1.159/return.php" delegate:self];
request.httpMethod = #"GET";
request.response = [[[TTURLJSONResponse alloc] init] autorelease];
request.cachePolicy = TTURLRequestCachePolicyNone;
[request send];
Then your delegate must implement these methods:
-(void)requestDidFinishLoad:(TTURLRequest *)request;
-(void)request:(TTURLRequest *)request didFailLoadWithError:(NSError *)error;

Resources