Download and Save plist file, please help me

Discussion in 'iOS Programming' started by MynEz, Mar 23, 2011.

  1. MynEz macrumors newbie

    Joined:
    Jan 13, 2011
    Location:
    Regina,Sask
    #1
    Hi, agian

    I don't know the correct way to do with this url: http://plistupdate.transitlive.com/saturday-1299867550.plist

    I'm now writing a project about to download this data and show in the tableView. I want to load this data and save in my directory but it seems that when I access to this url, it's not automatically file for download. So I did try to parse the elements from this data by using NSXMLParser but I couldn't because the key of element in each row has the same name. I don't know the correct way to do with this. If somebody knows or can give me the advice please help.
     
  2. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #3
    Download the file to your sandbox using NSURLConnection. Then open the file using whichever class is the root object in the plist (usually NSArray or NSDicationary).
     
  3. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #4
    Couldn't you also just read it in with initWithContentsOfURL: and save it locally with writeToFile:atomically: ?

    B
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #5
    You could do but that method is synchronous. With a NSURLConnection you can download asynchronously (without having to thread the download yourself) which is normally better for the user experience.
     
  5. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #6
    OK. So that's basically like running wget or curl as background thread and then acting on the local copy. Makes sense.

    The impact on UX then ultimately depends somewhat on the size of the plist and the bandwidth and latency of the pipe available at the time?

    B
     
  6. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    The timeout for networking is apparently longer than the watchdog kill time. You will be killed sooner or later if you use synchronous networking because of this.
     
  7. MynEz thread starter macrumors newbie

    Joined:
    Jan 13, 2011
    Location:
    Regina,Sask
    #8
    Well, thank you for you reply.
    Now I'm using the NSURLConnection and request to this url, it seems like the processing time to parse this data took so long. Do you have any idea? I created the dictionary at <plist> and try to run in console but i couldn't display all of these objects into the table view. If you can help me fix about my code, I'll be glad. Thank you

    This is my code:
    Code:
    NSMutableArray = list;
    
    -(void)viewDidLoad{
    	
    	[list removeAllObjects];
    	[[self tableView]reloadData];
    	NSURL *url = [NSURL URLWithString:@"http://plistupdate.transitlive.com/saturday-1299867550.plist"];
    	NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
    	if (connection) {
    		[connection cancel];
    		[connection release];
    	}
    	[xmlData release];
    	xmlData = [[NSMutableData alloc]init];
    	connection = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:YES];
    	[super viewDidLoad];
    }
    
    
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    	if ([elementName isEqual:@"plist"]) {
    		NSLog(@"Found plist file!");
    		datas = [[NSDictionary alloc]init];
    		titleString = [[NSMutableString alloc]init ];
    	}
    }
    
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    	if ([elementName isEqual:@"plist"]) {
    		NSLog(@"ended title: %@", titleString); 
    		[list addObject:datas];
    		[titleString release];
    		titleString = nil;
    	}
    }
    
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    	[titleString appendString:string];
    }
     
  8. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #9
    Do this after you've saved the file in your sandbox.

    Code:
    NSString* path = path to the file;
    NSArray* array = [NSArray arrayWithContentsOfFile:path];
    It will parse the file for you. (If the root is a dictionary use [NSDictionary dictionaryWithContentsOfFile:])
     
  9. MynEz thread starter macrumors newbie

    Joined:
    Jan 13, 2011
    Location:
    Regina,Sask
    #10
    Err... I'm just beginner could you show me how to start and save file? and do I need to forget about the parser?

    Thank you
     
  10. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #11
    Yes, forget about the parser. Just use the code I showed. How do you create this plist file?

    To use the NSURLConnection to save the file there are a million tutorials and links and posts on this forum and every other forum. You just have to implement a few delegate callbacks that the NSURLConnection makes to its delegate. Save the file in each callback. When it's finished then open the file with the code I showed.
     
  11. MynEz thread starter macrumors newbie

    Joined:
    Jan 13, 2011
    Location:
    Regina,Sask
    #12
    Yes, this plist file is from my instructor. well I loaded the data from url and saved it, last night I ran the program and everything went well but this morning I tried to run it agian but it got crashed. Do you have any ideas, here is my code, please help.
    Code:
     //Save
    NSString *urlString = @"http://plistupdate.transitlive.com/weekday-1299867550.plist";
    	NSURL *url = [NSURL URLWithString:urlString];
    	NSData *datas = [NSData dataWithContentsOfURL:url];
    	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    	NSString *documentsDirectory = [paths objectAtIndex:0];
    	NSString *plistFile = [documentsDirectory stringByAppendingPathComponent:@"abc.plist"];
    	
    	[datas writeToFile:plistFile atomically:YES];
    
    Load
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    		
    		NSString *documentsDirectory = [paths objectAtIndex:0];
    		
    		NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:@"abc.plist"];
    		if (plistPath) {
    			NSLog(@"pass!");
    		}
    		NSDictionary *dict = [[NSDictionary alloc]initWithContentsOfFile:plistPath];
    		self.dataUpdate = dict;
    		[dict release];
    		if (dict) {
    			NSLog(@"has file");
    		}
    
    
     
  12. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #13
    Crashed where? For what reason?
     
  13. MynEz thread starter macrumors newbie

    Joined:
    Jan 13, 2011
    Location:
    Regina,Sask
    #14
    It's probably from NSData. I used NSLog to check it but It couldn't retrieve the data from url. So I don't know how to fix it please help.:(
     
  14. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #15
    It's probably? I think you should find out for sure. I would suggest putting a breakpoint in before the section of code you suspect and step through it line by line until you find the problem line. Basic debugging is a key skill; no time like the present to learn more about it. :)
     
  15. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #16
    That file is 10MB. Kind of a big plist file. It takes Safari a minute to download it on my Mac.

    You can't possibly download it using NSData dataWithContentsOfURL: on the main thread.

    If you were running the app in the Sim it could do this because the watchdog isn't active, but your app would be frozen for a minute or more. On a device your app would be killed by the watchdog.

    Also, it's possible that you don't have 10MB free memory on an older device, which could also cause problems.

    You need to download the file using NSURLConnection and its asynchronous method. The root of the plist is a dictionary so once it's a local file you can open it with NSDictionary dictionaryWithContentsOfFile: but it might take some seconds to open.
     
  16. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #17
    Agreed. Plus, you can then take advantage of NSURLConnection's connection:didFailWithError: delegate method to better handle possible problems.
     
  17. MynEz thread starter macrumors newbie

    Joined:
    Jan 13, 2011
    Location:
    Regina,Sask
    #18
    Thanks to you guys, I used breakpoint to check it and as you said the file size is big so it's quit itself. I'm gonna try with NSURLConnection. Is it really good for reducing the processing time?
     
  18. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #19
    It won't make the download run any faster but, assuming you use the asynchronous methods, it will not cause the main runloop thread to stop which will mean your app won't get killed.
     

Share This Page