Trying to answer your basic question, "How can I upload images to UICollectionview asynchronously?"
I propose the solution proposed by Natasha Murashev here , which worked great for me, and it's simple.
If here imgURL = [allImage objectAtIndex:k]; the allImage property stores an array of URLs, update your collectionView:cellForItemAtIndexPath: method as follows:
- (PSTCollectionViewCell *)collectionView:(PSTCollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { NSURL *url = [NSURL URLWithString:[allImage objectAtIndex:indexPath]]; [self downloadImageWithURL:url completionBlock:^(BOOL succeeded, NSData *data) { if (succeeded) { cell.grid_image.image = [[UIImage alloc] initWithData:data]; } }]; }
And add the downloadImageWithURL:completionBlock: method to your class, which will load images asynchronously and update cells in CollectionView automatically when the images are successfully loaded.
- (void)downloadImageWithURL:(NSURL *)url completionBlock:(void (^)(BOOL succeeded, NSData *data))completionBlock { NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { if (!error) { completionBlock(YES, data); } else { completionBlock(NO, nil); } }]; }
I see that you are trying to preload the images before the presentation appears, so maybe my solution is not that you are, but it is hard to say from your question. Be that as it may, you can also achieve what you want.
Swift 2.2 Solution in Swift.
public typealias ImageFetchCompletionClosure = (image: UIImage?, error: NSError?, imageURL: NSURL?) -> Void extension String { func fetchImage(completionHandler: (image: UIImage?, error: NSError?, imageURL: NSURL?) -> Void) { if let imageURL = NSURL(string: self) { NSURLSession.sharedSession().dataTaskWithURL(imageURL) { data, response, error in guard let httpURLResponse = response as? NSHTTPURLResponse where httpURLResponse.statusCode == 200, let mimeType = response?.MIMEType where mimeType.hasPrefix("image"), let data = data where error == nil, let image = UIImage(data: data) else { if error != nil { completionHandler(image: nil, error: error, imageURL: imageURL) } return } dispatch_sync(dispatch_get_main_queue()) { () -> Void in completionHandler(image: image, error: nil, imageURL: imageURL) } }.resume() } } }
Usage example:
"url_string".fetchImage { (image, error, imageURL) in // handle different results, either image was downloaded or error received }