NSMutableData response string - iphone

I am trying to upload images to yFrog which is working just fine, but I want to grab just the URL from the response. When I use the NSURLConnection method
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString* responseString = [[NSString alloc] initWithData:webData
encoding:NSUTF8StringEncoding];
// NSString *url = [webData valueForKey:#"mediaurl"];
NSLog(#"result: %#", responseString);
}
I get this as my response string
result: <?xml version="1.0" encoding="UTF-8"?>
<rsp stat="ok">
<mediaid>hszuhsp</mediaid>
<mediaurl>http://yfrog.com/hszuhsp</mediaurl>
</rsp>
As you can see in my blocked out code I tried to give my NSMutableData to give me the value of the key #"mediaurl" which just crashes. I think this should be relatively easy but for some reason I just can not figure out how to just grab the URL out of the response. Any help would be greatly appreciated. Thank you

This is a valid xml response.
If you need to parse only this response, you can iterate the NSString.
But if you have other response in xml format then the best approach is you are going to parse it using any XML parser.. :)
Here is how to choose your xml parser, and then you will search for tutorial accordingly.

you can't use the valueForKey on the instance of NSMutableData class., you should use the XML parser to extract the value.

Related

iOS Unable to store URL contents into array

I have to connect to a URL to check whether the records is empty. The response looks something like this:
<?xml version = "1.0" encoding = "UTF-8"?>
<find>
<record_id>1234</record_id>
<no_record>00001</no_record>
<entry_num>00001</entry_num>
<session-id>aijheifaohqrihelrkqn324tlejaofjaf</session-id>
</find>
My codes:
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init]
autorelease];
[request setURL:[NSURL URLWithString: finalSearchURL]];
// Content-Type related.
[request setValue:#"application/x-www-form-urlencoded"
forHTTPHeaderField:#"Content-Type"];
// Create Connection.
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (conn) {
// The connection was established.
NSMutableData *receivedData = [[NSMutableData alloc] initWithContentsOfURL:[NSURL URLWithString:request]];
NSLog( #"Data will be received from URL: %#", request.URL );
NSLog(#"Recieved Data 2: %#", receivedData);
}
else
{
// The download could not be made.
NSLog( #"Data could not be received from: %#", request.URL );
}
But it returns me:
Recieved Data : <3c3f786d 6c207665 7273696f 6e203d20 22312e30 2220656e 636f6469 6e67203d 20225554 462d3822 3f3e0a3c 66696e64 3e0a3c73 65745f6e 756d6265 723e3031 39303633 3c2f7365 745f6e75 6d626572 3e0a3c6e 6f5f7265 636f7264 733e3030 30303030 3030313c 2f6e6f5f 7265636f 7264733e 0a3c6e6f 5f656e74 72696573 3e303030 30303030 30313c2f 6e6f5f65 6e747269 65733e0a 3c736573 73696f6e 2d69643e 4d505843 33323433 58564336 4534454a 41464232 45473541 39374237 584e3832 43554631 4e314234 584e4c37 424c5947 4e533c2f 73657373 696f6e2d 69643e0a 3c2f6669 6e643e0a 20>
Can anyone help to tell me what am I doing wrong? This is my first attempt for getting response from a url please help thanks!
See the data as a string this way:
NSString *string = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
NSLog(#"the xml string is %#", string);
If the parsing goal is simple enough - like just to find the value of one tag - you can use string methods to parse. Otherwise, NSXMLParser or several other options are available.
To see if the string contains a substring, you can do something like this:
if (string) {
NSRange range = [string rangeOfString:#"<session-id>"];
if (range.location != NSNotFound) {
// session-id tag is at index range.location, so we know it's there
}
}
The method you used is to get the raw data from the url. You need a parser to convert the raw data to the understandable structure (probably NSDictionary rather than NSArray).
Apple has provided NSXMLParser for you to retrieve the xml structure from the url or you can find other xml parser libraries.
Actually, your code is returning the correct data. Since NSData can hold any kind of data, it will just display the hex value. If you convert the hex data to a sting, you'll see that it has the correct text.
Now, your code can be simplified a lot. All the code for setting up the NSURLConnection is not needed at all. All you need is the following line.
NSString *recievedText = [NSString stringWithContentsOfFile:finalSearchURL encoding:NSUTF8StringEncoding error:NULL];

How to use SBJSON parse with using Content-Type and Method(POST,GET) in iPhone?

Already i have worked on SBJSON parsing, that was working very fine. Now, i am working in SBJSON parsing. The problem is the parsing result is returning null(In NSDictionary). I have tested the url in Firefox POST tool, it returned result with the Content-Type = application/x-www-form-urlencoded and Method = POST. How to use Content-Type and Method[POST, GET] in SBJSON file parsing? Really i can not find the result in google search(sorry). Please help me to solve my problem. Please suggest me any sample code or idea. Thanks in advance.
This is my code,
SBJSON *jsonParser = [[SBJSON new] autorelease];
NSURL *urls = [NSURL URLWithString:[NSString stringWithFormat:#"SAMPLE URL"]];
NSString *stringUrl = [NSString stringWithFormat:#"%#",urls];
NSDictionary *dictionary = (NSDictionary *) [jsonParser objectWithString:stringUrl error:nil];
NSLog(#"Dictionary : %#", dictionary);
The dictionary is returning null. How to use Content-Type and [POST,GET] methods in SBJSON file parsing?
Thanks in advance.
You are not actually fetching the string data at the URL, just creating a URL and parsing that, which unsurprisingly, cannot be converted to a JSON object. You should asynchronously fetch the string data using something like NSURLConnection, or easier ASIHTTP, then parse the result.

Parse an XML stored in NSData with libxml2

please can you help me using libxml2 to parse an XML stored in a NSMutableData object? I get the XML using
NSString *path = "http://www.mySite.com/XMLPATH.xml";
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:path] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
and
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data_
{
[data appendData:data_];
}
where data is an instance of NSMutableData.
Now how can i start the libxml2 to parse this data? I need the equivalent of
NSString *xml; // string containing XML
mlDocPtr doc = xmlParseMemory([xml UTF8String], [xml lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
where xml is my NSMutabledata and not a NSString.
Thanks!
EDIT:
I'm currently using NSXMLParser to do the job, but i'd like to have a parser that automatically parses all the XML, with its node structure. With NSXMLParser i need to manually set the node structure of my XML
Any reason you are not using the NSXMLParser. It is a nice wrapper written by Apple and included on all iOS versions.
http://developer.apple.com/library/mac/ipad/#documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html

Extracting array from NSMutableData in http response

using iphone sdk 4.0. The callback for an http request gives data as an NSData object
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the data received to our data
[theData appendData:data];
}
In my php script on the server i am returning an array as follows
var_dump($array).
How do i get my array back from the NSMutableData object 'theData' obove on my iphone.
Thanks
You have a string describing your array (or maybe several arrays?) stored as a sequence of bytes in your NSMutableData object. In order to turn it back into an array you're going to need to parse the var_dump output, which is likely to be arduous.
If you can find a library (or roll your own code) to return your data in Apple plist format, your task will be much easier: you can use
[NSPropertyListSerialization propertyListFromData:mutabilityOption:format:errorDescription:]
which takes an NSData (or NSMutableData) pointer as its first argument. Try http://code.google.com/p/cfpropertylist/ for a starting point.
From the example code at the cfpropertylist page:
$plist = new CFPropertyList();
$td = new CFTypeDetector();
$guessedStructure = $td->toCFType( $array );
$plist->add( $guessedStructure );
// and then return the plist content with
$plist->toXML()
and in your iOS code:
NSString *errorString = nil;
NSArray *array = [[NSPropertyListSerialization
propertyListFromData:theData
mutabilityOption:NSPropertyListImmutable
format:nil
errorDescription:&errorString] retain];
I would likely use YAJL on iOS, and $var = json_encode($array); in the PHP. Then in the iOS, I would parse that content from the NSData input like:
YAJLParser *parser = [[YAJLParser alloc] initWithParserOptions:YAJLParserOptionsAllowComments | YAJLParserOptionsCheckUTF8];
parser.delegate = [[[MyArrayParserDelegate alloc] init] autorelease];
[parser parse:data];
NSArray *thePhpArrayReceived = parser.delegate.resultantArray;
Please check out how to structure the delegate, and get YAJL here : Get YAJL + Readme
PHP outputs text so you will have to read that NSData as NSString and then parse out the array data according to the format specified by var_dump. As a starting point, the following code snippet should print out the array (as text) to your console:
NSString * dump = [[NSString alloc] initWithData:theData
encoding:NSUTF8StringEncoding];
NSLog(#"%#", dump);
[dump release];
As Seamus Campbell points out, there are better ways of doing this. Another option would be to output XML from your PHP script, and then use Cocoa's XML parsing methods to retreive the array.

How to find why NSMutableData is invalid

I access a RESTFUL url and get back results. The results are in JSON. I turn the response into a string via:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *json = [[NSString alloc] initWithBytes:[self.receivedData mutableBytes] length:[self.receivedData length] encoding:NSUTF8StringEncoding];
The json variable has a value of 0x0. When I mouse over it, I see <Invalid CFStringRef>. How can I debug this to tell why it is invalid? I render the JSON given back through the browser in A JSON parser. That checks out fine.
Results are given back by entering an ID in the URL. Other IDs return results without issue. The result set is fairly large.
First I would use initWithData:encoding: to setup the NSString. Small difference, but that method is there for a reason.
Then, I would do a hexdump of self.receivedData to see what is actually in there. If that data is not properly UTF8 encoded then the initWithData:encoding: will fail.
(Google for NSData hex dump to find other people's utility functions to do this)
I have found that sometimes web services are sloppy with their encoding. So I usually implement a fallback like this:
NSString* html = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
if (html == nil) {
html = [[NSString alloc] initWithData: data encoding: NSISOLatin1StringEncoding];
if (html == nil) {
html = [[NSString alloc] initWithData: data encoding: NSMacOSRomanStringEncoding];
}
}
It is kind of sad that this is required but many web services are not written or configured properly.
Use NSLog to look at the bytes.