I have a file path like so:
smb://servername/Folder/Folder/FTP/ANC/ANC.pdf
and I am trying to read this file:
NSURL *url = [NSURL fileURLWithPath:#"smb:///servername/Folder/Folder/FTP/ANC/ANC.pdf"];
NSData *urlData = [NSData dataWithContentsOfURL:url];
but urlData is returning nil. Why? The path is 100% correct.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Tutorials for using HTTP POST and GET on the iPhone in Objective-C
Is there away to create an NSArray with the correct information like id = 1, name = #"John", score = 100 then send it and receive a response from the server?
Maybe display it inside an NSLog();
Can anyone help answer this question by linking me to a good tutorial, I don't want to use ASIHTTPRequest either. I know it would be much simpler but if there is away to do something without using a load of prewritten code id rather learn how to make something using the functionality the the foundation framework offers before going off using someone elses classes.
What you're looking for is NSMutableURLRequest and the addValue:forHTTPHeaderField method.
Create the request with the URL you wish to communicate with. Load the values you wish to transmit into the header or into the HTTPBody, set your HTTPMethod and then use a NSURLConnection method to send and receive the response.
As for an array with the information you could simply enumerate through the array and add the values to the HTTPHeaderFields. It really depends on what the server is setup to receive.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html#//apple_ref/doc/uid/10000165i
Has more information.
NSString *urlString = #"http://yoururl.com";
NSURL *url = [NSUL URLWithString:urlString];
NSMutalbeURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSDictionary *headerInformation = [NSDictionary dictionaryWithObjectsAndKeys:#"1",#"id",#"John",#"name",#"100",#"score", nil];
for (NSString *key in [headerInformation allKeys])
{
[request addValue:[dict valueForKey:key] forHTTPHeaderField:key];
}
NSHTTPURLResponse *response = nil;
NSError *error = nil;
// this will perform a synchronous GET operation passing the values you specified in the header (typically you want asynchrounous, but for simplicity of answering the question it works)
NSData *responseData = [NSURLConnection sendSynchronousRequest:request reuturningResponse:&response error:&error];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response: %#", responseString);
[responseString release];
It might be easier to just use NSData to send a url request and store the response then to reinvent the wheel. Here is some code similar to something in my production project:
+ (NSData *)getProfiles {
NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:#"token"];
// Create string of the URL
NSString *serviceURL = [NSString stringWithFormat:#"http://www.myurlhere.com/getProfiles.php?token=%#", token];
NSLog(#"Service URL : %#", serviceURL);
// Create a NSURL out of the string created earlier. Use NSASCIIStringEncoding to make it properly URL encoded (replaces " " with "+", etc)
NSURL *URL = [NSURL URLWithString:[serviceURL stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
// Request the url and store the response into NSData
NSData *data = [NSData dataWithContentsOfURL:URL];
if (!data) {
return nil;
}
// Since I know the response will be 100% strings, convert the NSData to NSString
NSString *response = [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
// Test response and return a string that an XML Parser can parse
if (![response isEqualToString:#"UNAUTHORIZED"]) {
response = [response stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
data = [response dataUsingEncoding:NSASCIIStringEncoding];
return data;
} else {
return nil;
}
}
NSLog output:
[Line: 476] +[WebSupport getProfiles]: Service URL : http://www.myurlhere.com/getProfiles.php?token=abcdef0123456789abcdef0123456789
I've read through the questions and answers related to TouchJSON serialization and I'm still not getting it to work.
I create an NSDictionary with sample data and used the JSONTouch serializer to convert the NSDictionary to JSON. However, when I log the NSData object 'theJSONData', it gives me this as a result:
<7b223131 31353535 34343434 223a2250
...
65227d>
Additionally, when I send this 'theJSONData' data to the web service (that's expecting JSON) this is what I get back:
2011-07-31 18:48:46.572 Street Lights[7169:207] Serialization Error: (null)
2011-07-31 18:48:46.804 Street Lights[7169:207] returnData: (null)
2011-07-31 18:48:46.805 Street Lights[7169:207] Error: Error Domain=kJSONScannerErrorDomain Code=-201 "Could not scan array. Array not started by a '[' character." UserInfo=0x4d51ab0 {snippet=!HERE>!?xml version="1.0" , location=0, NSLocalizedDescription=Could not scan array. Array not started by a '[' character., character=0, line=0}
What am I doing wrong? Does the JSON NSData object 'theJSONData' need to be converted to another type before I send it to the web service? Is there another step I'm missing?
// Create the dictionary
NSDictionary *outage = [[NSDictionary alloc] initWithObjectsAndKeys:
#"YCoord", #"12678967.543233",
#"XCoord", #"12678967.543233",
#"StreetLightID", #"666",
#"StreetLightCondition", #"Let's just say 'BAD'",
#"PhoneNumber", #"1115554444",
#"LastName", #"Smith",
#"Image",#"",
#"FirstName", #"Dawn",
#"Comments", #"Pole knocked down",
nil];
NSError *error = NULL;
// Serialize the data
NSData *theJSONData = [[CJSONSerializer serializer] serializeDictionary:outage error:&error];
NSLog(#"theJSONData: %#", theJSONData);
NSLog(#"Serialization Error: %#", error);
// Set up the request and send it
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: #"http://24.52.35.127:81/StreetLight/StreetlightService/CreateStreetLightOutage"]];
[request setHTTPMethod: #"POST"];
[request setHTTPBody: theJSONData];
// Deserialize the response
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error:&error];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSData *theReturnData = [returnString dataUsingEncoding:NSUTF8StringEncoding];
id theObject = [[CJSONDeserializer deserializer] deserializeAsArray:theReturnData error:&error];
NSLog(#"returnData: %#",theObject);
NSLog(#"Error: %#", error);
Thanks for everyone's help. I ended up using Fiddler to track what needed to be sent to the service in JSON and then saw I hadn't been formatting the header correctly. Here is the code that ended up working for me.
// Create the NSDictionary
NSDictionary *outage = [[NSDictionary alloc] initWithObjectsAndKeys:
#"12.543233",#"YCoord",
#"12.543233",#"XCoord",
#"111",#"StreetLightID",
#"Dented pole",#"StreetLightCondition",
#"1115554444",#"PhoneNumber",
#"Black",#"LastName",
[NSNull null],#"Image",
#"White",#"FirstName",
#"Hit by a car",#"Comments",
nil];
// Serialize the data
NSError *error = NULL;
NSData *theJSONData = [[CJSONSerializer serializer] serializeDictionary:outage error:&error];
NSLog(#"Serialization Error: %#", error);
// Change the data back to a string
NSString* theStringObject = [[NSString alloc] initWithData:theJSONData encoding:NSUTF8StringEncoding];
// Determine the length of the data
NSData *requestData = [NSData dataWithBytes: [theStringObject UTF8String] length: [theStringObject length]];
NSString* requestDataLengthString = [[NSString alloc] initWithFormat:#"%d", [requestData length]];
// Create request to send to web service
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: #"http://11.22.33.444:55/StreetLight/StreetlightService/CreateStreetLightOutage"]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:requestData];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:requestDataLengthString forHTTPHeaderField:#"Content-Length"];
[request setTimeoutInterval:30.0];
// Deserialize the response
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error:&error];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSData *theReturnData = [returnString dataUsingEncoding:NSUTF8StringEncoding];
id theObject = [[CJSONDeserializer deserializer] deserializeAsArray:theReturnData error:&error];
NSLog(#"returnData: %#",returnString);
NSLog(#"Error: %#", error);
For one thing, you've got your objects and keys reversed in the NSDictionary.
I don't know enough about TouchJSON to help with that part of the code.
I am having similar issues in parsing a goodle v3 api response. Still no closer to resolving my issue, but one thing I have found that may be helpful to you is if you are using the deserializerAsArray then the JSON response must be enclose in "[" and "]" and if you are deserializerAsDictionary then the JSON response must be enclosed in "{" and "}".
As the google v3 api JSON response is in the "{" "}" format I need to use deserialiserAsDictionary method.
I suspect you know this already, but after looking at Jonathan Wight's code this is as far as I have come in resolving my own issue as Jonathan's code is specific in checking for the above in parsing the JSON response.
Thanks,
Tim
NSURL *url = [NSURL URLWithString:escapedUrlString];
NSString *responseString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
But, I was reading online that I should probably be using an NSURLRequest instead if I want to add a timeout. The first code works fine, but the second code always returns #"" (not nil, just ""). Anyone have any suggestions?
I also read that the NSURLConnection takes care of any sort of web compression that might be done whereas NSURLRequest won't handle that, so I thought I better just go for the more well rounded solution.
http://lists.apple.com/archives/cocoa-dev/2009/Oct/msg01921.html
NSString *escapedUrlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *responseString;
NSURLResponse *response;
NSError *error;
NSURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:[NSURL URLWithString:escapedUrlString]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:5]; // 5 second timeout?
NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if(responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]){
NSLog(#"Recieved String Result: %#", responseString);
} else {
NSLog(#"Response String is null!");
}
Thanks for the good suggestions. The code magically worked this morning, so I'm guessing my webserver went down or something last night.
I implemented the following code:
NSURL *url = [ NSURL URLWithString:[ NSString stringWithFormat: #"http://www.google.com/search?q=%#", query ] ];
NSURLRequest *request = [ NSURLRequest requestWithURL: url ];
I want to extract the body from what I receive back from the url above. I attempted:
NSData *data = [request HTTPBody];
The data variable doesn't return any data? Am I going about extracting the data out of the request the right way?
Thanks!
If you're just trying to get a web page, you can use this.
NSURL *url = [ NSURL URLWithString: [ NSString stringWithFormat: #"http://www.google.com"] ];
NSString *test = [NSString stringWithContentsOfURL:url];
If you really want to convert the data from NSData you can use this:
NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSURLRequest just defines a request — it doesn't do anything by itself. To actually make a request, you need to give the request to an NSURLConnection.
Also, as indicated in the documentation, the HTTPBody is data that's sent with the request, not the response body.
There is an article on www.eigo.co.uk which shows exactly how to do the request and get the response in a string variable but the chunk of code you need is...
NSString * strResult = [[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding];
Check out the article here http://www.eigo.co.uk/iPhone-Submitting-HTTP-Requests.aspx