0

This is my problem, I'm building an iOS with some JSON returs from my server, here, no problems, all works fine.

The problem is that when I run the program, it take a long long time to parse the result into a NSMutableArray: this is the log

2013-01-10 12:03:48.627 project[5917:907] <- time begin parser
2013-01-10 12:03:48.755 project[5917:907] <- time finish parser
2013-01-10 12:03:48.756 project[5917:907] <- time begin implement arrays
2013-01-10 12:03:58.522 project[5917:907] <- time finish implement array

As you can see, implementing the arrays is really long.

I know that I have to use queueing and grand central dispatch to make my UI responsive, but I don't know how to, could you please help me to do that ?

This is my viewDidLoad Method

- (void)viewDidLoad
{
    [super viewDidLoad];

    if debug
        NSLog(@"<- time begin parser");
    endif


    NSString *URLStr = @"http://myJsonFile.json";

    NSDictionary *myDictwithReturn = [TOCJSONParser awesomeParserWithStringOfYourJSONFile:URLStr]; //really cool parser, i can put it on gitHub if you want
    NSArray *speakersArray = [myDictwithReturn objectForKey:@"speakers"];

    myArray = [[NSMutableArray alloc]init];

    NSLog(@"<- time finish parser");
    NSLog(@"<- time begin implement arrays");

    for (NSDictionary *myDict in speakersArray) {

        _nextSpeaker = [[TOCSpk alloc]init];
        [_nextSpeaker setName:[myDict objectForKey:@"name"]];
        [_nextSpeaker setBusiness:[myDict objectForKey:@"business"]];
        [_nextSpeaker setDesc:[myDict objectForKey:@"desc"]];
        [_nextSpeaker setTwitter:[NSURL URLWithString:[myDict objectForKey:@"twitter"]]];
        [_nextSpeaker setPicture:[_nextSpeaker retrieveImageFromServer:[myDict objectForKey:@"picture"]]];
        [myArray addObject:_nextSpeaker];
    }

    NSLog(@"<- time finish implement array"); 
}
Clément S.
  • 391
  • 1
  • 11

1 Answers1

2

I suspect that the slowness comes from calling retrieveImageFromServer, which lets me think that you are accessing the network. If that access is synchronous, as it seems from the fact that you are assigning the image in the same statement, than this is bound to be slow.

You should review your code and make it run on a separate thread or use asynchronous network access.

EDIT:

After your comment about using, dataWithContentsOfURL, my above hypothesis is confirmed. You can read this S.O. post about a way to download images asynchronously, or you might use any of various networking frameworks available out there.

Possibly, the easiest path forward is using SDWebImage, which is a class that offers async download for images, so you don´t have to bother yourself with thread management or NSURLConnection:

Just #import the UIImageView+WebCache.h header, and call the setImageWithURL:placeholderImage: method from the tableView:cellForRowAtIndexPath: UITableViewDataSource method. Everything will be handled for you, from async downloads to caching management.

Community
  • 1
  • 1
sergio
  • 68,819
  • 11
  • 102
  • 123
  • In fact this method doesn't call the server at all, it just instanciate an UIImage from a URL string parsed in JSON file – Clément S. Jan 10 '13 at 11:41
  • and where does the image data come from? have you already downloaded it? is it bundled within the app? – sergio Jan 10 '13 at 11:43
  • i have JSON attribute in the http://myjsonfile.json entitled "pictureURL" : "http://myurl.com/img.png" and then the method is something like (UIImage *)myMethodname:(NSString *)picturePath { UIImage *myimage [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:picturePath]]]; return myImage; } – Clément S. Jan 10 '13 at 11:46
  • 1
    `dataWithContentsOfURL` will access the network synchronously. – sergio Jan 10 '13 at 12:00
  • Ok, could you tell me how to do this async and to put it in my array then, thx – Clément S. Jan 10 '13 at 12:08
  • just edited my answer; have a look at `SDWebImage`, I think it will make things easier. – sergio Jan 10 '13 at 12:10
  • In fact i still have a pb, i import the .xcodeproj file to frameworks, i'll linked ImageIO and set the -ObjC flag but i've got `SDWebImage/UIImageView+WebCache.h file not found` :/ – Clément S. Jan 10 '13 at 14:45
  • either you add the path to `SDWebImage/UIImageView+WebCache.h` to your target build settings (header search path) or you add the `.h` file itself to your project (in this case, the compiler should find it on its own). – sergio Jan 10 '13 at 15:07
  • I change my method, i copy all .m .h file in a group, and as i see MKAnnotationView, i also add MapKit.framework and it's work fine :-) – Clément S. Jan 10 '13 at 15:24