How do I insert a POST request into a UIWebView - iphone

For a GET request I've tried this simple method:
NSString *urlAddress = #"http://example.com/";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[uiWebViewThingy loadRequest:request];
(Although it doesn't seem to work if the request contains high UTF-8 characters. )
I want to send a POST from the iPhone.
This also give an overview for sending POST/GET requests although what I really want to do is embed the resulting web page into UIWebView. What would be the best way to go around that?

You can use an NSMutableURLRequest, set the HTTP method to POST, and then load it into your UIWebView using -loadRequest.

Thanks for you answer Seva.
I've made a method out of your code, hope this helps other people :)
//-------------------------------------------------------------------
// UIWebViewWithPost
// init a UIWebview With some post parameters
//-------------------------------------------------------------------
- (void)UIWebViewWithPost:(UIWebView *)uiWebView url:(NSString *)url params:(NSMutableArray *)params
{
NSMutableString *s = [NSMutableString stringWithCapacity:0];
[s appendString: [NSString stringWithFormat:#"<html><body onload=\"document.forms[0].submit()\">"
"<form method=\"post\" action=\"%#\">", url]];
if([params count] % 2 == 1) { NSLog(#"UIWebViewWithPost error: params don't seem right"); return; }
for (int i=0; i < [params count] / 2; i++) {
[s appendString: [NSString stringWithFormat:#"<input type=\"hidden\" name=\"%#\" value=\"%#\" >\n", [params objectAtIndex:i*2], [params objectAtIndex:(i*2)+1]]];
}
[s appendString: #"</input></form></body></html>"];
//NSLog(#"%#", s);
[uiWebView loadHTMLString:s baseURL:nil];
}
to use it
NSMutableArray *webViewParams = [NSMutableArray arrayWithObjects:
#"paramName1", #"paramValue1",
#"paramName2", #"paramValue2",
#"paramName3", #"paramValue3",
nil];
[self UIWebViewWithPost:self.webView url:#"http://www.yourdomain.com" params:webViewParams];

(edited original answer to include newly tested code)
I just wanted to drop in my version of this request. I have used a dictionary to represent the post parameters.
It's a chunk of code but is simple enough to drop into a view with a webview and use for all URL loading. It will only POST if you send a "postDictionary". Otherwise it will use the url you sent it to just GET things.
- (void) loadWebView:(UIWebView *)theWebView withURLString:(NSString *)urlString andPostDictionaryOrNil:(NSDictionary *)postDictionary {
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60.0];
// DATA TO POST
if(postDictionary) {
NSString *postString = [self getFormDataString:postDictionary];
NSData *postData = [postString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
}
[theWebView loadRequest:request];
}
- (NSString *)getFormDataString:(NSDictionary*)dictionary {
if( ! dictionary) {
return nil;
}
NSArray* keys = [dictionary allKeys];
NSMutableString* resultString = [[NSMutableString alloc] init];
for (int i = 0; i < [keys count]; i++) {
NSString *key = [NSString stringWithFormat:#"%#", [keys objectAtIndex: i]];
NSString *value = [NSString stringWithFormat:#"%#", [dictionary valueForKey: [keys objectAtIndex: i]]];
NSString *encodedKey = [self escapeString:key];
NSString *encodedValue = [self escapeString:value];
NSString *kvPair = [NSString stringWithFormat:#"%#=%#", encodedKey, encodedValue];
if(i > 0) {
[resultString appendString:#"&"];
}
[resultString appendString:kvPair];
}
return resultString;
}
- (NSString *)escapeString:(NSString *)string {
if(string == nil || [string isEqualToString:#""]) {
return #"";
}
NSString *outString = [NSString stringWithString:string];
outString = [outString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// BUG IN stringByAddingPercentEscapesUsingEncoding
// WE NEED TO DO several OURSELVES
outString = [self replace:outString lookFor:#"&" replaceWith:#"%26"];
outString = [self replace:outString lookFor:#"?" replaceWith:#"%3F"];
outString = [self replace:outString lookFor:#"=" replaceWith:#"%3D"];
outString = [self replace:outString lookFor:#"+" replaceWith:#"%2B"];
outString = [self replace:outString lookFor:#";" replaceWith:#"%3B"];
return outString;
}
- (NSString *)replace:(NSString *)originalString lookFor:(NSString *)find replaceWith:(NSString *)replaceWith {
if ( ! originalString || ! find) {
return originalString;
}
if( ! replaceWith) {
replaceWith = #"";
}
NSMutableString *mstring = [NSMutableString stringWithString:originalString];
NSRange wholeShebang = NSMakeRange(0, [originalString length]);
[mstring replaceOccurrencesOfString: find
withString: replaceWith
options: 0
range: wholeShebang];
return [NSString stringWithString: mstring];
}

You can use something like ASIHTTPRequest to make the POST request (With the option of doing it asynchronously) and then load the response string/data into the UIWebView. Look at this page under the section titled Sending data with POST or PUT requests and then look at the Creating an asynchronous request section at the top for information on how to handle the response string/data.
Hope that helps, sorry if I misunderstood your question.

Using loadHTMLString, feed a page to the UIWebView that has a hidden, pre-populated form, then make that page do a Javascript forms[0].submit() on loading.
EDIT: First, you collect the input into variables. Then you compose HTML like this:
NSMutableString *s = [NSMutableString stringWithCapacity:0];
[s appendString: #"<html><body onload=\"document.forms[0].submit()\">"
"<form method=\"post\" action=\"http://someplace.com/\">"
"<input type=\"hidden\" name=\"param1\">"];
[s appendString: Param1Value]; //It's your variable
[s appendString: #"</input></form></body></html>"];
Then you add it to the WebView:
[myWebView loadHTMLString:s baseURL:nil];
It will make the WebView load the form, then immediately submit it, thus executing a POST request to someplace.com (your URL will vary). The result will appear in the WebView.
The specifics of the form are up to you...

Create POST URLRequest and use it to fill webView
NSURL *url = [NSURL URLWithString: #"http://your_url.com"];
NSString *body = [NSString stringWithFormat: #"arg1=%#&arg2=%#", #"val1",#"val2"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL: url];
[request setHTTPMethod: #"POST"];
[request setHTTPBody: [body dataUsingEncoding: NSUTF8StringEncoding]];
[webView loadRequest: request];

Here is a Swift version of Seva Alekseyev's answer which worked perfectly for me. Thanks for the nice post mate! BTW following code is in Swift 3.1.
func injectPOST(params data: [String: Any]) {
var str = String()
str.append("<html><head></head>")
str.append("<body onload=\"payment_form.submit()\">")
str.append("<form id=\"payment_form\" action=\"\(urlString)\" method=\"post\">") //urlString is your server api string!
for object in data { //Extracting the parameters for request
str.append("<input name=\"\(object.key)\" type=\"hidden\" value=\"\(object.value)\">")
}
str.append("</form></body></html>")
webView?.loadHTMLString(stringObj, baseURL: nil)
}

Related

newby IOS: unable to redirect url

This is my first IOS project. Having a tough time getting login to work. The site has a meta_refresh to another url. I've tried to send another request to the url in the meta_refresh but then the app just hangs. I'm sure that I'm doing something wrong but I'm using XCode 4.4 so a lot of the NSURLConnection delegate methods have been deprecated.
Here's what I'm doing:
NSString *urlAsString = baseURL;
urlAsString = [urlAsString stringByAppendingString:#"?user[login]=username"];
urlAsString = [urlAsString stringByAppendingString:#"&user[password]=password"];
urlAsString = [urlAsString stringByAppendingString:#"&origin=splash"];
NSURL *url = [NSURL URLWithString:urlAsString];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setTimeoutInterval:30.0f];
[urlRequest setHTTPMethod:#"POST"];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
if([data length] > 0 && error == nil){
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"HTML = %#", html);
NSRange obj = [html rangeOfString:#"http-equiv=\"refresh\""];
NSInteger len = obj.length;
} else if([data length] == 0 && error == nil) {
NSLog(#"No data was returned.");
} else {
NSLog(#"Error happened = %#", error);
}
Here's what I'm getting:
Another question is that I've read that I should use asynchronous connection. The trouble is that I need the data scraped from the site to display on the screen. If I display the screen before the data is returned, then I won't have any data -- or am I not understanding how this works?
Thanks.
--Tony
I think that maybe you're a mixing stuff. You're setting a string url with GET values and then you set the HTTPMethod to POST and I don't know if that is going to work fine.
Here's a code that I have to send values with POST:
NSString *post = [NSString stringWithFormat:#"&user_login=%#&user_password=%#&origin=%#,username,password, splash];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:baseURL]]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];

Google Api Using With Json

When I Call Google API for get the address and i calling api here like .
-(void)searchviews:(NSString*)EditString selector:(SEL)sel
{
NSLog(#"Welcome To Search views");
searchviews=sel;
NSString *path =[NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?address=%#&sensor=false",EditString];
NSURL *url=[NSURL URLWithString:path];
NSLog(#"hiii---%#",url);
ASIFormDataRequest *request=[ASIFormDataRequest requestWithURL:url];
[request setRequestMethod:#"POST"];
[request setDelegate:self];
[request startAsynchronous];
[drkSignUp showWithMessage:nil];
NSLog(#" Complet--------------- ");
and for Request Method I call like .
- (void)requestFinished:(ASIHTTPRequest *)request {
//NSLog(#"%#",[request responseString]);
NSString *func = [self getFunc:[request url]];
NSLog(#"%#\n%#",func,[request responseString]);
if ([func isEqual:#"json?address=%#&sensor=false"])
{
NSDictionary *resDict = [parser objectWithString:[request responseString] error:nil];
NSLog(#"---- ResData%#",resDict);
NSString *result = [resDict objectForKey:#"successful"];
NSLog(#"hiiiii google api calling............");
[drkSignUp hide];
[self.delegate performSelector:searchviews withObject:[resDict objectForKey:#"results"]];
the is like that but problem create in fun . When i call
if ([func isEqual:#"json?address=%#&sensor=false"])
it is not calling cos the it is be Dynamic String.So What Should I put inplace of %# in func ?
You can fill the userInfo dictionary of ASIFormDataRequest like the following
//After this line
ASIFormDataRequest *request=[ASIFormDataRequest requestWithURL:url];
//Add
request.userInfo = [NSDictionary dictionaryWithObject:#"EditString" forKey:#"request"];
Then in
- (void)requestFinished:(ASIHTTPRequest *)request {
//Get the request userInfo
NSString *str = [request.userInfo objectForKey:#"request"];
//now fill the request string
NSString *requestString = [NSString stringWithFormat:#"json?address=%#&sensor=false", str];
//Check it with func
if ([func isEqual:requestString])
{
//Continue your procedure
}
}

Google Image Search iPhone URL Data

I want to do a simple google image search and return one image for whatever is string I'm searching for. image is null when I finish, what am I doing wrong? Code below:
-(void)getGoogleImage
{
NSString *google = [NSString stringWithFormat:#"%#",[[NSUserDefaults standardUserDefaults]objectForKey:#"string"]];
NSString *newGoogle = [google stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSString *fullGoogle = [NSString stringWithFormat:#"https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=%#",newGoogle];
NSURL * url = [NSURL URLWithString:fullGoogle];
NSURLRequest * request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"Did Recieve Response");
responseData = [[NSMutableData alloc]init];
}
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
NSLog(#"Did Recieve Data");
[responseData appendData:data];
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
NSLog(#"Did Fail");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Did Finish");
image = [[UIImage alloc]initWithData:responseData];
}
When i search for dog i get this in a web browser:
{"responseData": {"results":[{"GsearchResultClass":"GimageSearch","width":"220","height":"211","imageId":"ANd9GcTZKvO0mDGuDdifdhW3TEG8bmcPM23DMGEB4wevzBuIPp7HMMwQ3dTetVc","tbWidth":"107","tbHeight":"103","unescapedUrl":"http://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Timba%2B1.jpg/220px-Timba%2B1.jpg","url":"http://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Timba%252B1.jpg/220px-Timba%252B1.jpg","visibleUrl":"en.wikipedia.org","title":"\u003cb\u003eDog\u003c/b\u003e - Wikipedia, the free encyclopedia","titleNoFormatting":"Dog - Wikipedia, the free encyclopedia","originalContextUrl":"http://en.wikipedia.org/wiki/Dog","content":"the appropriate-sized \u003cb\u003edog\u003c/b\u003e","contentNoFormatting":"the appropriate-sized dog","tbUrl":"http://t0.gstatic.com/images?q\u003dtbn:ANd9GcTZKvO0mDGuDdifdhW3TEG8bmcPM23DMGEB4wevzBuIPp7HMMwQ3dTetVc"},{"GsearchResultClass":"GimageSearch","width":"170","height":"224","imageId":"ANd9GcTycy7IfwO9VLFIftSa7yNZj1b_BP583qUQ0UmSZnog_jdhdwvewcWvrw","tbWidth":"82","tbHeight":"108","unescapedUrl":"http://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Golden_retriever_eating_pigs_foot.jpg/170px-Golden_retriever_eating_pigs_foot.jpg","url":"http://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Golden_retriever_eating_pigs_foot.jpg/170px-Golden_retriever_eating_pigs_foot.jpg","visibleUrl":"en.wikipedia.org","title":"\u003cb\u003eDog\u003c/b\u003e - Wikipedia, the free encyclopedia","titleNoFormatting":"Dog - Wikipedia, the free encyclopedia","originalContextUrl":"http://en.wikipedia.org/wiki/Dog","content":"See also: \u003cb\u003eDog\u003c/b\u003e food","contentNoFormatting":"See also: Dog food","tbUrl":"http://t1.gstatic.com/images?q\u003dtbn:ANd9GcTycy7IfwO9VLFIftSa7yNZj1b_BP583qUQ0UmSZnog_jdhdwvewcWvrw"},{"GsearchResultClass":"GimageSearch","width":"334","height":"360","imageId":"ANd9GcTsX8rcRiPIMso7akKaQmVP4PzMwoAfbVnlc6KkPNG5jpU7wfyZNWy1oNs","tbWidth":"112","tbHeight":"121","unescapedUrl":"http://www.petscarecenter.com/wp-content/uploads/2011/05/dog.jpg","url":"http://www.petscarecenter.com/wp-content/uploads/2011/05/dog.jpg","visibleUrl":"www.petscarecenter.com","title":"Tips for \u003cb\u003eDog\u003c/b\u003e Care","titleNoFormatting":"Tips for Dog Care","originalContextUrl":"http://www.petscarecenter.com/dog-care/tips-for-dog-care.html","content":"Since \u003cb\u003edogs\u003c/b\u003e are known for the","contentNoFormatting":"Since dogs are known for the","tbUrl":"http://t0.gstatic.com/images?q\u003dtbn:ANd9GcTsX8rcRiPIMso7akKaQmVP4PzMwoAfbVnlc6KkPNG5jpU7wfyZNWy1oNs"},{"GsearchResultClass":"GimageSearch","width":"400","height":"366","imageId":"ANd9GcS6VxIzGltwNb2PWMGDfoBvvuof26Kn9i_BrXYRvgWqpnnT3UNfy5DYyC8","tbWidth":"124","tbHeight":"113","unescapedUrl":"http://static.ddmcdn.com/gif/dog-best-friend-1.jpg","url":"http://static.ddmcdn.com/gif/dog-best-friend-1.jpg","visibleUrl":"animals.howstuffworks.com","title":"Is a \u003cb\u003edog\u003c/b\u003e really a man\u0026#39;s best friend?: \u003cb\u003eDog\u003c/b\u003e Care: Animal Planet","titleNoFormatting":"Is a dog really a man\u0026#39;s best friend?: Dog Care: Animal Planet","originalContextUrl":"http://animals.howstuffworks.com/pets/dog-best-friend.htm","content":"\u003cb\u003eDog\u003c/b\u003e Image Gallery","contentNoFormatting":"Dog Image Gallery","tbUrl":"http://t3.gstatic.com/images?q\u003dtbn:ANd9GcS6VxIzGltwNb2PWMGDfoBvvuof26Kn9i_BrXYRvgWqpnnT3UNfy5DYyC8"}],"cursor":{"resultCount":"3,460,000,000","pages":[{"start":"0","label":1},{"start":"4","label":2},{"start":"8","label":3},{"start":"12","label":4},{"start":"16","label":5},{"start":"20","label":6},{"start":"24","label":7},{"start":"28","label":8}],"estimatedResultCount":"3460000000","currentPageIndex":0,"moreResultsUrl":"http://www.google.com/images?oe\u003dutf8\u0026ie\u003dutf8\u0026source\u003duds\u0026start\u003d0\u0026hl\u003den\u0026q\u003ddog","searchResultTime":"0.07"}}, "responseDetails": null, "responseStatus": 200}
instead of doing a manual url encoding of your url like you do:
NSString *google = [NSString stringWithFormat:#"%#",[[NSUserDefaults standardUserDefaults]objectForKey:#"string"]];
NSString *newGoogle = [google stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSString *fullGoogle = [NSString stringWithFormat:#"https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=%#",newGoogle];
NSURL * url = [NSURL URLWithString:fullGoogle];
NSURLRequest * request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
Try the method:
- (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding
which does a more accurate encoding of the url:
NSString *google = [NSString stringWithFormat:#"%#",[[NSUserDefaults standardUserDefaults]objectForKey:#"string"]];
NSString *fullGoogle = [NSString stringWithFormat:#"https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=%#",google];
NSString * urlEncoded = [fullGoogle stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL * url = [NSURL URLWithString:urlEncoded];
NSURLRequest * request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
Maybe this is your problem, hope it helps!
You need this in connectionDidFinish
NSError* error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
NSDictionary *test = [json objectForKey:#"responseData"];
NSDictionary *closer = [test objectForKey:#"results"];
NSArray *closest = [closer valueForKey:#"url"];

error in uploading photo on facebook wall using graph API

I am going to work on iphone app which upload the photos on facebook wall.
I am using this code
here
- (void)rateTapped:(id)sender {
NSString *likeString;
NSString *filePath = nil;
if (_imageView.image == [UIImage imageNamed:#"angelina.jpg"]) {
filePath = [[NSBundle mainBundle] pathForResource:#"angelina" ofType:#"jpg"];
likeString = #"babe";
} else if (_imageView.image == [UIImage imageNamed:#"depp.jpg"]) {
filePath = [[NSBundle mainBundle] pathForResource:#"depp" ofType:#"jpg"];
likeString = #"dude";
} else if (_imageView.image == [UIImage imageNamed:#"maltese.jpg"]) {
filePath = [[NSBundle mainBundle] pathForResource:#"maltese" ofType:#"jpg"];
likeString = #"puppy";
}
if (filePath == nil) return;
NSString *adjectiveString;
if (_segControl.selectedSegmentIndex == 0) {
adjectiveString = #"cute";
} else {
adjectiveString = #"ugly";
}
NSString *message = [NSString stringWithFormat:#"I think this is a %# %#!", adjectiveString, likeString];
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/me/photos"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request addFile:filePath forKey:#"file"];
//[request setFile:filePath withFileName:#"myphoto.jpg" andContentType:#"image/jpeg" forKey:#"photo"];
[request setPostValue:message forKey:#"message"];
[request setPostValue:_accessToken forKey:#"access_token"];
[request setDidFinishSelector:#selector(sendToPhotosFinished:)];
[request setDelegate:self];
[request startAsynchronous];
}
here i got Photo id is: (null)
- (void)sendToPhotosFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
NSMutableDictionary *responseJSON = [responseString JSONValue];
NSString *photoId = [responseJSON objectForKey:#"id"];
NSLog(#"Photo id is: %#", photoId);
NSString *urlString = [NSString stringWithFormat:#"https://graph.facebook.com/%#?access_token=%#", photoId, [_accessToken stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *newRequest = [ASIHTTPRequest requestWithURL:url];
[newRequest setDidFinishSelector:#selector(getFacebookPhotoFinished:)];
[newRequest setDelegate:self];
[newRequest startAsynchronous];
}
- (void)getFacebookProfileFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
NSLog(#"Got Facebook Profile: %#", responseString);
NSString *likesString;
NSMutableDictionary *responseJSON = [responseString JSONValue];
NSArray *interestedIn = [responseJSON objectForKey:#"interested_in"];
if (interestedIn != nil) {
NSString *firstInterest = [interestedIn objectAtIndex:0];
if ([firstInterest compare:#"male"] == 0) {
[_imageView setImage:[UIImage imageNamed:#"depp.jpg"]];
likesString = #"dudes";
} else if ([firstInterest compare:#"female"] == 0) {
[_imageView setImage:[UIImage imageNamed:#"angelina.jpg"]];
likesString = #"babes";
}
} else {
[_imageView setImage:[UIImage imageNamed:#"maltese.jpg"]];
likesString = #"puppies";
}
NSString *username;
NSString *firstName = [responseJSON objectForKey:#"first_name"];
NSString *lastName = [responseJSON objectForKey:#"last_name"];
if (firstName && lastName) {
username = [NSString stringWithFormat:#"%# %#", firstName, lastName];
} else {
username = #"mysterious user";
}
_textView.text = [NSString stringWithFormat:#"Hi %#! I noticed you like %#, so tell me if you think this pic is hot or not!",
username, likesString];
[self refresh];
}
But here am suffered from following error
here in Console i got an error : Got Facebook Photo: {"error":{"message":"(#803) Some of the aliases you requested do not exist: (null)","type":"OAuthException"}}
I tried this by changing various App ID but my problem doesn't solve.
Anyone help me to achieve this.........
Thanks In advance...
You try like this,
NSData *imagedata = UIImageJPEGRepresentation(urPhoto, 10);
[newRequest setPostValue:imagedata forKey:#"data"];
or add image like this,
[newRequest setPostValue:link forKey:#"data"];

Uploading Video with iPhone

Is it possible to upload video to a server? I know that images are possible.
If someone can just point me in the right direction that would be awesome.
Thanks
Edited Aug 2015
This answer is now seriously out of date. At the time of writing there weren't to many options and videos were relatively small in size.
If you are looking at doing this now, I would use AFNetworking which makes this much simpler. It will stream the upload from file rather than holding it all in memory, and also supports the new Apple background upload Task.
Docs here: https://github.com/AFNetworking/AFNetworking#creating-an-upload-task
--
Yes this is possible and this is how i went about it.
Implement the following function which runs when the media picker is finished.
- (NSData *)generatePostDataForData:(NSData *)uploadData
{
// Generate the post header:
NSString *post = [NSString stringWithCString:"--AaB03x\r\nContent-Disposition: form-data; name=\"upload[file]\"; filename=\"somefile\"\r\nContent-Type: application/octet-stream\r\nContent-Transfer-Encoding: binary\r\n\r\n" encoding:NSASCIIStringEncoding];
// Get the post header int ASCII format:
NSData *postHeaderData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Generate the mutable data variable:
NSMutableData *postData = [[NSMutableData alloc] initWithLength:[postHeaderData length] ];
[postData setData:postHeaderData];
// Add the image:
[postData appendData: uploadData];
// Add the closing boundry:
[postData appendData: [#"\r\n--AaB03x--" dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
// Return the post data:
return postData;
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
//assign the mediatype to a string
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
//check the media type string so we can determine if its a video
if ([mediaType isEqualToString:#"public.movie"]){
NSLog(#"got a movie");
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSData *webData = [NSData dataWithContentsOfURL:videoURL];
[self post:webData];
[webData release];
}
for the post function i had something like this which i got from somewhere else (sorry i dont know where i found it):
- (void)post:(NSData *)fileData
{
NSLog(#"POSTING");
// Generate the postdata:
NSData *postData = [self generatePostDataForData: fileData];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
// Setup the request:
NSMutableURLRequest *uploadRequest = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.example.com:3000/"] cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval: 30 ] autorelease];
[uploadRequest setHTTPMethod:#"POST"];
[uploadRequest setValue:postLength forHTTPHeaderField:#"Content-Length"];
[uploadRequest setValue:#"multipart/form-data; boundary=AaB03x" forHTTPHeaderField:#"Content-Type"];
[uploadRequest setHTTPBody:postData];
// Execute the reqest:
NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:uploadRequest delegate:self];
if (conn)
{
// Connection succeeded (even if a 404 or other non-200 range was returned).
NSLog(#"sucess");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Got Server Response" message:#"Success" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
else
{
// Connection failed (cannot reach server).
NSLog(#"fail");
}
}
The above snippet builds the http post request and submits it. You will need to modify it if you want decent error handling and consider using a library that allows async upload (theres one on github)
Also Notice the port :3000 on the server url above, I found it easy for bug testing to start a rails server on its default port 3000 in development mode so i could see the request parameters for debugging purposes
Hope this helps
Since iOS8 there is no need to use 3rd party libraries and you can stream video directly from the file which solves crucial OUT OF MEMORY ERROR when you try to upload bigger videos while loading them from file:
// If video was returned by UIImagePicker ...
NSURL *videoUrl = [_videoDictionary objectForKey:UIImagePickerControllerMediaURL];
NSMutableURLRequest *request =[[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:VIDEO_UPLOAD_LINK]];
[request addValue:#"video" forHTTPHeaderField: #"Content-Type"];
[request setHTTPMethod:#"POST"];
NSInputStream *inputStream = [[NSInputStream alloc] initWithFileAtPath:[videoUrl path]];
[request setHTTPBodyStream:inputStream];
self.uploadConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
iOS7 also offers great NSURLSeession / NSURLSessionUploadTask combo solution, which not only let's you stream directly from the file, but can also delegate task to the iOS process, which will let upload to finish even when your app is closed.
It requires a bit more coding and I have no time to write it all here (you can Google it).
Here are the most crucial parts:
Confugure audio session in background support:
-(NSURLSession *)urlSession{
if (!_urlSession) {
NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
NSString *bundleId = infoDict[#"CFBundleIdentifier"];
NSString *label = [NSString stringWithFormat:#"ATLoggerUploadManager_%#", bundleId];
NSURLSessionConfiguration *conf = (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) ? [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:label] : [NSURLSessionConfiguration backgroundSessionConfiguration:label];
conf.allowsCellularAccess = NO;
_urlSession = [NSURLSession sessionWithConfiguration:conf delegate:self delegateQueue:self.urlSessionQueue];
_urlSession.sessionDescription = #"Upload log files";
}
return _urlSession;
}
Upload task method:
-(NSURLSessionUploadTask *)uploadTaskForFilePath:(NSString *)filePath session:(NSURLSession *)session{
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
// Consruct request:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"POST"];
NSString *finalUrlString = [self.uploadURL absoluteString];
if (self.uploadUserId) {
[request setValue:self.uploadUserId forHTTPHeaderField:#"X-User-Id"];
finalUrlString = [finalUrlString stringByAppendingFormat:#"?id=%#", self.uploadUserId];
}
[request setURL:[NSURL URLWithString:finalUrlString]];
/*
It looks like this (it only works if you quote the filename):
Content-Disposition: attachment; filename="fname.ext"
*/
NSString *cdh = [NSString stringWithFormat:#"attachment; filename=\"%#\"", [filePath lastPathComponent]];
[request setValue:cdh forHTTPHeaderField:#"Content-Disposition"];
error = nil;
unsigned long fileSize = [[fm attributesOfItemAtPath:filePath error:&error] fileSize];
if (!error) {
NSString *sizeInBytesAsString = [NSString stringWithFormat:#"%lu", fileSize];
[request setValue:sizeInBytesAsString forHTTPHeaderField:#"X-Content-Length"];
}
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileUrl];
uploadTask.taskDescription = filePath;
return uploadTask;
}
Upload function:
[self.urlSession getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
NSMutableDictionary *tasks = [NSMutableDictionary new];
int resumed_running_count = 0;
int resumed_not_running_count = 0;
int new_count = 0;
// 1/2. Resume scheduled tasks:
for(NSURLSessionUploadTask *task in uploadTasks) {
//MILogInfo(#"Restored upload task %zu for %#", (unsigned long)task.taskIdentifier, task.originalRequest.URL);
if (task.taskDescription) {
[tasks setObject:task forKey:task.taskDescription];
}
BOOL isRunning = (task.state == NSURLSessionTaskStateRunning);
if (!isRunning) {
resumed_not_running_count++;
}else{
resumed_running_count++;
}
[task resume];
}
// 2/2. Add tasks / files not scheduled yet:
NSString *uploadFilePath = nil;
// already uploading:
if (![tasks valueForKey:uploadFilePath]) {
NSURLSessionUploadTask *uploadTask = [self uploadTaskForFilePath:uploadFilePath session:_urlSession];
new_count++;
[uploadTask resume];
}
}];
Background session requires UIApplecation delegate (AppDelegate callback implemented:
(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler
{
NSLog(#"Background URL session needs events handled: %#", identifier);
completionHandler();
}
Have a look at the UIImagePickerController.
As of 3.0 you can allow the choose to shoot a video or pick an existing video. According to the docs you're limited to 10min max on the movie though:
http://developer.apple.com/IPhone/library/documentation/UIKit/Reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html
NSURL *urlvideo = [info objectForKey:UIImagePickerControllerMediaURL];
NSString *urlString=[urlvideo path];
NSLog(#"urlString=%#",urlString);
NSString *str = [NSString stringWithFormat:#"you url of server"];
NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setFile:urlString forKey:#"key foruploadingFile"];
[request setRequestMethod:#"POST"];
[request setDelegate:self];
[request startSynchronous];
NSLog(#"responseStatusCode %i",[request responseStatusCode]);
NSLog(#"responseStatusCode %#",[request responseString]);