1

What I am trying to do is render image in a UICollectionView from imageUrl which is coming from server as response. There is no issue with UICollectionView as I have already tested it with hardcoded URL. The problem starts when I try to load it with the array which consist url as key-value pair. May be, I don't know the exact position from where I have to call the method which is responsible for getting the response from the server. I am getting the response exactly as it should be and pass it into an array. While debugging I can see that after getting response control is not going back to execute theUICollectionView delegate methodsto renderimageUrl`. Here is the code, which I am trying.

#import "ProductCollectionViewController.h"
#import "ProductCell.h"
#import "UIImageView+WebCache.h"

@interface ProductCollectionViewController ()
{
  NSMutableData *receivedData;
  NSMutableArray *productList;

}
@end
@implementation ProductCollectionViewController

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  if (self) {
    // Custom initialization
  }
  return self;
}
static NSString * const reuseIdentifier = @"Cell";
-(void)viewDidLoad 
{
  [super viewDidLoad];
  [self getProductList];
}

#pragma mark <UICollectionViewDataSource>

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
 }

 -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 
{

  return productList.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{

  ProductCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

  NSURL *url = [[productList objectAtIndex:indexPath.row]valueForKey:@"url"];

  [cell.productImageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"placeholder.jpg"]];

  return cell;
}

-(void)getProductList
{
  NSURLSessionConfiguration *defaultConfigObject =    [NSURLSessionConfiguration defaultSessionConfiguration];

  NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];

  NSURL * url = [NSURL URLWithString:@“http:xxxxxxxxx"];
  NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];  

  NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithRequest:urlRequest];

  [dataTask resume];
}

-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{

  NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) response;
  NSLog(@"status code %li", httpResp.statusCode);

  receivedData=nil;
  receivedData=[[NSMutableData alloc] init];
  [receivedData setLength:0];
  completionHandler(NSURLSessionResponseAllow);
}

-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
  [receivedData appendData:data];
}

 -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
  if (error) {
    // Handle error
  }
  else {
     NSError *tempError;

     NSDictionary* response=(NSDictionary*)[NSJSONSerialization      JSONObjectWithData:receivedData options:kNilOptions error:&tempError];

     NSLog(@"Response is :%@", response);
     productList = [NSMutableArray new];
     NSArray *rsBody = response [@"rsBody"];
     for(NSDictionary *dict in rsBody)       
     {
        [productList addObject:@{@“url":dict[@"productImageUrl"]}]
     }

    }

}

Response {"rsBody": [{"productId":11, "productImageUrl":"http:xxxx"}, {"productId":9, "productImageUrl":"http:"xxxx"}]}

Kunal Kumar
  • 1,722
  • 1
  • 17
  • 32
  • Can you please send your API response? – Rupal Patel Nov 04 '15 at 10:22
  • plz check, updated the question. – Kunal Kumar Nov 04 '15 at 10:33
  • Please check my updated answer hope its work. – Rupal Patel Nov 04 '15 at 10:45
  • Please change below line in cellForItemAtIndexPath NSURL *url =[[productList objectAtIndex:indexPath.row]valueForKey:@"url"]; to this line NSURL *url = [NSURL URLWithString:[[productList objectAtIndex:indexPath.row]valueForKey:@"url"]]; – Rupal Patel Nov 04 '15 at 10:49
  • Please reload your collection view after this loop for(NSDictionary *dict in rsBody) { [productList addObject:@{@“url":dict[@"productImageUrl"]}] } //Reload [YOUR_COLLECTION_VIEW_OBJECT reloadData]; – Rupal Patel Nov 04 '15 at 11:18
  • 1
    As stated by Rupal Patel, the mistake was that I wasn't reloading the CollectionView. `[self.collectionView reloadData];` – Kunal Kumar Nov 05 '15 at 12:14

2 Answers2

0

Change this line from NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url]; to

NSURLRequest * urlRequest = [NSURLRequest requestWithURL:url];

rest looks fine

S.Jain
  • 441
  • 4
  • 9
0

Please try below code. Hope its work for you.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{

   ProductCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

   NSURL *url = [NSURL URLWithString:[[productList objectAtIndex:indexPath.row]valueForKey:@"url"]];

   [cell.productImageView sd_setImageWithURL:url
       placeholderImage:[UIImage imageNamed:@"placeholder"] options:SDWebImageRefreshCached
              completed:nil];

   return cell;
}

Thanks :)

Rupal Patel
  • 570
  • 6
  • 13
  • Problem is that control is not going to that delegate method. – Kunal Kumar Nov 04 '15 at 10:30
  • Can you please share your API response or Image URL? – Rupal Patel Nov 04 '15 at 10:32
  • What is `imgUrl ` in `[NSURL URLWithString:imgUrl]`. I have already append the `productImageUrl` in the array. – Kunal Kumar Nov 04 '15 at 10:55
  • Rupal: Problem is that, after getting response control is not going back to the dalegate method to render image. Code ll executed only when the control ll go to the block. I think, problem is somewhere else in code. – Kunal Kumar Nov 04 '15 at 11:07
  • Please reload your collection view after this loop for(NSDictionary *dict in rsBody) { [productList addObject:@{@“url":dict[@"productImageUrl"]}] } //Reload [YOUR_COLLECTION_VIEW_OBJECT reloadData]; – Rupal Patel Nov 04 '15 at 11:09
  • Now throwing exception after line `ProductCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];` the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values. – Kunal Kumar Nov 04 '15 at 11:27