Choosing the right IOS XML parser
Best comparison I've seen on the subject:
http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project
The difference between the slowest and fastest parsers in his case was a factor of 2. Depending on your feature requirements, there are definitely parsers that can cut your parsing time in half.
iOS XML Parser - Which one?
I would recommend to use TBXML as it takes lowest time comparatively to parse a document. To implement this surely you need multi-threading(GCD). You can implement this like lazy-loading concept, adding more rows as scroll reach to last.
XML Parsing in iPhone
You should use the following methods:
- (void)parseXMLFileAtURL:(NSString *)URL { //own method from me, URL could be local file or internet website
itemsOfFeed = [[NSMutableArray alloc] init];
NSURL *xmlURL = [NSURL URLWithString:URL];
feedParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[feedParser setDelegate:self];
[feedParser setShouldProcessNamespaces:NO];
[feedParser setShouldReportNamespacePrefixes:NO];
[feedParser setShouldResolveExternalEntities:NO];
[feedParser parse];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
//in case of an error
}
- (void)parserDidStartDocument:(NSXMLParser *)parser {
// start to parse xml
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
feedElement = [elementName copy];
if([elementName isEqualToString:@"item"]) { //main xml tag
item = [[NSMutableDictionary alloc] init];
feedTitle = [[NSMutableString alloc] init];
feedDate = [[NSMutableString alloc] init];
feedText = [[NSMutableString alloc] init];
feedLink = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if([feedElement isEqualToString:@"title"]) {
[feedTitle appendString:string];
} else if([feedElement isEqualToString:@"link"]) { // some examples of tags
[feedLink appendString:string];
} else if([feedElement isEqualToString:@"content:encoded"]) {
[feedText appendString:string];
} else if([feedElement isEqualToString:@"pubDate"]) {
[feedDate appendString:string];
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:@"item"]) {
[item setObject:feedTitle forKey:@"title"];
[item setObject:feedDate forKey:@"date"];
[item setObject:feedText forKey:@"text"];
[item setObject:feedLink forKey:@"link"];
[itemsOfFeed addObject:item];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.myTableView reloadData]; // for example reload table view
[self writeArrayToFile]; //or write to a local property list
}
in your header file:
NSMutableArray *itemsOfFeed;
NSXMLParser *feedParser;
NSMutableDictionary *item;
NSMutableString *feedElement;
NSMutableString *feedTitle, feedDate, feedText, feedLink; //strings of your tags
Then you have:
- NSArray
- NSDictionary
- object a
- object b
- object c
- NSDictionary
Just access 'object a' and put it in your text field
hopefully this code example helps you
How can I improve the XML parsing performance of my iOS code?
Your parsing logic is quite inefficient - you are doing the same test over and over again by saying
if (string and x) do this
if (string and y) do this
if (string and z) do this
Instead of
if (string)
if (x) do this
if (y) do this
if (z) do this
All those unnecessary string comparisons are probably why your parsing is so slow. Same goes for all the object lookups. If you need a value multiple times, get it once and then store it in a variable.
Objective C method calls are relatively slow and can't be optimised away by the compiler, so if the value doesn't change you should call the method once and then store it.
So for example, this:
if([elementName isEqualToString:@"string"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"id"]){
if(categoryFound){
categoryIdFound = YES;
}
else{
subscriptionIdFound = YES;
}
}
if([elementName isEqualToString:@"string"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"title"]){
subscriptionTitleFound = YES;
}
if([elementName isEqualToString:@"string"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"label"]){
categoryLabelFound = YES;
}
if([elementName isEqualToString:@"string"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"htmlUrl"]){
subscriptionHtmlURLFound = YES;
}
Could be rewritten as this:
NSString *name = [attributeDict objectForKey:@"name"];
if([elementName isEqualToString:@"string"])
{
if ([name isEqualToString:@"id"])
{
if(categoryFound){
categoryIdFound = YES;
}
else{
subscriptionIdFound = YES;
}
}
else if ([name isEqualToString:@"title"])
{
subscriptionTitleFound = YES;
}
else if ([name isEqualToString:@"label"])
{
categoryLabelFound = YES;
}
else if ([name isEqualToString:@"htmlUrl"])
{
subscriptionHtmlURLFound = YES;
}
}
Which is way more efficient.
Ipad XML parsing doubts
There is a built in XML parsing class in iOS called NSXMLParser
. As an init
parameter it takes an NSData
that is usually the data you get back from a web service. Assign yourself as its delegate and call [parser parse]
and it will call your delegate when it encounters an element, when it finishes an element, etc. See documentation for the parser and its delegate protocol.
If you have control over the structure of your XML, I've found it easier when it's structured like this:
<Element attr1='value1' attr2='value2' />
instead of:
<Element>
<attr1>value1</attr1>
<attr2>value2</attr2>
</Element>
The reason is that the callback for when it finds an element is:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
where attributes
is a dictionary of the values, so in the above example, [attributes objectForKey:@"attr1"]
would give you "value1" if it was structured in the first way. If it's the second way, you end up doing lots of state management that's a bit of a pain, especially if you've got elements within elements, etc.
In addition to NSXMLParser
thare are open-source parsers that either do everything themselves or wrap the built-in parser. I've written my own wrapper for it before. See here for a post on the subject (thanks to this question for the link).
Parsing data in an iOS app using XML or JSON parser
Just to add onto what others have already said in the comments:
Ideally you'll want to always connect asynchronously, using NSURLConnection's Delegate which will not block the main thread. If you're not already aware, iOS will force quit applications that block the main thread for too long a time. Synchronous connections can be ok in certain instances, but I'd say over 90% of the time you'll want asynchronous.
That said, asynchronous connections cause their own set of headaches. If you need to have data before allowing your users access to the application interface, you'll need to throw up loading screens and then remove them. You'll need to manage canceling requests if the user moves to a different part of the application that starts a new request. You'll also want to determine if any ongoing requests need to be registered for background completion in the event the user backgrounds the app.
On the JSON parsing side of things, it's always recommended to use NSData when you can, as converting JSON from NSString adds a lot of overhead from NSString itself. I personally do NOT use Apple's provided JSON parser, but the excellent JSONKit as it's faster than even Apple's binary plist parser. It does however require that your JSON adhere very strictly to the JSON RFC, and that it be UTF-8/16/32 encoded, not ASCII. This is fairly standard amongst the faster JSON parsers available.
Avoid XML all together when possible. The built-in iPhone parser is a SAX-style parser only, which is obnoxious to implement. If you must use XML, take a look at Ray Wenderlich's XML parser comparison and choose an appropriate one. If you have a large XML document to parse though, SAX is probably your only option given the limited processing capabilities of iDevices.
--EDIT--
One of the commenters mention SBJSON. I'd recommend against that entirely. It's slower than Apple's JSON parser (which has been available since iOS 5), and is much slower then JSONKit and several others by an order of magnitude. I specifically moved my current enterprise-level iOS Application off of SBJSON because of errors I was receiving in the JSON parsing as well.
Xml parsing in iOS tutorial
Use TBXml parser..That is the easiest way and also less time taken to parse a value..U can download TBXMLDemo project on github and to print that instead of label u can use table view cell and make it selection as null.So that it looks simillarly like label.If u need more details comment me,..i'll be helping it..
How To Parse XML in Cocoa?
You can access the value enclosed within tags by intelligently using this delegate method ;):
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
This link can prove to be useful - Handling XML Elements and Attributes
Related Topics
This Action Could Not Be Completed. Try Again (-22421)
Uitableview - Scroll to the Top
Difference Between Dispatch_Async and Dispatch_Sync on Serial Queue
How to Update a Localized Storyboard's Strings
How to Style Uitextview to Like Rounded Rect Text Field
How to Hide a Navigation Bar from First Viewcontroller in Swift
Center Content of Uiscrollview When Smaller
iPhone "Slide to Unlock" Animation
Xcode 8 Shows Error That Provisioning Profile Doesn't Include Signing Certificate
My App Was Just Rejected for Using the Ad Support Framework. Which Library Is Responsible
Pod Install -Bash: Pod: Command Not Found
Ios6 Udid - What Advantages Does Identifierforvendor Have Over Identifierforadvertising
How to Mask a Square Image into an Image with Round Corners in iOS
iOS Enterprise Distribution Through Ota
How to Use Namespaces in Swift
Why Maskstobounds = Yes Prevents Calayer Shadow
How to Fetch All Contacts Record in iOS 9 Using Contacts Framework