NSURLRequest for JSON w/ credentials - objective-c

NSString *login = #"Web Guest";
NSString *password = #"xxxxx";
NSError *myError = nil;
NSLog(#"CONNECTION: Adding credentials");
NSURLCredential *credential = [NSURLCredential credentialWithUser:login
password:password
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:#"54.225.xxx.xxx"
port:80
protocol:#"http"
realm:#"54.225.xxx.xxx"
authenticationMethod:NSURLAuthenticationMethodDefault];
//Not sure if set up correctly
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"xx.xxx.xxx.xxx/blah"]
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:12];
NSLog(#"CONNECTION: Running request");
//Perform the request
NSURLResponse *response;
NSData *data = [NSURLConnection
sendSynchronousRequest:request
returningResponse:&response
error:&myError];
At this point, I get an error "Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: ' +[NSString
stringWithCString:encoding:]: NULL cString'"
NSString *result = [NSString stringWithCString:[data bytes] encoding:NSUTF8StringEncoding];
NSLog(#"Webserver response: %#", result);
I'm attempting to return some JSON from the web server which requires authorization using basic authentication, but seem to be having some trouble with getting it set up. I'm new to objective-c programming and ios development, but would really appreciate any help! Thanks.

You're not using a scheme in your request URL string: #"xx.xxx.xxx.xxx/blah". You'll need something like #"https://xx.xxx.xxx.xxx/blah", otherwise [NSURL URLWithString:] returns nil.

Related

Obj-C NSURLConnection not working

So i am trying to send data to a webservice via url with a parameter. the code i have is below but it never hits the server. the request and responses are null. What am i doing wrong?
-(void) postData:(NSString *)data{
NSURLResponse* response;
NSError* error = nil;
NSString *urlString = [NSString stringWithFormat:#"http://someaddress.com/api?data=%#", data];
NSURL *lookupURL = [NSURL URLWithString:urlString];
//Create the request.
NSURLRequest *theRequest=[NSURLRequest requestWithURL:lookupURL];
NSData *request = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
NSString *dataString = [[NSString alloc] initWithData:request encoding:NSUTF8StringEncoding];
NSLog(#"-----------------------------");
NSLog(#"Request: %#", theRequest);
NSLog(#"req response: %#", request);
NSLog(#"response: %#", dataString);}
you want to POST some binary data but you do a GET request and try to put the binary into the url. (without encoding it)
sample post:
NSURL *url = [NSURL URLWithString:#"http://server.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = #"POST";
request.HTTPBody = postData;
NSData *respData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
also, note that the synchronous get is bad as it blocks :) use async networking!

Reddit API ios modhash/cookie issue

Im' trying to submit to Reddit via my iOS app. I can login fine and am sent back a modhash and a cookie which I save via NSUserDefaults.
The issue is when I post the data I keep getting "USER_REQUIRED" as the response, even though I have included the modhash in the post and set my session cookie. I have even included the following in my app delegate:
[[NSHTTPCookieStorage sharedHTTPCookieStorage]
setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
But it still doesn't work. Here is my code:
-(void) post {
NSString *modhash2 = [[NSUserDefaults standardUserDefaults]
objectForKey:#"modhash"];
NSString *urlString = [NSString
stringWithFormat:#"https://ssl.reddit.com/api/submit"];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
NSString *contentType = [NSString stringWithFormat:#"application/x-www-form-urlencoded;"];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
[request addValue:redditCookie forHTTPHeaderField:#"Cookie"];
[request setHTTPMethod:#"POST"];
NSString *httpBody = [NSString stringWithFormat
:#" ?uh=%#&kind=link&url=%#&sr=%#&title=%#&r=%#&api_type=json",
modhash2,
#"www.google.com",
#"test",
#"Google.com",
#"test"];
[request setHTTPBody:[httpBody dataUsingEncoding:NSASCIIStringEncoding]];
NSURLResponse* response;
NSError* error = nil;
NSData* result = [NSURLConnection
sendSynchronousRequest:request
returningResponse:&response
error:&error];
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:result
options:NSJSONReadingMutableContainers
error:nil];
NSDictionary *responseJSON = [json valueForKey:#"json"];
NSLog(#"RETURN: %#",responseJSON);
}
Any ideas?

NSURLConnection closes early on GET

I'm working on a method to centralize my URL connections for sending and receiving JSON data from a server. It works with POST, but not GET. I'm using a Google App Engine server and on my computer it'll handle the POST requests and return proper results (and log appropriately), but I get the following error when I try the request with a GET method:
Error Domain=kCFErrorDomainCFNetwork Code=303 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error 303.)" UserInfo=0xd57e400 {NSErrorFailingURLKey=http://localhost:8080/api/login, NSErrorFailingURLStringKey=http://localhost:8080/api/login}
In addition, the GAE dev server shows a "broken pipe" error, indicating that the client closed the connection before the server was finished sending all data.
Here's the method:
/* Connects to a given URL and sends JSON data via HTTP request and returns the result of the request as a dict */
- (id) sendRequestToModule:(NSString*) module ofType:(NSString*) type function:(NSString*) func params:(NSDictionary*) params {
NSString *str_params = [NSDictionary dictionaryWithObjectsAndKeys:func, #"function", params, #"params", nil];
NSString *str_url = [NSString stringWithFormat:#"%#%#", lds_url, module];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:str_url]];
NSData *data = [[NSString stringWithFormat:#"action=%#", [str_params JSONString]] dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPMethod:type];
[request setHTTPBody:data];
[request setValue:[NSString stringWithFormat:#"%d", [data length]] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSError *error = nil;
NSURLResponse *response = nil;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Error: %#", error);
NSLog(#"Result: %#", [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]);
return [result objectFromJSONData];
}
A sample call would be:
NSDictionary *response = [fetcher sendRequestToModule:#"login" ofType:#"GET" function:#"validate_email" params:dict];
Again, this works with a POST but not a GET. How can I fix this?
In my case i was not calling [request setHTTPMethod: #"POST" ]
I think the root cause is you have an invalid URL.
JSON encoding will include things like '{', '}', '[' and ']'. All of these need to be URL encoded before being added to a URL.
NSString *query = [NSString stringWithFormat:#"?action=%#", [str_params JSONString]];
query = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", str_url, query]];
To directly answer your question:
According to CFNetwork Error Codes Reference the error is kCFErrorHTTPParseFailure. This means the client failed to correctly parse the HTTP response.
The reason why is that a GET doesn't include a body. Why would you want to submit JSON in a GET anyways?
If the target api returns data only you pass it in the url params.
If you want to send data and "get" a response use a post and examine the body on return.
Sample Post:
NSError *error;
NSString *urlString = [[NSString alloc] initWithFormat:#"http://%#:%#/XXXX/MVC Controller Method/%#",self.ServerName, self.Port, sessionId ];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding ]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
// hydrate the remote object
NSString *returnString = [rdc JSONRepresentation];
NSData *s10 = [returnString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:s10];
NSURLResponse *theResponse = [[NSURLResponse alloc] init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&error];
NSString *message = [[NSString alloc] initWithFormat: #"nothing"];
if (error) {
message = [[NSString alloc] initWithFormat:#"Error: %#", error];
} else {
message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
NSLog(#"%#", message);
return message;

GTM OAuth Twitter update error

I'm having a posting issue with the gtm oauth toolbox. I've been trying to send a tweet to twitter but I keep getting authorization errors. Right now I'm receiving the following error with the code below "POST error: Error Domain=com.google.HTTPStatus Code=401 "The operation couldn’t be completed. (com.google.HTTPStatus error 401.)"
NSString *body = [NSString stringWithFormat: #"status=thisisatest"];
NSString *urlStr = #"http://api.twitter.com/1/statuses/update.json";
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody: [body dataUsingEncoding:NSUTF8StringEncoding]];
GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher
fetcherWithRequest:request];
[myFetcher setAuthorizer: mAuth];
[myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData,
NSError *error)
{
if (error != nil)
{
NSLog(#"POST error: %#", error);
}
else
{
NSDictionary *results = [[[[NSString alloc] initWithData:
retrievedData encoding:NSUTF8StringEncoding] autorelease] JSONValue];
NSLog(#"POST Successful: #%# # %#", [results objectForKey:
#"id"], [results objectForKey: #"created_at"]);
}
}];
What am I doing wrong here? The token is already stored in the keychain. Do I need to retrieve the keychain token or does gtm sign the request automatically?
Ok, I found out the issue. I missed a place in one of the GTM .m files for the consumer key. That's what I get for rushing things. :-)

URL GET/POST Request objective-c

I have to send get or post request to localhost:
<?php
if(#$_GET['option']) {
echo "You said \"{$_GET['option']}\"";
}else if(#$_POST['option']) {
echo "You said \"{$_POST['option']}\"";
}
?>
ive using this code:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://localhost/wsh/index.php?option=Hello"]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *get = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
it works, but one time in code. if ill do it another one time, application has terminate.
Im try to use ASIFormDataRequest:
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:#"http://localhost/wsh/index.php"] autorelease];
[request setPostValue:#"option" forKey:#"myFormField1"];
[request start];
NSError *error = [request error];
if (!error) {
NSString *response = [request responseString];
NSLog(response);
}else{
NSLog(#"error");
}
it says:
2010-01-07 13:20:34.964 WSH[3351:903] -[NSCFString absoluteURL]: unrecognized selector sent to instance 0x160f8
2010-01-07 13:20:34.966 WSH[3351:903] error
sry for my english
You are using a plain NSString literal where an NSURL object is expected: [...] initWithURL:#"http://localhost/wsh/index.php" [...]
Change this to initWithURL:[NSURL URLWithString:#"http://localhost/wsh/index.php"].
I wonder if also you should switch the value and key for the post values, ie change the line
[request setPostValue:#"option" forKey:#"myFormField1"];
to
[request setPostValue:#"myFormField1" forKey:#"option"];