0

I used SDWebImage library to download images from server. In my code I am facing an image loading issue & SDwebImage. The problem is: I've written the code like this:

[cell.imgNews setImageWithURL:[NSURL URLWithString:[self.arrImages objectAtIndex:indexPath.row]]

If I give I like this my Application is working smooth & fast. But the images are not loading. It's displaying only empty cells. The Reason of displaying the empty cell is a couple of images are named in Arabic and in that the names are having space Ex.%20.

My question is: how can we display the Arabic named images (you can see the bellow screen shot) in the image cell? (Note: Few images are being displayed that are named in English)

But the Images are downloading in the Debugger Area (You can see the Screen shot here)

To Escape that empty cell I used this code:

[cell.imgNews setImageWithURL:[NSURL URLWithString:[[self.arrImages objectAtIndex:indexPath.row] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]

The Problem is if I use this code, the application gets very slow. How can I solve this Issue?

Can any one help me to solve this issue?

Here is my Code :

NewsViewController.m

#import "NewsViewController.h"
#import "NewsTableViewCell.h"
#import "NewDetailsViewController.h"
#import <SDWebImage/UIImageView+WebCache.h>
#import "SearchVC.h"
@interface NewsViewController ()
{
    NSString *temString;
    NSMutableString *strTemp;
    BOOL isDateSearch;
    int search;
}
@property(strong,nonatomic) NSArray *SearchResultsArray;

@end

@implementation NewsViewController
@synthesize arrImages;
@synthesize TittleOne;
@synthesize TittleTwo;
@synthesize TittleThree;
@synthesize datepicker;
@synthesize PickerContainer;
@synthesize datepickerTittle;
@synthesize searchBr;
@synthesize NewsIndicator;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

#pragma mark - View Life Cycle
- (void)viewDidLoad
{
    [self performSelector:@selector(myindicator) withObject:nil afterDelay:10.0];

    [super viewDidLoad];
    search=0;
    self.searchBr.hidden=YES;
    self.searchBr.barTintColor = UIColorFromRGB(0Xe54c41);
    self.searchBr.backgroundColor = UIColorFromRGB(0Xe54c41);
    [self removeUISearchBarBackgroundInViewHierarchy:self.searchDisplayController.searchBar];
    self.searchDisplayController.searchBar.backgroundColor = NO;
    [TittleOne setFont: [UIFont fontWithName:@"GEEast-ExtraBold" size:12]];
    [TittleTwo setFont: [UIFont fontWithName:@"GEEast-ExtraBold" size:12]];
    [TittleThree setFont: [UIFont fontWithName:@"GEEast-ExtraBold" size:10]];
    NSDateFormatter *dateFormatter=[[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"dd/MM/yyyy"];
    NSLog(@"%@",[dateFormatter stringFromDate:[NSDate date]]);
    [TittleTwo setText:[dateFormatter stringFromDate:[NSDate date]]];
    // [[UIColor redColor] set];
    [datepickerTittle setFont:[UIFont fontWithName:@"GEEast-ExtraBold" size:12]];
    // [datepickerTittle.textColor= [UIColor yellowColor]];

    isDateSearch=NO;
    self.arrTitles =[[NSMutableArray alloc] init];
    self.arrDescription=[[NSMutableArray alloc]init];
    self.arrImages=[[NSMutableArray alloc]init];
    self.arrDate=[[NSMutableArray alloc]init];
    self.arrUrls=[[NSMutableArray alloc]init];
    self.arrDateSearch=[[NSMutableArray alloc]init];
    //[self performSelectorInBackground:@selector(requestingForNews:) withObject:nil];

    // dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), s^{
    self.spinnerView.hidden=YES;
    [self makeRequestForNews];
    //  self.spinnerView.stopAnimating;
    //});

    // Do any additional setup after loading the view.
    [self imagedownloader:@"http://www.shura.bh/MediaCenter/News/"];
     self.SearchResultsArray = [[NSArray alloc] init ];
}
-(void)myindicator {
    [NewsIndicator stopAnimating];
    NewsIndicator.hidden =YES;
    [self.tblNews reloadData];
}
-(void)requestingForNews:(id)sender
{
    [self makeRequestForNews];
}
-(void) imagedownloader : (NSString *)urlStringOfImage
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(queue, ^{
        //downlaod image
        NSURL *imageUrl = [NSURL URLWithString:urlStringOfImage];
        NSData  *imageData = [NSData dataWithContentsOfURL:imageUrl];
        UIImage *image = [UIImage imageWithData:imageData];
        dispatch_async(dispatch_get_main_queue(), ^{

            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50, 50 )];
            imageView.image = image;
            [self.view addSubview:imageView];
        });
    });
}

- (void) removeUISearchBarBackgroundInViewHierarchy:(UIView *)view
{
    for (UIView *subview in [view subviews]) {
        if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
            [subview removeFromSuperview];
            break; //To avoid an extra loop as there is only one UISearchBarBackground
        } else {
            [self removeUISearchBarBackgroundInViewHierarchy:subview];
        }
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma  mark - make request for news
-(void)makeRequestForNews
{

    NSURL *url =[NSURL URLWithString:self.strNewsApi];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //After making request the apparent thing is expecting the response that may be expected response or an Error. so create those objects and intialize them with NULL.
    NSURLResponse *response = NULL;
    NSError *requestError =NULL;
    //Once you have response with you , Capture YOur Responce data using NsData.

    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&requestError];

    //Convert the respnse Data into Response String.

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

    //Now We can start parsing the Data using XMl parser . you need XML parser in-order to use the below class method "dictionaryFOrXMLString".

    NSError *parserError = NULL;

    //XML parsing

    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:responseData];
    [xmlParser setDelegate:self];
    [xmlParser parse];

    //    NSURL *url = [NSURL URLWithString:url];
    //    NSData *data = [NSData dataWithContentsOfURL:url];
    //    UIImage *image = [UIImage imageWithData:data];

    //NSDictionary *xmlDict = [XMLReader dictionaryForXMLString:responseString error:NULL];

    //once you have xmlDict handy, you can pass this to the any ViewController (Like table view) to populate the Data.
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {

}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{


    if ([elementName isEqualToString:@"ShuraNews"])
    {

    }
    if ([elementName isEqualToString:@"PUBLISHINGPAGEIMAGE"])
    {

    }
    strTemp=[NSMutableString new];
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    //temString =string;
    [strTemp appendString:string];
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"TITLE"])
    {
        NSLog(@"temstring=== %@", strTemp);
        [self.arrTitles addObject:strTemp];
    }
    if ([elementName isEqualToString:@"PUBLISHINGPAGECONTENT"])
    {
        NSLog(@"temstring=== %@", strTemp);
        [self.arrDescription addObject:strTemp];
    }
    if ([elementName isEqualToString:@"NEWSARTICLEDATE"])
    {
        NSLog(@"temstring=== %@", strTemp);
        [self.arrDate addObject:strTemp];
    }
    if ([elementName isEqualToString:@"PUBLISHINGPAGEIMAGE"])
    {

        NSLog(@"temstring=== %@", strTemp);
        [self.arrImages addObject:strTemp];
    }
    if ([elementName isEqualToString:@"ShuraNews"])
    {
        [self.tblNews reloadData];
        // self.spinnerView.hidden=YES;
    }
    if ([elementName isEqualToString:@"URL"])
    {
        [self.arrUrls addObject:strTemp];
    }

}
#pragma mark - TabeView Datasource//delegate method

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;

}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView)
    {
        return [self.SearchResultsArray count];
    }
    else
    {
        return [self.arrTitles count];
    }

    if (isDateSearch)
    {
        return [self.arrDateSearch count];
    }
    else{
        return [self.arrTitles count];
    }
    return [self.arrTitles count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView setSeparatorInset:UIEdgeInsetsZero];
    static NSString *cellIdentifier=@"cellNews";
    NewsTableViewCell *cell=(NewsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
  //  NewsTableViewCell *cell=(NewsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    if (cell == nil)
    {
        cell = [[NewsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        // cell.NewsTableViewCell.textColor = UIColorFromRGB(0x000000);
        cell.backgroundColor=[UIColor clearColor];


    }

    if (tableView == self.searchDisplayController.searchResultsTableView)
    {
        cell.textLabel.text= [self.SearchResultsArray objectAtIndex:indexPath.row];
    }



    if( [indexPath row] % 2){
        cell.contentView.backgroundColor =UIColorFromRGB(0Xffffff);

    }
    else{
        cell.contentView.backgroundColor =UIColorFromRGB (0Xdcdcdc);
    }

    //selectbackground color start
    UIView *NewsTableViewCell = [[UIView alloc] initWithFrame:cell.frame];
    NewsTableViewCell.backgroundColor = UIColorFromRGB(0Xdcdcdc);
    cell.selectedBackgroundView = NewsTableViewCell; //select background colro end
    cell.lblTitles.font = [UIFont fontWithName:@"GEEast-ExtraBold" size:12];
    if (isDateSearch)
    {
        cell.lblTitles.text=[[self.arrDateSearch objectAtIndex:indexPath.row]objectForKey:@"title"];
    }
    else{
        cell.lblTitles.text=[self.arrTitles objectAtIndex:indexPath.row];
    }
    cell.lblDescription.font =[UIFont fontWithName:@"GE SS Unique" size:12];
    cell.lblDate.font=[UIFont fontWithName:@"GE SS Unique" size:12];
    if (isDateSearch)
    {
        cell.lblDescription.text=[[self.arrDateSearch objectAtIndex:indexPath.row]objectForKey:@"des"];
    }
    else{
        cell.lblDescription.text=[self.arrDescription objectAtIndex:indexPath.row];
    }
    cell.lblDate.text=[self.arrDate objectAtIndex:indexPath.row];
    cell.lblTitles.textAlignment= NSTextAlignmentRight;
    cell.lblDate.textAlignment = NSTextAlignmentRight;
    cell.lblDescription.textAlignment = NSTextAlignmentRight;
    NSData *data;
    if (isDateSearch)
    {
        data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[self.arrDateSearch objectAtIndex:indexPath.row]objectForKey:@"img"]]];
    }
    else{
        data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self.arrImages objectAtIndex:indexPath.row]]];
    }

    //SDWebImage Code for lazy loader
   [cell.imgNews setImageWithURL: //[NSURL URLWithString:[self.arrImages objectAtIndex:indexPath.row]]
   [NSURL URLWithString:[[self.arrImages objectAtIndex:indexPath.row] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]

                       completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {

                         //   if (![self.arrImages objectAtIndex:indexPath.row])
                          //  if ((cell.imgNews.image = image))
                            if (image)
                            {
                                cell.imgNews.layer.borderColor = [UIColor blackColor].CGColor;
                                cell.imgNews.layer.borderWidth = 2.0;
                                cell.lblTitles.frame=CGRectMake(cell.lblTitles.frame.origin.x, cell.lblTitles.frame.origin.y, 208, cell.lblTitles.frame.size.height);
                                cell.lblDate.frame=CGRectMake(cell.lblDate.frame.origin.x, cell.lblDate.frame.origin.y, 208, cell.lblDate.frame.size.height);
                                cell.lblDescription.frame=CGRectMake(cell.lblDescription.frame.origin.x, cell.lblDescription.frame.origin.y, 206, cell.lblDescription.frame.size.height);

                            }
                            else {

                             //  if (!cell.imgNews ==nil)
                            if (!cell.imgNews.image)
                                {

                                    cell.lblTitles.frame=CGRectMake(cell.lblTitles.frame.origin.x, cell.lblTitles.frame.origin.y, 283, cell.lblTitles.frame.size.height);
                                    cell.lblDate.frame=CGRectMake(cell.lblDate.frame.origin.x, cell.lblDate.frame.origin.y, 286, cell.lblDate.frame.size.height);
                                    cell.lblDescription.frame=CGRectMake(cell.lblDescription.frame.origin.x, cell.lblDescription.frame.origin.y, 281, cell.lblDescription.frame.size.height);
                                    cell.imgNews.layer.borderColor = [UIColor blackColor].CGColor;
                                    cell.imgNews.layer.borderWidth = 0;


                                }
                            }

                        }];

    [PickerContainer setHidden:YES];

    return cell;
}

#pragma Search Methods
-(void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope
{
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains [search] %@", searchText];
    self.SearchResultsArray = [self.arrTitles filteredArrayUsingPredicate:predicate];


}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterContentForSearchText:searchString scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];


    return YES;

}

- (void)layoutSubviews
{
    if(!(searchBr == nil))
    {
        searchBr.frame = CGRectMake(4, 5, 185, 30);
    }
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSDictionary *dict=nil;
    if (isDateSearch)
    {
        dict=[[NSDictionary alloc]initWithObjectsAndKeys:[NSString stringWithFormat:@"%@",[[self.arrDateSearch objectAtIndex:indexPath.row]objectForKey:@"title"]],@"title",[NSString stringWithFormat:@"%@",[[self.arrDateSearch objectAtIndex:indexPath.row]objectForKey:@"des"]],@"img",[NSString stringWithFormat:@"%@",[self.arrDescription objectAtIndex:indexPath.row]],@"Des",[NSString stringWithFormat:@"%@",[self.arrUrls objectAtIndex:indexPath.row]],@"url", nil];
    }
    else{
        dict=[[NSDictionary alloc]initWithObjectsAndKeys:[NSString stringWithFormat:@"%@",
                   [self.arrTitles objectAtIndex:indexPath.row]],@"title",[NSString stringWithFormat:@"%@",
                    [self.arrImages objectAtIndex:indexPath.row]],@"img",[NSString stringWithFormat:@"%@",
                     [self.arrDescription objectAtIndex:indexPath.row]],@"Des",[NSString stringWithFormat:@"%@",
                     [self.arrDate objectAtIndex:indexPath.row]],@"Date",[NSString stringWithFormat:@"%@",

                      [self.arrUrls objectAtIndex:indexPath.row]],@"url", nil];
    }
    [self performSegueWithIdentifier:@"NewsDetailsID" sender:dict];

}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"NewsDetailsID"])
    {
        ((NewDetailsViewController *)segue.destinationViewController).strTitle=[sender objectForKey:@"title"];
        ((NewDetailsViewController *)segue.destinationViewController).strDetailImage=[sender objectForKey:@"img"];
        ((NewDetailsViewController *)segue.destinationViewController).strDescription=[sender objectForKey:@"Des"];//strUrl
         ((NewDetailsViewController *)segue.destinationViewController).strDate=[sender objectForKey:@"Date"];
        ((NewDetailsViewController *)segue.destinationViewController).strUrl=[sender objectForKey:@"url"];
    }
}
- (IBAction)SearchButton:(id)sender {
    if (search == 0) {
       searchBr.hidden=NO;
        search=1;
    }
    else
    {
       searchBr.hidden=YES;
        search=0;
    }
}

- (IBAction)backBtnClicked:(id)sender {
    [self.navigationController popViewControllerAnimated:YES];
}

- (IBAction)DatePickerBt:(id)sender {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
    PickerContainer.frame = CGRectMake(0, 150, 320, 261);
    [PickerContainer setHidden:NO];
}
- (IBAction)HideButton:(id)sender
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
    PickerContainer.frame = CGRectMake(0,600, 320, 261);
    [UIView commitAnimations];


    if ([self.arrDate count])
    {
        for (int i=0; i<[self.arrDate count]; i++)
        {
            NSArray *arrDateStr=[[self.arrDate objectAtIndex:i] componentsSeparatedByString:@" "];
            // NSString *dateString=[NSString stringWithFormat:@"%@ %@",[[arrDateStr objectAtIndex:0]stringByReplacingOccurrencesOfString:@"/" withString:@"-"],[arrDateStr objectAtIndex:1]];

            NSString *dateString=[NSString stringWithFormat:@"%@ %@",[arrDateStr objectAtIndex:0],[arrDateStr objectAtIndex:1]];

            NSDateFormatter *format = [[NSDateFormatter alloc]init];
            [format setDateFormat:@"dd/MM/yyyy"];
            NSDate *currentDate = [format dateFromString:dateString];
            if ([[[[NSString stringWithFormat:@"%@",currentDate]componentsSeparatedByString:@" "]objectAtIndex:0] isEqualToString:[[[NSString stringWithFormat:@"%@",self.datepicker.date]componentsSeparatedByString:@" "]objectAtIndex:0]])
            {
                isDateSearch=YES;
                NSDictionary *dictTemp=[NSDictionary dictionaryWithObjectsAndKeys:[self.arrTitles objectAtIndex:i],@"title",[self.arrDescription objectAtIndex:i],@"des",[self.arrImages objectAtIndex:i],@"img", nil];
                [self.arrDateSearch addObject:dictTemp];
                [self.tblNews reloadData];
                NSLog(@"dates equal");
            }

        }
    }
}


- (IBAction)ReloadButton:(id)sender {
    self.spinnerView.hidden=YES;
    isDateSearch=NO;
    [self makeRequestForNews];
    NSLog(@"RELOADING!!!!!!!!!!!!!!!");
}

@end
Neeku
  • 3,646
  • 8
  • 33
  • 43

1 Answers1

0

You should definitely be using stringByAddingPercentEscapesUsingEncoding, and I do not think that this is "per se" causing the performance problem you see. That is just modifying a bit the URL you use.

I tend to think that by using stringByAddingPercentEscapesUsingEncoding your app is getting all of the images (as opposed to just a few of them) and this is making it slower.

E.g., if the images you download are large, then this might explain the app slowness, both in terms of how long you have to wait for the image to be available and to scale it down to cell size.

EDIT:

I checked the site http://www.shura.bh/MediaCenter/News and images are indeed large. They take quite a while to download in Safari. I have found images as large as 4000x3000px, and this is definitely too large.

sergio
  • 68,819
  • 11
  • 102
  • 123
  • Hi , If i use 'stringByAddingPercentEscapesUsingEncoding ' the images are not displaying ? I want display all the images . if its not possible to display the "20%"(Which images are having arabic named) images at least the app should work smooth .I do not know whats wrong with my code ? – user3744932 Jul 03 '14 at 08:28
  • So will it possible to load those images in my image cell ?? And my Question is why Arabic Named images are not loading ? Will it possible to load or not ? if yes how can we do that ? – user3744932 Jul 03 '14 at 08:55
  • You mean that if you use `stringByAddingPercentEscapesUsingEncoding` then the images are NOT displaying? I understood that images are downloaded with `stringByAddingPercentEscapesUsingEncoding` (which is right) but the app gets slow... – sergio Jul 03 '14 at 09:00
  • you need to use `stringByAddingPercentEscapesUsingEncoding` to get a properly formatted URL whenever certain characters are present (not just arabic ones, also spaces, colons, etc.). – sergio Jul 03 '14 at 09:02
  • @ sergio ,your right . I used '[cell.imgNews setImageWithURL:[NSURL URLWithString:[[self.arrImages objectAtIndex:indexPath.row] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]' Still not displaying ? – user3744932 Jul 03 '14 at 09:19
  • I do not understand what is happening exactly. You say that either with `stringByAddingPercentEscapesUsingEncoding` or without it, you cannot see the images. Is this right? Or maybe it is working in one case? And if it is not working in any case, what is the thing with the app getting slow? – sergio Jul 04 '14 at 08:10
  • if i use 'stringByAddingPercentEscapesUsingEncoding' images are not loading And app getting very slow , when i scroll down the news are keep loading .. – user3744932 Jul 05 '14 at 06:11
  • Exactly what i need is, My app Currently working very slow and All images are not loading , So i want my App should be perform bit faster and all the images should be display . This is what i want !! Hope now its clear for you . – user3744932 Jul 05 '14 at 09:10
  • I am pretty sure your app is slow due to image size. have no idea why it does not load all images, should see it running. if you want to post your project, I can give it a look... – sergio Jul 05 '14 at 09:20