ASIHTTPRequest-multiple request - iphone

I am developing an app that will request the profile picture URL of some users from Facebook servers, but I don't know how many users I will have (it might be 2 or it might be 20). Should I use ASIHTTPRequest with a loop and a synchronous request, or the API graph (with Facebook SDK for iOS) with a loop?

Trying using ASINetworkQueue. It will allow you to create a queue of ASIHTTPRequests that can still be started asynchronously. For example
- (void)getImages
{
if(!self.queue)
self.queue = [[[ASINetworkQueue alloc] init] autorelease];
NSArray* urlStringsToRequest = [NSArray arrayWithObjects:#"http://www.example.com/image1.png",#"http://www.example.com/image2.png",nil];
for(NSString* urlString in urlStringsToRequest)
{
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestDone:)];
[request setDidFailSelector:#selector(requestWentWrong:)];
[self.queue addOperation:request];
}
[self.queue go];
}
- (void)requestDone:(ASIHTTPRequest*)req
{
UIImage* image = [UIImage imageWithData:[req responseData]];
[imageArray addObject:image];
}
- (void)requestWentWrong:(ASIHTTPRequest*)req
{
NSLog(#"Request returned an error %#",[req error]);
}

Related

ASIHTTPRequest multiple downloads control like pause, resume

I am using ASIHTTPRequest to download video file from URL in background.
I am displaying the downloads with progress-bar & percentage and I want user can control the downloads like pause & resume.
Below is the code:
-(void)Initiate_Download:(NSString*)urlStr contentID:(NSString*)cid progressBar:(UIProgressView*)progressBar
{
NSLog(#"Initiate_Download for cid:%#",cid);
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:urlStr]];
NSString *fileName = [NSString stringWithFormat:#"%#.mp4",cid];
NSString *destinationPath = [[self VideoDownloadFolderPath]stringByAppendingPathComponent:fileName];
[request setDownloadDestinationPath:destinationPath];
[request setTemporaryFileDownloadPath:[NSString stringWithFormat:#"%#-part",destinationPath]];
[request setDelegate:self];
NSDictionary *rqstDict = [NSDictionary dictionaryWithObjectsAndKeys:cid,#"cid",urlStr,#"url", nil];
[request setUserInfo:rqstDict];
[request setAllowResumeForFileDownloads:YES];
[request startAsynchronous];
}
//Delegate
- (void)requestStarted:(ASIHTTPRequest *)request1
{
//some code
}
- (void)request:(ASIHTTPRequest *)request1 didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
//some code
}
- (void)requestFinished:(ASIHTTPRequest *)request1
{
//some code
}
- (void)requestFailed:(ASIHTTPRequest *)request1
{
//some code
}
You need to save the URL and destination path of the request for each request and to pause the request use code :-
[request Cancel];
and to resume the request you need to create another request with same URL and destination path. For example :-
ASIHTTPRequest *requestToResume = [ASIHTTPRequest requestWithURL:url];
[requestToResume setTemporaryFileDownloadPath:tempfilePath];
[requestToResume setDownloadDestinationPath:filePath];
[requestToResume setDelegate:self];
[requestToResume setDownloadProgressDelegate:self];
[requestToResume setUserInfo:dictInfo];
// This file has part of the download in it already
[requestToResume setAllowResumeForFileDownloads:YES];
[requestToResume setDidFinishSelector:#selector(requestDone:)];
[requestToResume setDidFailSelector:#selector(requestWentWrong:)];
[requestToResume startAsynchronous];
In the above code we get the url of the song from the dictionary which was set as userInfo of the request and now we get these details for resuming the request. When we resume the request the file will be downloaded from the point it was paused, hence it will solve the purpose of resuming the file download.

Specifying HTTP referer in UIWebView

How can we set HTTP referer in embedded UIWebView?
I had gone through this but still not got success.
1. In viewDidLoad, I wrote this code,
[objWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"MY_URL"]]];
Here is my code :
- (BOOL) webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType) navigationType
{
NSDictionary *headers = [request allHTTPHeaderFields];
BOOL hasReferer = [headers objectForKey:#"Referer"]!=nil;
if (hasReferer) {
// .. is this my referer?
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 setHTTPMethod:#"GET"];
[request setValue:#"Referer link" forHTTPHeaderField:#"Referer"];
[objWebView loadRequest:request];
});
});
return NO;
}
}
2. I had tried this also in viewDidLoad
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"MY_URL"]];
[request setValue:#"Referel URL" forHTTPHeaderField:#"Referer"];
[objWebView loadRequest:request];
But doesn't got success yet.
Please help me solve this problem or tell me is there any problem with this code or not?
Hope I presented question clearly.
You can set Default User-Agent using following code
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:#"Safari/528.16", #"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
It is well explained here.
I am not sure what exactly is your situation. But for me, simply just setting baseURL parameter in -loadHTMLString:baseURL:; will automatically add HTTP header Referer as baseURL to all outgoing request under the HTML page.

OAuthConsumer and Twitpic

I'm trying to post images to TwitPic using OAuthConsumer. I keep receiving a 401 "Could not authenticate you (header rejected by twitter)." error.
I am also making use of the Twitter+OAuth library to handle the login and posting regular tweets, and then saving the token and token secret for using with TwitPic.
This is the code I am using the construct the request:
NSURL *twitpicUrl = [NSURL URLWithString:#"http://api.twitpic.com/2/upload.json"];
NSString* realm = #"http://api.twitter.com/";
OAToken* oaToken = [[OAToken alloc] initWithKey:savedToken secret:savedTokenSecret];
OAConsumer* oaConsumer = [[OAConsumer alloc] initWithKey:kOAuthConsumerKey secret:kOAuthConsumerSecret];
OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL:twitpicUrl consumer:oaConsumer
token:oaToken realm:realm signatureProvider:nil] autorelease];
[request prepare];
[request setHTTPMethod:#"POST"];
[request setValue:#"https://api.twitter.com/1/account/verify_credentials.json" forHTTPHeaderField:#"X-Auth-Service-Provider"];
NSString* authorizeHeader = [request valueForHTTPHeaderField:#"Authorization"];
[request setValue:authorizeHeader forHTTPHeaderField:#"X-Verify-Credentials-Authorization"];
And if I print out my headers, this is what I get (excluding the unused Authorization header):
"X-Auth-Service-Provider" = "https://api.twitter.com/1/account/verify_credentials.json";
"X-Verify-Credentials-Authorization" = "OAuth realm=\"http%3A%2F%2Fapi.twitter.com%2F\", oauth_consumer_key=\"JOvwW7mtZUjRXZRInkQI7w\", oauth_token=\"293217559-pD0HL0oE6TZSkU35mPnc7kia325oPDgMfQMTVArK\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"ctmCK35JFwx8qs8lQj0AYB6sUr4%3D\", oauth_timestamp=\"1304580843\", oauth_nonce=\"7EBE3EB0-641A-40EA-A57C-8D071B5E647F\", oauth_version=\"1.0\"";
The error I receive is:
Error: The operation couldn’t be completed. (NSURLErrorDomain error -1012.)
{"errors":[{"code":401,"message":"Could not authenticate you (header rejected by twitter)."}]}
I have excluded some detail here, specifically appending the post data, mainly because I don't think it's relevant to the error. If you think otherwise let me know and I'll update the question.
Can anyone help?
Update: Here is the code that I am now using successfully
In header:
#define kVerifyCredentialsUrl #"https://api.twitter.com/1/account/verify_credentials.json"
#define kTwitPicUrl #"http://api.twitpic.com/2/upload.json"
Implementation:
//prepare the verify credentials header
NSURL* serviceUrl = [NSURL URLWithString:kVerifyCredentialsUrl];
NSString* realm = #"http://api.twitter.com/";
OAToken* token = [[OAToken alloc] initWithKey:tokenKey secret:tokenSecret];
OAConsumer* consumer = [[OAConsumer alloc] initWithKey:kOAuthConsumerKey secret:kOAuthConsumerSecret];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:serviceUrl consumer:consumer token:token realm:realm signatureProvider:nil];
[request setHTTPMethod:#"GET"];
[request prepare];
NSDictionary* headerDictionary = [request allHTTPHeaderFields];
NSString* oAuthHeader = [NSString stringWithString:[headerDictionary valueForKey:#"Authorization"]];
[request release];
request = nil;
//prepare the full request
serviceUrl = [NSURL URLWithString:kTwitPicUrl];
request = [[OAMutableURLRequest alloc] initWithURL:serviceUrl consumer:consumer token:token realm:realm signatureProvider:nil];
[request setHTTPMethod:#"POST"];
[request setValue:kVerifyCredentialsUrl forHTTPHeaderField:#"X-Auth-Service-Provider"];
[request setValue:oAuthHeader forHTTPHeaderField:#"X-Verify-Credentials-Authorization"];
//add the content and start the request
UIImage* imageToUpload = [UIImage imageNamed:#"test.png"];
NSData *data = UIImagePNGRepresentation(imageToUpload);
ASIFormDataRequest *asiRequest = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:kTwitPicUrl]] autorelease];
[asiRequest addRequestHeader:#"X-Auth-Service-Provider" value:kVerifyCredentialsUrl];
[asiRequest addRequestHeader:#"X-Verify-Credentials-Authorization" value:oAuthHeader];
[asiRequest setPostValue:#"Message here" forKey:#"message"];
[asiRequest setPostValue:kTwitPicAPIKey forKey:#"key"];
[asiRequest setData:data forKey:#"media"];
[asiRequest setDidFinishSelector:#selector(requestDone:)];
[asiRequest setDidFailSelector:#selector(requestWentWrong:)];
[asiRequest setDelegate:self];
[asiRequest startAsynchronous];
Try this :
NSURL *serviceURL = [NSURL URLWithString:#"https://api.twitter.com/1/account/verify_credentials.json"];
OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:serviceURL
consumer:consumer_
token:accessToken_
realm:#"http://api.twitter.com/"
signatureProvider:nil];
[oRequest setHTTPMethod:#"GET"];
[oRequest prepare];
NSDictionary * headerDict = [oRequest allHTTPHeaderFields];
NSString * oauthHeader = [NSString stringWithString:[headerDict valueForKey:#"Authorization"]];
[oRequest release];
// Prepare the POST request
oRequest = nil;
serviceURL = nil;
serviceURL = [NSURL URLWithString:#"http://api.twitpic.com/2/upload.json"];
oRequest = [[OAMutableURLRequest alloc] initWithURL:serviceURL
consumer:consumer_
token:accessToken_
realm:#"http://api.twitter.com/"
signatureProvider:nil];
[oRequest setHTTPMethod:#"POST"];
[oRequest setValue:#"https://api.twitter.com/1/account/verify_credentials.json" forHTTPHeaderField:#"X-Auth-Service-Provider"];
[oRequest setValue:oauthHeader forHTTPHeaderField:#"X-Verify-Credentials-Authorization"];
You should also make this change in OAMutableURLRequest.m at the end of the method - (void)prepare:
NSString *oauthHeader = [NSString stringWithFormat:#"OAuth realm=\"%#\", oauth_consumer_key=\"%#\", %#oauth_signature_method=\"%#\", oauth_signature=\"%#\", oauth_timestamp=\"%#\", oauth_nonce=\"%#\", oauth_version=\"1.0\"%#",
[realm URLEncodedString],
[consumer.key URLEncodedString],
oauthToken,
[[signatureProvider name] URLEncodedString],
[signature URLEncodedString],
timestamp,
nonce,
extraParameters];
if(![self valueForHTTPHeaderField:#"X-Verify-Credentials-Authorization"])
[self setValue:oauthHeader forHTTPHeaderField:#"Authorization"];
It may also be a problem with twitter right now.
My code using OAMutableURLRequest like yours, has been working fine for ages, and today I keep getting the 401 error code. Searching twitter you will find more people having this problem recently.
This is what you can read now in the api status page:
We are currently experiencing elevated
error rates. There may be intermittent
issues loading twitter.com and Twitter
clients. We are aware of the problem
and taking action. Thanks for your
patience!
Twitter API Status

How to upload image on Twitter

I want to upload image on Twitter.
please any one help me how we upload image on Twitter.
Please explain or provide code.
The following is to utilize Twitpic.
As said by others you have to start by looking at the API to understand the requests.
You can use Oliver Drobnik's Tutorial : Uploading UIImages to TwitPic which does it from scratch using NSMutableURLRequest
or you can use the asi-http-request which is a CFNetwork wrapper for HTTP requests
NSData *imageData = UIImagePNGRepresentation(imageToPost);
NSURL *twitpicURL = [NSURL URLWithString:#"http://twitpic.com/api/uploadAndPost"];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:twitpicURL] autorelease];
[request setData:imageData forKey:#"media"];
[request setPostValue:#"myUsername" forKey:#"username"];
[request setPostValue:#"myPassword" forKey:#"password"];
[request setPostValue:#"myMessage" forKey:#"message"];
[request setDelegate:self];
[request setDidFinishSelector:#selector(requestDone:)];
[request setDidFailSelector:#selector(requestFailed:)];
[request start];
You should look at the first.. first that way you understand what is happening.
You must use a "twitter-picture-provider" like TwitPic or TweetPhoto. They usually provide their own APIs as far as I know.
Twitter does not host image uploads at the moment. You have to use a third-party service. Yfrog and Twitpic are the two most popular on Twitter.
first import twitter frame work after that u write this code
TWTweetComposeViewControllerCompletionHandler completionHandler =^(TWTweetComposeViewControllerResult result)
{
switch (result) {
case TWTweetComposeViewControllerResultCancelled:
NSLog(#"twitter result:cancelled");
break;
case TWTweetComposeViewControllerResultDone:
NSLog(#"twitter result:sent");
}
[self dismissModalViewControllerAnimated:YES];
};
TWTweetComposeViewController *tvc = [[TWTweetComposeViewController alloc] init];
if(tvc)
{
[self addTweetContentContent:tvc];
tvc.completionHandler = completionHandler;
[self presentModalViewController:tvc animated:YES];
}
the local method is....
-(void)addTweetContentContent:(id)tvc
{
UIImage *image1 = UIGraphicsGetImageFromCurrentImageContext();
NSData *imageData = UIImagePNGRepresentation(image1);
UIImage *picture = [UIImage imageWithData:imageData];
or
UIImage *picture=[UIImage imageNamed:#"a.png"];
[tvc addImage:picture];
NSString *tweetText = #"write your comands";
[tvc setInitialText:tweetText];
}

ASIHTTPRequest - HTTPS

Does ASIHTTPRequest support HTTPS connections? My connection right now works for a HTTP connection and errors if I try a HTTPS Connection. (Goes into requestFailed and gives me a ASIHTTPErrorRequestDomain)
-(void) getData
{
av.hidden = NO;
[av startAnimating];
NSString *urlString = [IP stringByAppendingString:#"Method1"];
NSURL *url = [NSURL URLWithString:urlString];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
NSLog(#"URL = %#",url);
[request setRequestMethod:#"POST"];
[request setPostValue:#"val1" forKey:#"key1"];
[request setPostValue:#"val2" forKey:#"key2"];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
//NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
[self parseData:responseData];
[av stopAnimating];
av.hidden = YES;
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
[av stopAnimating];
av.hidden = YES;
}
Thanks,
Teja
Whoops, sorry, figured it out -
[request setValidatesSecureCertificate:NO] works for reference.
Thanks to these guys - http://www.iphonedevsdk.com/forum/iphone-sdk-development/29417-asihttprequest-library-works-https.html
EDIT: Since this is getting some upvotes, I'd just like to add that this might not be the best approach for valid SSL certificates. The one I was using was a self-signed certificate, so this was fine.