Last active
September 23, 2019 16:19
-
-
Save PaulWoodIII/298c185df2ca78f226ba92ba43b3b0cb to your computer and use it in GitHub Desktop.
Obj-C Code needed to show progress of an image downloading using NSURLSession
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ImageDownloaderCommonBlocks.h | |
// AsyncImageDownloader | |
// | |
// Created by Paul Wood on 9/23/19. | |
// Copyright © 2019 Paul Wood. All rights reserved. | |
// | |
#ifndef ImageDownloaderCommonBlocks_h | |
#define ImageDownloaderCommonBlocks_h | |
typedef void (^ImageCallback)(UIImage * _Nonnull); | |
typedef void (^ProgressBlock)(NSNumber * _Nonnull); | |
typedef void (^ImageWithErrorCallback)(NSError * _Nullable, UIImage * _Nullable); | |
#endif /* ImageDownloaderCommonBlocks_h */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ProgressiveSingleImageDownloader.h | |
// AsyncImageDownloader | |
// | |
// Created by Paul Wood on 9/23/19. | |
// Copyright © 2019 Paul Wood. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
#import <UIKit/UIKit.h> | |
#import "ImageDownloaderCommonBlocks.h" | |
NS_ASSUME_NONNULL_BEGIN | |
@interface ProgressiveSingleImageDownloader : NSObject<NSURLSessionDownloadDelegate> | |
- (void)downloadBy_NSURLSession:(NSString *)urlString | |
progress:(ProgressBlock)progressHandler withErrorCallback:(ImageWithErrorCallback) callback; | |
@end | |
NS_ASSUME_NONNULL_END |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ProgressiveSingleImageDownloader.m | |
// AsyncImageDownloader | |
// | |
// Created by Paul Wood on 9/23/19. | |
// Copyright © 2019 Paul Wood. All rights reserved. | |
// | |
#import "ProgressiveSingleImageDownloader.h" | |
NSString *TASK_PROGRESS_CONTEXT = @"SingleImageDownloaderTaskProgressChanged"; | |
@interface ProgressiveSingleImageDownloader () | |
@property (nonatomic, retain) NSURLSessionDownloadTask* progressiveTask; | |
@property (nonatomic, retain) NSURLSession* progressiveSession; | |
@property (nonatomic, copy, nullable) void (^progressBlock)(NSNumber * _Nonnull); | |
@property (nonatomic, copy, nullable) void (^completionBlock)(NSError * _Nullable, UIImage * _Nullable); | |
@end | |
@implementation ProgressiveSingleImageDownloader | |
- (void)downloadBy_NSURLSession:(NSString *)urlString | |
progress:(ProgressBlock)progressHandler | |
withErrorCallback:(ImageWithErrorCallback) callback { | |
self.progressBlock = progressHandler; | |
self.completionBlock = callback; | |
NSURLSessionConfiguration *configuration = NSURLSession.sharedSession.configuration.copy; | |
self.progressiveSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil]; | |
NSURL *url = [NSURL URLWithString:urlString]; | |
NSURLRequest* request = [[NSURLRequest alloc] initWithURL:url]; | |
self.progressiveTask = [self.progressiveSession downloadTaskWithRequest:request]; | |
[self.progressiveTask resume]; | |
} | |
- (void)URLSession:(NSURLSession *)session | |
downloadTask:(NSURLSessionDownloadTask *)downloadTask | |
didFinishDownloadingToURL:(NSURL *)location { | |
__block UIImage *img = [UIImage imageWithData: [NSData dataWithContentsOfURL:location]]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
__weak typeof (self) weakSelf = self; | |
weakSelf.completionBlock(nil, img); | |
}); | |
} | |
- (void)URLSession:(NSURLSession *)session | |
downloadTask:(NSURLSessionDownloadTask *)downloadTask | |
didWriteData:(int64_t)bytesWritten | |
totalBytesWritten:(int64_t)totalBytesWritten | |
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { | |
double progress = (double)totalBytesWritten / (double)totalBytesExpectedToWrite; | |
NSNumber* progressNum = [NSNumber numberWithDouble:progress]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
self.progressBlock(progressNum); | |
}); | |
} | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.m | |
// AsyncImageDownloader | |
// | |
// Created by Paul Wood on 9/23/19. | |
// Copyright © 2019 Paul Wood. All rights reserved. | |
// | |
#import "ViewController.h" | |
#import "SingleImageDownloader.h" | |
#import "ProgressiveSingleImageDownloader.h" | |
@interface ViewController () | |
@property (nonatomic, retain) NSString* urlString; | |
@property (nonatomic, retain) SingleImageDownloader* imageDownloader; | |
@property (nonatomic, retain) ProgressiveSingleImageDownloader* progressiveDownloader; | |
@end | |
@implementation ViewController | |
- (void)viewDidLoad { | |
[super viewDidLoad]; | |
//Setup | |
self.imageName.text = @"Downloading Image"; | |
self.imageDownloader = [SingleImageDownloader new]; | |
self.progressiveDownloader = [ProgressiveSingleImageDownloader new]; | |
self.urlString = @"https://i.redd.it/4c4slwzhni901.png"; | |
[self.progressView setProgress:0.0 animated:NO]; | |
[self.progressiveDownloader downloadBy_NSURLSession:self.urlString | |
progress:^(NSNumber * _Nonnull progress) { | |
__weak typeof (self) weakSelf = self; | |
[weakSelf.progressView setHidden:NO]; | |
[weakSelf.progressView setProgress:progress.floatValue animated:YES]; | |
weakSelf.imageName.text = [NSString stringWithFormat:@"Downloading Image %@", progress]; | |
} | |
withErrorCallback:^(NSError * _Nullable err, UIImage * _Nullable img) { | |
__weak typeof (self) weakSelf = self; | |
if ( err == nil && img != nil) { | |
weakSelf.imageView.image = img; | |
[weakSelf.progressView setHidden:YES]; | |
weakSelf.imageName.text = @"Downloaded Image"; | |
} else if ( err != nil ) { | |
//handle error | |
weakSelf.imageName.text = @"Image Download Failed"; | |
} | |
}]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment