getting access token with OAuth - iphone

I am trying to get around this OAuth issue of getting an access token from Instapaper, it says in their site that they don't there is no request-token/authorize workflow and they said this is pretty similar to what twitter does, so here's what I did:
- (void)getXAuthAccessToken
{
OAConsumer *consumer = [[[OAConsumer alloc] initWithKey:CONSUMER_KEY secret:CONSUMER_SECRET] autorelease];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:INSTAPAPER_CLIENT_OAUTH_URL]
consumer:consumer
token:nil // xAuth needs no request token?
realm:nil // our service provider doesn't specify a realm
signatureProvider:nil]; // use the default method, HMAC-SHA1
[request setHTTPMethod:#"POST"];
[request setParameters:[NSArray arrayWithObjects:
[OARequestParameter requestParameterWithName:#"x_auth_mode" value:#"client_auth"],
[OARequestParameter requestParameterWithName:#"x_auth_username" value:self.username],
[OARequestParameter requestParameterWithName:#"x_auth_password" value:self.password],
nil]];
[request prepare];
AFHTTPRequestOperation *requestOAuth = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[requestOAuth setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject){
NSLog(#"RESPONSE OBJECT IS %#", responseObject);
}failure:^(AFHTTPRequestOperation *operation, NSError *error){
NSLog(#"ERROR IS %#", error);
}];
[requestOAuth start];
}
Any idea why this is constantly giving me a 401?
So turns out I'd have to call prepare on this request first. But then I can't read the responseData back as what I see it now just binaries.. how can I convert this to a human readable?
EDIT:
Set parameter puts the params in the header:
- (void)setParameters:(NSArray *)parameters
{
NSMutableString *encodedParameterPairs = [NSMutableString stringWithCapacity:256];
int position = 1;
for (OARequestParameter *requestParameter in parameters)
{
[encodedParameterPairs appendString:[requestParameter URLEncodedNameValuePair]];
if (position < [parameters count])
[encodedParameterPairs appendString:#"&"];
position++;
}
if ([[self HTTPMethod] isEqualToString:#"GET"] || [[self HTTPMethod] isEqualToString:#"DELETE"])
[self setURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#?%#", [[self URL] URLStringWithoutQuery], encodedParameterPairs]]];
else
{
// POST, PUT
NSData *postData = [encodedParameterPairs dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
[self setHTTPBody:postData];
[self setValue:[NSString stringWithFormat:#"%d", [postData length]] forHTTPHeaderField:#"Content-Length"];
[self setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
}
}

After reading the Instapaper API docs, it looks like you need to provide a token in the request.
the page is here: http://www.instapaper.com/main/request_oauth_consumer_token

Related

Trouble in sending data to server in ios

I am creating ios and android application which include chatting mechanisum.
I got problem in ios application when I am sending message to server. Sometime message send by ios device get repeated entry in server database. It happen rearly.
I am using ASIFormDataRequest class for communicating with server in ios.
My android app also using same API for communicating with server. Android app works properly
Code for sending message in ios is as follow.
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:urlString];
[request setRequestMethod:#"POST"];
for (NSString* key in dictionaryWithValue) {
[request setPostValue:[dictionaryWithValue objectForKey:key] forKey:key];
}
[request setTimeOutSeconds:60];
[request setDelegate:self];
[request setShouldContinueWhenAppEntersBackground:YES];
request.shouldAttemptPersistentConnection = NO;
[request startSynchronous];
Here dictionaryWithValue is NSDictonary which contain data in key value pair.
Is there in anything getting wrong in code?
Also in ios application, image is not uploading to server. it get connection time out.
For uploading image i have used following code
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setDelegate:self];
[request setRequestMethod:#"POST"];
[request setTimeOutSeconds:120];
[request setShouldContinueWhenAppEntersBackground:YES];
[request setUploadProgressDelegate:self];
[request setShouldAttemptPersistentConnection:YES];
[request setData:[parametersPOST objectAtIndex:2] withFileName:#"UserAvatarFile.png" andContentType:#"image/png" forKey:KEYAvatar];
[request startSynchronous];
NSString *fileName = [parametersPOST objectAtIndex:1];
[request setData:[parametersPOST objectAtIndex:2] withFileName:fileName andContentType:#"image/jpg" forKey:KEYAvatar];
[request setPostValue:[parametersPOST objectAtIndex:2] forKey:#"avatar"];
[request addPostValue:[parametersPOST objectAtIndex:2] forKey:#"avatar"];
[request setPostValue:[parametersPOST objectAtIndex:0] forKey:#"userid"];
[request setPostValue:fileName forKey:#"name"];
[request setPostValue:[parametersPOST objectAtIndex:3] forKey:#"token"];
[request startSynchronous];
Here parametersPOST is NSArray which contain data which i have to send to server.
+(NSDictionary *)getParsedDictonaryforUrlString:(NSString *)urlString withData:(NSData *)postData
{
NSString *newURL = urlString;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:newURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
[request setHTTPBody: postData];
// get response
NSHTTPURLResponse *urlResponse = nil;
NSError *error = [[NSError alloc] init];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&urlResponse
error:&error];
if (responseData == nil)
{
// Check for problems
if (responseData != nil)
{
}
}
else
{
// Data was received.. continue processing
NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response code: %d", [urlResponse statusCode]);
if ([urlResponse statusCode] >=200 && [urlResponse statusCode] <300)
{
NSLog(#"Response ==> %#", result);
NSError *parseError = nil;
NSDictionary *xmlDictionary = [XMLReader dictionaryForXMLString:result error:parseError];
return xmlDictionary;
}
}
return nil;
}
This method may help to you

How to authenticate id password in Gdata video upload to you tube

To upload vedio on you tube i am using Gdata sample code.
Its working fine as it is. But in my application I need to authenticate username and password of user before user try to upload video.
Can I do it with Gdata service ?
Thanks for any help.
Below is method for client login in Youtube:
- (BOOL)login:(NSString *)strusername password:(NSString *)strpassword
{
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:#"https://www.google.com/accounts/ClientLogin"]];
NSString *params = [[NSString alloc] initWithFormat:#"Email=%#&Passwd=%#&service=youtube&source=&continue=http://www.google.com/",username,password];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
[params release];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-type"];
NSHTTPURLResponse *response;
NSError *error;
[request setTimeoutInterval:120];
NSData *replyData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *replyString = [[[NSString alloc] initWithData:replyData encoding:NSUTF8StringEncoding] autorelease];
if([replyString rangeOfString:#"Auth="].location!=NSNotFound)
{
NSString *authToken=[[replyString componentsSeparatedByString:#"Auth="] objectAtIndex:1];
NSLog(#"Auth : %#",authToken);
return YES;
}
else
{
return NO;
}
}

AFNetworking POST to REST webservice

Brief backstory, our previous developer used ASIHTTPRequest to make POST requests and retrieve data from our webservice. For reasons unknown this portion of our app stopped working. Seemed like good enough time to future proof and go with AFNetworking. REST webservice runs on the CakePHP framework.
In short I am not receiving the request response string using AFNetworking.
I know the webservice works because I am able to successfully post data and receive the proper response using curl:
curl -d "data[Model][field0]=field0value&data[Model][field1]=field1value" https://example.com/api/class/function.plist
Per the previous developer's instructions I came up with the following.
#import "AFHTTPRequestOperation.h"
…
- (IBAction)loginButtonPressed {
NSURL *url = [NSURL URLWithString:#"https://example.com/api/class/function.plist"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:[usernameTextField text] forHTTPHeaderField:#"data[User][email]"];
[request setValue:[passwordTextField text] forHTTPHeaderField:#"data[User][password]"];
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc] initWithRequest:request] autorelease];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"operation hasAcceptableStatusCode: %d", [operation.response statusCode]);
NSLog(#"response string: %# ", operation.responseString);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", operation.responseString);
}];
[operation start];
}
output:
operation hasAcceptableStatusCode: 200
response string: a blank plist file
attempted solution 1:
AFNetworking Post Request
the proposed solution uses a function of AFHTTPRequestOperation called operationWithRequest. However, when I attempt to use said solution I get a warning "Class method '+operationWithRequest:completion:' not found (return type defaults to 'id'"
attempted solution 2: NSURLConnection. output: I'm able to print the success log messaged but not the response string.
*update - returns blank plist.
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *httpBodyData = #"data[User][email]=username#example.com&data[User][password]=awesomepassword";
[httpBodyData dataUsingEncoding:NSUTF8StringEncoding];
[req setHTTPMethod:#"POST"];
[req setHTTPBody:[NSData dataWithContentsOfFile:httpBodyData]];
NSHTTPURLResponse __autoreleasing *response;
NSError __autoreleasing *error;
[NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
// *update - returns blank plist
NSData *responseData = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"responseData %#",str);
if (error == nil && response.statusCode == 200) {
// Process response
NSLog(#"success");//returns success code of 200 but blank
NSLog(#"resp %#", response );
} else {
// Process error
NSLog(#"error");
}
These are the essential (stripping out conditions I've made for my own use) lines that ended up satisfying my request to the web service. Thanks for the suggestions #8vius and #mattt !
- (IBAction)loginButtonPressed {
NSURL *baseURL = [NSURL URLWithString:#"https://www.example.com/api/class"];
//build normal NSMutableURLRequest objects
//make sure to setHTTPMethod to "POST".
//from https://github.com/AFNetworking/AFNetworking
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
[httpClient defaultValueForHeader:#"Accept"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
[usernameTextField text], kUsernameField,
[passwordTextField text], kPasswordField,
nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"https://www.example.com/api/class/function" parameters:params];
//Add your request object to an AFHTTPRequestOperation
AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc]
initWithRequest:request] autorelease];
//"Why don't I get JSON / XML / Property List in my HTTP client callbacks?"
//see: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ
//mattt's suggestion http://stackoverflow.com/a/9931815/1004227 -
//-still didn't prevent me from receiving plist data
//[httpClient registerHTTPOperationClass:
// [AFPropertyListParameterEncoding class]];
[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
[operation setCompletionBlockWithSuccess:
^(AFHTTPRequestOperation *operation,
id responseObject) {
NSString *response = [operation responseString];
NSLog(#"response: [%#]",response);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", [operation error]);
}];
//call start on your request operation
[operation start];
[httpClient release];
}
Use AFHTTPClient -postPath:parameters:success:failure:, passing your parameters (nested dictionaries/arrays are fine). If you're expecting a plist back, be sure to have the client register AFPropertyListRequestOperation.
In any case, setValue:forHTTPHeaderField: is not what you want here. HTTP headers are for specifying information about the request itself; data is part of the request body. AFHTTPClient automatically converts parameters into either a query string for GET requests or an HTTP body for POST, et al.

How to send a Get request in iOS?

I am making a library to get response from a particular URL with specified data and method type. For this, I am making a request with url. But when I set its method type, it shows an exception of unrecognized selector send in [NSURLRequest setHTTPMethod:]
I am setting it as
[requestObject setHTTPMethod:#"GET"];
Tell me what could be the problem. Also provide me the code if you have.
NSMutableURLRequest *request =
[NSMutableURLRequest requestWithURL:[NSURL
URLWithString:serverAddress]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:10
];
[request setHTTPMethod: #"GET"];
NSError *requestError = nil;
NSURLResponse *urlResponse = nil;
NSData *response1 =
[NSURLConnection sendSynchronousRequest:request
returningResponse:&urlResponse error:&requestError];
NSString *getString = [NSString stringWithFormat:#"parameter=%#",yourvalue];
NSData *getData = [getString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *getLength = [NSString stringWithFormat:#"%d", [getData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:#"https:yoururl"]];
[request setHTTPMethod:#"GET"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:getData];
self.urlConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
NSAssert(self.urlConnection != nil, #"Failure to create URL connection.");
// show in the status bar that network activity is starting
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
Make sure your requestObject is of type NSMutableURLRequest.
Simply call and use:
(void)jsonFetch{
NSURL *url = [NSURL URLWithString:#"http://itunes.apple.com/us/rss/topaudiobooks/limit=10/json"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *data = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSError *erro = nil;
if (data!=nil) {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&erro ];
if (json.count > 0) {
for(int i = 0; i<10 ; i++){
[arr addObject:[[[json[#"feed"][#"entry"] objectAtIndex:i]valueForKeyPath:#"im:image"] objectAtIndex:0][#"label"]];
}
}
}
dispatch_sync(dispatch_get_main_queue(),^{
[table reloadData];
});
}];
[data resume];
}

Sending form data via HTTP Post [Objective C]

I have a form data from an iphone app that needs to send HTTP Post variables to a URL.
The thing is, I've been told not to use setHTTPBody, but am unsure of how else to do it as every example I see uses setHTTPBody; even those that use POST methods.
To make things matters a little more complicated, the URL/webpage requires a submit=true and action=enquiry in the post variables.
Here's what I have so far.
NSString *formContactName = [self contactName];
NSString *formEmail = [self email];
NSString *formPhone = [self phone];
NSString *formComments = [self comments];
// The above data is fine, as explored here.
NSLog(#"formContactName = %#", formContactName);
NSLog(#"formEmail = %#", formEmail);
NSLog(#"formPhone = %#", formPhone);
NSLog(#"formComments = %#", formComments);
// Setup request
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:advertURL]];
[request setHTTPMethod:#"POST"];
// set headers
NSString *contentType = [NSString stringWithFormat:#"text/plain"];
[request addValue:contentType forHTTPHeaderField:#"Content-Type"];
// setup post string
NSMutableString *postString = [[NSMutableString alloc] init];
[postString appendFormat:#"contactname=%#", formContactName];
[postString appendFormat:#"&email=%#", formEmail];
[postString appendFormat:#"&phone=%#", formPhone];
[postString appendFormat:#"&comments=%#", formComments];
[postString appendFormat:#"&submit=yes"];
[postString appendFormat:#"&action=enquiry"];
// I've been told not to use setHTTPBody for post variables, but how else do you do it?
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
// get response
NSHTTPURLResponse *urlResponse = nil;
NSError *error = [[NSError alloc] init];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&urlResponse
error:&error];
NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response code: %d", [urlResponse statusCode]);
if ([urlResponse statusCode] >=200 && [urlResponse statusCode] <300)
{
NSLog(#"Response ==> %#", result);
}
[result release];
[error release];
I always get a 200 result, which is good. But the response back indicates that the Post variables are not getting through.
The response back has a field in it called "enquirysent" and its always blank. If the Post variables are successful, it should return a "1" or true statement.
"enquirysent": ""
Therefore, my question is: How do I force the HTTP-POST variables in the above request?
Thanks.
you can use ASIHTTPRequest to simplify:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:#"Ben" forKey:#"first_name"];
[request setPostValue:#"Copsey" forKey:#"last_name"];
[request setFile:#"/Users/ben/Desktop/ben.jpg" forKey:#"photo"];