简体   繁体   中英

How can I improve the speed of my ios app?

My app is developed in Objective-C for ios 7, and it (throught queries inserted in NSString) connects itself to the php script that execute queries on the database on the server. I've some cells (in a tableView) that each contain the information of a user (ID, name, description, profile picture). Every time I load the TableView, I run 3 queries that retrieve all the elements (and a method that retrieves profile pictures for each user from the server), that is:

NSString *IDUsers = @"Select ID from user";
NSString *Names = @"Select name from user";
NSString *Descriptions = @"Select Description from user";

For each string (IDUser,Names,Descriptions) I do it:

//query can be IDUser or Names or Descriptions
NSMutableString *strURL = [NSMutableString stringWithFormat:@"http://localhost/myApp/selectquery.php?query=%@",query];

[strURL setString:[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];

NSError* error;

NSDictionary* json = [NSJSONSerialization
                      JSONObjectWithData:dataURL
                      options:kNilOptions
                      error:&error];

NSMutableArray *results = [[NSMutableArray alloc] init];

int numRow = 0;

for (NSArray *arrow in json) {
    [results addObjectsFromArray:arrow];
    numRow++;
}

//results is the array of results of the query

When I execute the queries on db throught the script, it give me Back arrays (one array for each ID, one array for each name, one array for each description). Then I execute a for cycle for each ID in array of ID and I retrieve the profile picture associated to each ID (from server).

NSMutableString *strURL = [NSMutableString stringWithFormat:@"http://localhost/myApp/getProfilePicture.php?IDUser=%@",arrID[i]];

    [strURL setString:[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];

    UIImage *profileSnap = [UIImage imageWithData:dataURL];

These arrays then populate each cell (a cell for each user). This, occurred locally (with MAMP) is really fast. But if this happens when the connection string is connected to the server, it's really too slow. How can I do? Have you got suggestions? I read that I could do with Grand Central Dispatch, but how?

If the slow speed is because of the network latency and the inherent nature of web requests, Grand Central Dispatch doesn't help at all.

You can follow the correct example suggested by emotality in his answer, to perform some lazy loading, specially for images. GCD allows you to do tasks in the background to improve the user experience, but it won't speed up the web requests.

If your app is slow because it is processing a lot of data there are other strategies that you can follow. For example if your app processes 100,000 records, you could modify your web service to be queried a subset of the data, so you can present immediately to the user the first n records, while you still download more in the background.

I hope this helps you in some way, but you need to provide more details about why is your application slow, and for each reason there's a different strategy.

EDIT:
AS I said, you're web service needs to support it, if it doesn't you need to change it and design some way of doing it. On way would be passing other parameters in the querystring of your request (these parameters would be rangeStart and rangeEnd , for example). Your php script needs to recognize these parameters and query your database for records corresponding to that specific range.

Obviously this complicates your design, because you need to keep track of which ranges you have already queried, but I don't think it's thaaaat difficult either.

This is called lazy loading, it runs (downloading) in the background while your tableView is loading all other data from delegate etc :)

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{

// get image from server here

        dispatch_sync(dispatch_get_main_queue(), ^{

            // set images after they have been downloaded/saved.
            // ALWAYS USE MAIN_QUEUE WHEN WORKING WITH VISIBLE ELEMENTS LIKE THESE

            [cell.imageView setImage:(UIImage *)];
            [cell setNeedsLayout];
        });

});

[self.tableView reloadData];

Remember to reload tableview data when finished. Hope this helps!

For the fastest webservice calls, use MKNetworkKit

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM