I my application I have table view with custom cell, that has:
@property (weak, nonatomic) IBOutlet UIImageView *image;
@property (weak, nonatomic) IBOutlet UILabel *nameOfImage;
@property (weak, nonatomic) IBOutlet UIButton *start;
I need to download any number of images asynchronously (by pressing a lot of start buttons). For this purpose I created subclass of NSOperation - MyOperationQueue. implementation of it looks like this:
- (id)initWithURL:(NSURL*)url andRaw:(NSInteger)row
{
if (![super init])
return nil;
[self setTargetURL:url];
[self setCurrentCell:row];
self.customCell = [[CustomTableViewCell alloc]init];
self.tableView = [ContentTableView sharedManager];
return self;
}
- (void)main
{
if ([self isCancelled])return;
self.defaultSession = [self configureSession];
NSURLSessionDownloadTask *task = [self.defaultSession downloadTaskWithURL:self.targetURL];
if ([self isCancelled]) return;
[task resume];
}
- (void)cancel
{
self.isCancelled = YES;
if(self.downloadTask.state == NSURLSessionTaskStateRunning)
[self.downloadTask cancel];
}
among this methods I have also described here NSURLSession methods:
- (NSURLSession *) configureSession //it visits it
{
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self.tableView **delegateQueue:self**]; //self - warning - incompatible pointer type sending "MyOperationQueue" to "NSOperationQueue" _Nullable.
}
-(void)URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite // don't visit
-(void)URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location // don't visit
I create the custom queue in method in TableView:
- (void)didClickStartAtIndex:(NSInteger)cellIndex withData:(CustomTableViewCell*)data
{
NSURL *url = [NSURL URLWithString: tmp.imeageURL];
MyOperationQueue * one = [[MyOperationQueue alloc]initWithURL:url andRaw:self.selectedCell];
[self.queue addOperation:one];
}
The image is not loaded at all, the queue just enter into configuration method and thats all. Please advise me whats wrong? Thank you in advance.
EDIT: Updating UI:
-(void)URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
{
NSLog(@"didFinishDownloadingToURL - Queue");
NSData *d = [NSData dataWithContentsOfURL:location];
UIImage *im = [UIImage imageWithData:d];
dispatch_async(dispatch_get_main_queue(), ^{
self.customCell.image.image = im;
self.customCell.realProgressStatus.text = @"Downloaded";
[self.tableView.tableView reloadData];
});
}
Your class is a subclass of NSOperation
, not NSOperationQueue
So you can't specify it to use self
as the target queue for the NSURLSession
object. Frankly, you'd just use nil
for the operation queue parameter, as you don't care which on which queue the delegate methods run. Or you can create your own operation queue, if you want. But you cannot use self
.
But make sure to dispatch any UI updates back to the main queue.
Also, you must make this an asynchronous NSOperation
subclass or else the operation will terminated and be deallocated before your delegate methods ever get a chance to be called.
As a minor observation, I'd suggest renaming this class to be MyOperation
, to avoid confusion between operations and operation queues.