Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 10-13-2009, 01:24 PM   #1 (permalink)
Registered Member
 
Join Date: Sep 2009
Posts: 9
Default Best way to load remote data (XML, XML to Local SQLite) into UITableView?

Hello Everyone,
I'm currently developing an app and my major bottleneck is getting data into the program. The data is highly dynamic and changes several time a day so local storage is not an option. Currently, I have all data loaded on application load via a remote XML file (the XML file is created programatically via a PHP script that queries a MySQL db that houses the data). The problem with this is that it is very slow to parse even though the XML file is only about 67k (using NSXMLParser). It takes about 25 seconds to parse the file, during which time the UI is completely locked up (I put an animated overlay for now but ultimately it would be awesome to be able to load the data into the view asynchronously or just reduce the load time to something under 4 seconds). I've tried using a static locally stored XML file rather than a programatically generated one but it still suffers the same parsing times. I've seen SQLite in use but it's hindered by the fact that you can't load data remotely. I've seen a few people using PLIST files but I haven't been able to create one programatically and I'm also not sure how to deal with creating an NSSArray with the data. I know there are apps out there that have large amounts of data updated on a continuous stream but they don't seem to suffer from the problems I'm having. Am I missing something obvious? Thank you so much in advance!
tspitznas is offline   Reply With Quote
Old 10-13-2009, 01:42 PM   #2 (permalink)
Humbled Student
 
Dutch's Avatar
 
Join Date: Apr 2009
Location: Long Island, NY
Age: 32
Posts: 883
Send a message via AIM to Dutch
Default

you can easily download the file asynchronously... Check out this post. It shows how to download an HTML file, but the same thing applies, just pass an XML file to it.

How are you parsing the XML? Are you using NSXMLParser? That is the only way to go, if not.
Dutch is offline   Reply With Quote
Old 10-13-2009, 01:43 PM   #3 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 62
Default

Hi tspitznas,

SQLite is not option for remote data pull, you already pointed out why. If you have problems with the NSXMLParser class try out TouchXML. It is a replacement for the missing NSXML class tree which is not ported to Cocoa touch.
To not lock up the system you can go deep with POSIX commands in plain C, but I suggest you look up NSThread for threading or NSOperationQueue if the task is more complex (as the name states, NSO.Q. queses threads) but you won't give up comfortable threading.
ff10 is offline   Reply With Quote
Old 10-13-2009, 01:45 PM   #4 (permalink)
Registered Member
 
Join Date: Sep 2009
Posts: 9
Default

I will try both of these solutions. Thanks! I tried out KissXML awhile ago but wasn't successful.
tspitznas is offline   Reply With Quote
Old 10-13-2009, 01:46 PM   #5 (permalink)
Humbled Student
 
Dutch's Avatar
 
Join Date: Apr 2009
Location: Long Island, NY
Age: 32
Posts: 883
Send a message via AIM to Dutch
Default

NSXMLParser should not lock the Main Thread..
Dutch is offline   Reply With Quote
Old 10-13-2009, 01:48 PM   #6 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 62
Default

Quote:
Originally Posted by tspitznas View Post
I will try both of these solutions. Thanks! I tried out KissXML awhile ago but wasn't successful.
One hint: if you try TouchXML and wonder about the lack of documentation for it, keep in mind that it is a replacement for NSXML, so just use commands analog to it, (e.g. NSXMLElement would be CXMLElement).
ff10 is offline   Reply With Quote
Old 10-13-2009, 02:11 PM   #7 (permalink)
Registered Member
 
Join Date: Sep 2009
Posts: 9
Default

Quote:
Originally Posted by Dutch View Post
you can easily download the file asynchronously... Check out this post. It shows how to download an HTML file, but the same thing applies, just pass an XML file to it.

How are you parsing the XML? Are you using NSXMLParser? That is the only way to go, if not.
I am using NSXMLParser but it locks the main thread. I can't really see where to invoke the XML parser in that script you linked to. I may try out TouchXML and see if it simply parses out the XML quicker.
tspitznas is offline   Reply With Quote
Old 10-13-2009, 02:58 PM   #8 (permalink)
iPhone SDK fanatics!
 
Join Date: Aug 2009
Location: Malaysia
Posts: 370
Default

Quote:
Originally Posted by Dutch View Post
you can easily download the file asynchronously... Check out this post. It shows how to download an HTML file, but the same thing applies, just pass an XML file to it.

How are you parsing the XML? Are you using NSXMLParser? That is the only way to go, if not.
Hi Dutch, dun mind I chap in. Any idea how to read a .plist from a website and replace the one in my app's folder? Does this work? Thanks.
__________________
KennyChong
iPhone SDK Fanatic!
KennyChong is offline   Reply With Quote
Old 10-13-2009, 03:38 PM   #9 (permalink)
Humbled Student
 
Dutch's Avatar
 
Join Date: Apr 2009
Location: Long Island, NY
Age: 32
Posts: 883
Send a message via AIM to Dutch
Default

Quote:
Originally Posted by KennyChong View Post
Hi Dutch, dun mind I chap in. Any idea how to read a .plist from a website and replace the one in my app's folder? Does this work? Thanks.
Well, what I'll tell you is that you can download just about any file this way - as far as replacing the app's info.plist - that I do not know about.
Dutch is offline   Reply With Quote
Old 10-13-2009, 03:39 PM   #10 (permalink)
Humbled Student
 
Dutch's Avatar
 
Join Date: Apr 2009
Location: Long Island, NY
Age: 32
Posts: 883
Send a message via AIM to Dutch
Default

Quote:
Originally Posted by tspitznas View Post
I am using NSXMLParser but it locks the main thread. I can't really see where to invoke the XML parser in that script you linked to. I may try out TouchXML and see if it simply parses out the XML quicker.
Perhaps there is an issue in your parsing code. I have not experienced such delays.
Dutch is offline   Reply With Quote
Old 10-13-2009, 05:35 PM   #11 (permalink)
Registered Member
 
Join Date: Sep 2009
Posts: 9
Default

Quote:
Originally Posted by Dutch View Post
Perhaps there is an issue in your parsing code. I have not experienced such delays.
I really don't know what could be wrong with my parsing code. Would you mind taking a look for anything obvious?
Code:
@implementation XMLParser

- (XMLParser *) initXMLParser {
	
	[super init];
	
	appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];
	
	return self;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName 
	attributes:(NSDictionary *)attributeDict {
	
	if([elementName isEqualToString:@"Books"]) {
		//Initialize the array.
		appDelegate.books = [[NSMutableArray alloc] init];
	}
	else if([elementName isEqualToString:@"Book"]) {
		
		//Initialize the book.
		aBook = [[Book alloc] init];
		
		//Extract the attribute here.
		aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];
		
		NSLog(@"Reading id value :%i", aBook.bookID);
	}
	
	NSLog(@"Processing Element: %@", elementName);
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
	
	if(!currentElementValue) 
		currentElementValue = [[NSMutableString alloc] initWithString:string];
	else
		[currentElementValue appendString:string];
	
	NSLog(@"Processing Value: %@", currentElementValue);
	
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
	
	if([elementName isEqualToString:@"Books"])
		return;
	
	//There is nothing to do if we encounter the Books element here.
	//If we encounter the Book element howevere, we want to add the book object to the array
	// and release the object.
	if([elementName isEqualToString:@"Book"]) {
		[appDelegate.books addObject:aBook];
		
		[aBook release];
		aBook = nil;
	}
	else 
		[aBook setValue:currentElementValue forKey:elementName];
	
	[currentElementValue release];
	currentElementValue = nil;
}

- (void) dealloc {
	
	[aBook release];
	[currentElementValue release];
	[super dealloc];
}

@end
tspitznas is offline   Reply With Quote
Old 10-13-2009, 08:58 PM   #12 (permalink)
Registered Member
 
Join Date: Sep 2009
Posts: 9
Default

Quote:
Originally Posted by tspitznas View Post
I really don't know what could be wrong with my parsing code. Would you mind taking a look for anything obvious?
Code:
@implementation XMLParser

- (XMLParser *) initXMLParser {
	
	[super init];
	
	appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];
	
	return self;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName 
	attributes:(NSDictionary *)attributeDict {
	
	if([elementName isEqualToString:@"Books"]) {
		//Initialize the array.
		appDelegate.books = [[NSMutableArray alloc] init];
	}
	else if([elementName isEqualToString:@"Book"]) {
		
		//Initialize the book.
		aBook = [[Book alloc] init];
		
		//Extract the attribute here.
		aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];
		
		NSLog(@"Reading id value :%i", aBook.bookID);
	}
	
	NSLog(@"Processing Element: %@", elementName);
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
	
	if(!currentElementValue) 
		currentElementValue = [[NSMutableString alloc] initWithString:string];
	else
		[currentElementValue appendString:string];
	
	NSLog(@"Processing Value: %@", currentElementValue);
	
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
	
	if([elementName isEqualToString:@"Books"])
		return;
	
	//There is nothing to do if we encounter the Books element here.
	//If we encounter the Book element howevere, we want to add the book object to the array
	// and release the object.
	if([elementName isEqualToString:@"Book"]) {
		[appDelegate.books addObject:aBook];
		
		[aBook release];
		aBook = nil;
	}
	else 
		[aBook setValue:currentElementValue forKey:elementName];
	
	[currentElementValue release];
	currentElementValue = nil;
}

- (void) dealloc {
	
	[aBook release];
	[currentElementValue release];
	[super dealloc];
}

@end
wow, after looking at my code, I just removed the NSLog calls and it reduced the parsing time down to less than 1 second! I can't beleive I missed that. This is one of those moments where you want to punch yourself in the face lol
tspitznas is offline   Reply With Quote
Reply

Bookmarks

Tags
parse, parser, slow, sqlite, xml

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 276
26 members and 250 guests
ADY, Bertrand21, Dani77, Dattee, fkmtc, HDshot, HemiMG, iDifferent, IphoneSdk, jakerocheleau, JasonR, jimbo, macquitzon216, MACralik, mer10, NSeven, prchn4christ, Rudy, sacha1996, silverwiz, sneaky, spiderguy84, Sunny46, theone8one
Most users ever online was 1,187, 10-11-2011 at 08:09 AM.
» Stats
Members: 158,885
Threads: 89,230
Posts: 380,767
Top Poster: BrianSlick (7,129)
Welcome to our newest member, bookesp
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 03:06 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0