开发者

iphone slow navigation due to data load

开发者 https://www.devze.com 2023-02-26 16:10 出处:网络
I\'m newbie to objective-c . My problem is slow navigation between controllers. When I jump from one controller to another it\'s really slow, because it gets data from the service, parse it and then d

I'm newbie to objective-c . My problem is slow navigation between controllers. When I jump from one controller to another it's really slow, because it gets data from the service, parse it and then display it. All this takes around 4-5 secs. Now I've put all this data fetching in loadView of my DetailController. Is there anyway that I show the controller first and then display the data. Because as of now, when I select a row on my root controller, it shows activity and stays on root controller and then it navigates to the DetailController. So it loads the data first and then displays it. Is there anyway that I can reverse this process, show the controller first and then display it..

this is what I'm doing

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

DataCollection *collection = [DataCollection sharedObject];
Product *tempProduct = [[collection popularProducts] objectAtIndex:row] ;

ProductDetailViewController *tempProductDetail = [[ProductDetailViewController alloc] init];

tempProductDetail.homeViewProduct = tempProduct;
[tempProductDetail release];
}

and then the Detail Controller

- (void)loadView {
      [super loadView];
      // here's all the data loading and parsing ... which takes time
}

//Here's the method for downloading the data, I'm using a REST service to get all the data.

- (void) getProductData:(NSString*)productId{

NSMutableString *specificURL = [[NSMutableString alloc] initWithString:@"GetProductPage?id="];
[specificURL appendFormat:@"%@",productId];
[specificURL appendFormat:@"&dataSources=&accountId=&companyId=&version=1&cultureCode=sv&currencyId=2&format=json"];

NSDictionary *serverCategories = [[NSDictionary alloc] initWithDictionary:[appRequestController proceesRequest:specificURL]];
NSArray *categories = [[[serverCategories objectForKey:@"DataSources"] objectAtIndex:0] objectForKey:@"Items"];
[serverCategories release];

        if ([[productsArray objectAtIndex:j] objectForKey:@"Name"]  != [NSNull null]) {
            [product setProductName:[[productsArray objectAtIndex:j] objectForKey:@"Name"]];
        }
        else {
            [product setProductName:@""];
        }


        if ([[productsArray objectAtIndex:j] objectForKey:@"ThumbnailImage"]  != [NSNull null]) {
            [product setProductImage:[[productsArray objectAtIndex:j] objectForKey:@"ThumbnailImage"]];
        }
        else {
            [product setProductImage:@""];
        }


        if ([[productsArray objectAtIndex:j] objectForKey:@"Price"]  != [NSNull null]) {

            [product setProductPrice:[[productsArray objectAtIndex:j] objectForKey:@"Price"]];      
        }
        else {
            [product setProductPrice:@""];
        }

            [[collection popularProducts] addObject:product];
        [product release];

}

I've copy pasted junks of the code so that you can get an idea how I'm getting the data. Below is the code for cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *MyIdentifier = @"mainMenuIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
    [cell setSelectedBackgroundView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"highlightstrip.png"]]];

}

UILabel *productNameLbl = [[UILabel alloc] initWithFrame:CGRectMake(90, 8, 200,10)];
[productNameLbl setText:[NSString stringWithString:[[[[DataCollection sharedObject] popularProducts]objectAtIndex:indexPath.row] productName]]];
[productNameLbl setFont:[UIFont boldSystemFontOfSize:12.0]];

[cell addSubview:productNameLbl];
[productNameLbl release];

UILabel *productSubLbl = [[UILabel alloc] initWithFrame:CGRectMake(90, 22, 190,40)];
[productSubLbl setText:[NSString stringWithString:[[[[DataCollection sharedObject] popularProducts]objectAtIndex:indexPath.row] productSubHeader]]];
[productSubLbl setTextColor:[UIColor colorWithRed:102.0/255.0 green:102.0/255.0 blue:102/255.0 alpha:1.0]];
productSubLbl.lineBreakMode = UILineBreakModeWordWrap;
productSubLbl.numberOfLines = 3;
[productSubLbl setFont:[UIFont fontWithName:@"Arial" size:10]];

[cell addSubview:productSubLbl];
[productSubLbl release];

NSMutableString *url = [[NSMutableString alloc] initWithString:@""];
NSString *baseImageURL = @"http://samplesite.com/";
NSString *imagePath = [开发者_开发百科NSString stringWithString:[[[[DataCollection sharedObject] popularProducts]objectAtIndex:indexPath.row] productImage]];

[url appendString:baseImageURL];
[url appendString:imagePath];
NSURL *imageURL = [NSURL URLWithString:url];

NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *img = [[UIImage alloc] initWithData:data cache:NO];
UIImageView *imageView = [[UIImageView alloc] initWithImage:img];
[imageView setFrame:CGRectMake(10, 10, 70, 70)];
[cell addSubview:imageView];
[imageView release];

cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;

}


Pass the url or product id to the detail view. Inside the viewDidLoad of the ProductDetail, create a background thread to retrieve your data. When you background thread finish, it will notify your ProductDetail controller with the detail. At that time, you update your ProductDetailView.

To get your data on a background thread you can use

  • NSThread
  • NSOperation


Pass the row into your ProductDetailViewController, and do the fetch in it's viewDidLoad method. You might also want to show a spinner (UIActivityIndicator), and you definitely should read up on background threads.


To make view available to user and loading data after some time you can use NSTimer.

Just have a NSTimer method which will be called in viewDidLoad method as

  • [NSTimer scheduledTimerWithTimeInterval:<#(NSTimeInterval)ti#> target:<#(id)aTarget#> selector:<#(SEL)aSelector#> userInfo:<#(id)userInfo#> repeats:<#(BOOL)yesOrNo#>]

put some time interval which will be calling your loading method after that.

Hope this helps.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号