Im building a new version of an iPhone application and Im wondering if I should review how my app communicates with the server.
My iPhone client sends and receives XML over HTTP requests.
To send the information I use ASIHTTPRequest framework. I "manually" build the XML request by appending strings.
To parse the response Im using a NSXMLParser.
My question is if I have better options to
A) Create an XML string from a memory object.
B) Create a memory object from the XML string.
Is there anything like JAXB to marshal XML into object?
Thanks
Gonso
Have a look TouchXml
http://code.google.com/p/touchcode/wiki/TouchXML
I'm not entirely sure if this would work for you, but you could try using JSON along with a JSON parser such as SBJSON, which will create an object in memory for you based on the data.
To get JSON from an XML feed, I believe you could send the request for XML to YQL(http://developer.yahoo.com/yql) which can then translate the feed into JSON before sending it back.
Parsing XML
I cant think of something that looks for tags and parses things directly into objects (for XML), but a standard line-by line parser does the job. It does require a lot of code to use NSXMLParser, so just set up an external class to do it. It doesn't take that long, and is easy to cancel [parser abortParsing]
I basically used a model in which it starts a parent element, gets the the data from detail elements and then when the parent element closes, the parser takes the temporary data, fills an object with it, and adds the object to an array. It then repeats the process. I don't think my way would be very effective if you had more that 3 levels of XML (root==>parent tags==>details tags within parents), but it works for me. If you have complex XML, I would find some way to switch over to JSON and use SBJSON like Matt.M suggested.
Creating XML
If I were creating XML, I would just use a bunch of for loops and one big NSMutableString.
Related
I'm getting a large JSON string (11MB) from a web service. When I parse the data using JSONKit, my app reaches 70MB, I get memory warnings, and the app crashes.
How can I parse this data?
the easiest solution is reducing the json size you are getting from the server. If you cant to it, the only way to parse huge JSON is using lazy evaluation.
I dont think there is a JSON lib for objective-c that supports lazy evaluation. however you can implement one.
Your best bet is to look at the YAJL JSON parser, that supports event driven parsing. Then you can parse the JSON as it comes down in a data feed, and not have to store the whole thing in memory at once.
https://github.com/gabriel/yajl-objc
Sorry, I don't know of any code examples that demonstrate this use in practice.
SBJson supports parsing a stream of data. This lets your process your document bit by bit so you don't need to hold on to the entire document. The distribution contains two examples of how to use this. First there's the StreamParserIntegrationTest.m and next there's the TweetStream demo app: a twitter application that will sit and parse a HTTP stream all day (if you let it) displaying each tweet as they come in and then throw them away.
(Disclaimer: I am SBJson's author.)
11 mb is a largedata and solution is only to minimise your size of data
JSON support is not native to iOS, but there is a great framework for this exact purpose: http://code.google.com/p/json-framework/
This framework supports conversion from raw JSON objects to Objective-C objects (NSArray, NSDictionary) and vice versa.
I use GDataXML for parsing the XML I received from my webservice, actually I only parse the part that I need and then I want to "edit" that XML and send it back to Webservice.
I checked some GDataXML examples but they were about saving XML as model objects and creating an XML from model objects again.
Because speed is important what I want is without saving or converting that xml into model objects I just want to edit/delete some nodes on it and send it back quickly as possible.
Actually I can do this by simply converting it into string and do string manipulation. But I dont think editing XML as a string is a safe way.
How can I do this better?
Thanks
I tend to use a XML to NSDictionary object that I found on google which saves a lot of time parsing and configuring the XML. Try that out.
My Iphone communicates with my SOAP web service.
I have a questionnaire in my XML, which includes questions, their answers, and choices of some UI information..etc. So when the user enters a value for a set of questions using the IPhone and sends them back again to the Web service, the Service will add new unanswered questions to that XML.
So a conversation with the Web service starts with an empty XML and builds up to 200-300Kb of XML as the user answers the questions and receives new ones. Since it is a stateless Web Service, all the information will be kept in the XML.
Practically, I only need to find and parse the latest questions from the response XML, which should be good with a SAX parser, and modify only that part of the XML while adding the new answer and sending back again via the Web service the modified XML. BUT the user also should be able to click "Back". So that means I have to hold that XML in memory(200-300KB) and parse when necessary as the user clicks back and next.
My question is which approach is better:
1-Get the XML, parse it totally into objects with the DOM, release XML from memory and work only with the objects as the user clicks back and next. Then when it comes to sending it back, assemble a new XML message from scratch with my objects. Also this approach seems to reduce the clicking time
2-Use the SAX parser and only parse when I need to as the user clicks back and next. But then I have to hold all the XML in the memory. I do not know if Iphone can handle that, and back-next actions should take longer since I parse every time. But the good side is that I don't need to re-assemble an XML from objects again when I am done.
I think the second approach is better, what do you think? And which parser is good for this job?
Personally I prefer DOM XML parsers due to their ease of use and the ability to separate parsing/creating logic from the rest of the code. It seems that your application would be best suited to use a DOM parser because you said so yourself that sometimes you only need certain parts of the XML, not the entire document. SAX parsers do not support random read access.
read the following article and you will find the best solution for you
http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project
I would go with NSXMLDocument nevertheless.
I'm making an awesome iPhone app which searches for YouTube videos using the JSON API. However, Google is lazy so they just transformed the ATOM feed into JSON. Things look like this:
feed->entry[0]->author[0]->name->$t
This means that getting the information out of the NSArray is difficult, as I need to get a value of a key of an object of an array of an object of an array of an object of a key.
To check if the structure is correct, I can choose two things:
Use a huge amount of code for each item I want to check if the JSON was correct.
Wrap everything in a #try block.
I'd like to choose the second one. The problem is that some time ago I read that this is bad practice. Is it? And if so, is there a shorter way to validate the NSArrays en NSDictionaries? My app may never crash, not even if the user remover the processor at runtime, so not checking at all is not an option.
Can you please help me? Thanks.
Have you tried the GData API? I'm using it for my application ( http://itunes.apple.com/us/app/skystop/id392782307?mt=8 ) for the Youtube Feed. It basically spits out an XML file for whatever you've requested and you can convert it right into a plist file or an NSArray.
i'm not sure i understand, the API itself works in JSON instead of ATOM so you need to di into every item ?
If this is so then you are right, not much you can do except to seardch the web for helper libraries that might have been made even in google code to support this API.
In any case #2 is bad practice first of all since try catch usually consume more system resources then simple boolean cheek or checks.
Second once you are in the catch block you are kind of in problem since all you can do is print an error to the user or yourself, if you want to go on parsing and checking, you can't...
and last but not least (I'm sure there are reasons I'm not thinking of) except for the message you might get with the exception u are never to sure where it came from...
Are you parsing the JSON yourself? If so, I suggest using an external framework to do the work for you. I use Json-framework in a few of my own projects and it does the job just fine.
http://code.google.com/p/json-framework/
We want to take XML data and convert it to an NSDictionary object, but we don't want to manually iterate over the XML. Is there an easy way to do this? How are you doing web services for your iPhone app?
If you have control over the XML output you could try creating a property list which you can then read into a dictionary using -dictionaryWithContentsOfURL: (though the better asynchronous way would be to get the data using an NSURLConnection and then converting the data using the -propertyList method on NSString). You can find more about property lists here: http://developer.apple.com/documentation/Cocoa/Conceptual/PropertyLists/Introduction/chapter_1_section_1.html
Of course the best solution is to use a RESTful client and use a combination of NSURLConnection to get/send the data and the TouchXML classes (http://code.google.com/p/touchcode/wiki/TouchXML) to parse the data, though this would require more work to put the data into a dictionary. Of course if these are going to be the main data objects in your system you really want to be using either a custom class or SQLite to store the data as it provides you much more reliability in testing your app than a dictionary.
If you can control the server output, try using plists. Otherwise you're stuck with parsing XML (or JSON if the server can do that), but there are frameworks you can use. See the answer to this question.
Also, here is a good overview of how to do RESTful clients on the iphone:
https://developer.apple.com/webapps/articles/creatingrestfulclients.html
You can return the data in JSON format. There are many open-source JSON parsers available for the iPhone (TouchJSON being one).
There's another class available called NSPropertyListSerialization which gets you a dictionary from data.
You can do something like this with the data you receive
NSDictionary* propertyList;
NSPropertyListFormat format;
NSString *errorStr;
propertyList = [NSPropertyListSerialization
propertyListFromData:receivedData
mutabilityOption: NSPropertyListImmutable
format: &format
errorDescription: &errorStr];
Sorry, don't know what tags are used here for formatting code!