diff --git a/DFImageManager/Source/Core/Managing/DFImageManager.h b/DFImageManager/Source/Core/Managing/DFImageManager.h index 08cbbef..2fca6e3 100644 --- a/DFImageManager/Source/Core/Managing/DFImageManager.h +++ b/DFImageManager/Source/Core/Managing/DFImageManager.h @@ -25,7 +25,6 @@ @class DFImageManagerConfiguration; - /*! The DFImageManager and the related classes provides an implementation of the DFImageManaging protocol. The role of the DFImageManager is to manage the execution of image requests by delegating the actual job to a classes, implementing DFImageFetching, DFImageCaching, and DFImageProcessing protocols. @note Completion Block diff --git a/DFImageManager/Source/Core/Managing/DFImageManager.m b/DFImageManager/Source/Core/Managing/DFImageManager.m index bfd881e..812ee6e 100644 --- a/DFImageManager/Source/Core/Managing/DFImageManager.m +++ b/DFImageManager/Source/Core/Managing/DFImageManager.m @@ -708,6 +708,11 @@ - (void)_cancelRequestWithHandler:(_DFImageHandler *)handler { _DFImageManagerTask *task = handler.task; if ([task.handlers containsObject:handler]) { [task removeHandler:handler]; + if (handler.completionHandler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler.completionHandler(nil, @{ DFImageInfoErrorKey: [NSError errorWithDomain:DFImageManagerErrorDomain code:DFImageManagerErrorCancelled userInfo:nil] }); + }); + } if (task.handlers.count == 0) { [task cancel]; [self _removeTask:task]; diff --git a/DFImageManager/Source/Core/Support/DFImageManagerDefines.h b/DFImageManager/Source/Core/Support/DFImageManagerDefines.h index dd8e85a..f2ac013 100644 --- a/DFImageManager/Source/Core/Support/DFImageManagerDefines.h +++ b/DFImageManager/Source/Core/Support/DFImageManagerDefines.h @@ -74,3 +74,11 @@ typedef NS_ENUM(NSInteger, DFImageRequestPriority) { /*! Progress handler, called on a main thread. */ typedef void (^DFImageRequestProgressHandler)(double progress); + +/*! The error domain for DFImageManager. + */ +extern NSString *const DFImageManagerErrorDomain; + +/*! Returned when an image request is cancelled. + */ +static const NSInteger DFImageManagerErrorCancelled = -1; diff --git a/DFImageManager/Source/Core/Support/DFImageManagerDefines.m b/DFImageManager/Source/Core/Support/DFImageManagerDefines.m index ca692d7..302919f 100644 --- a/DFImageManager/Source/Core/Support/DFImageManagerDefines.m +++ b/DFImageManager/Source/Core/Support/DFImageManagerDefines.m @@ -25,5 +25,6 @@ NSString *const DFImageInfoRequestIDKey = @"DFImageInfoRequestIDKey"; NSString *const DFImageInfoErrorKey = @"DFImageInfoErrorKey"; - CGSize const DFImageMaximumSize = { FLT_MAX, FLT_MAX }; + +NSString *const DFImageManagerErrorDomain = @"DFImageManagerErrorDomain"; diff --git a/DFImageManager/Source/Core/Support/DFImageRequestID.h b/DFImageManager/Source/Core/Support/DFImageRequestID.h index 4f6c325..b3342d0 100644 --- a/DFImageManager/Source/Core/Support/DFImageRequestID.h +++ b/DFImageManager/Source/Core/Support/DFImageRequestID.h @@ -27,7 +27,7 @@ */ @interface DFImageRequestID : NSObject -/*! Advices the image manager that the request should be cancelled. +/*! Advices the image manager that the request should be cancelled. The completion block will be called with error value of { DFImageManagerErrorDomain, DFImageManagerErrorCancelled } */ - (void)cancel; diff --git a/DFImageManager/Source/UI/UIImageView+DFImageManager.m b/DFImageManager/Source/UI/UIImageView+DFImageManager.m index b6012eb..4ae2cbc 100644 --- a/DFImageManager/Source/UI/UIImageView+DFImageManager.m +++ b/DFImageManager/Source/UI/UIImageView+DFImageManager.m @@ -55,7 +55,9 @@ - (void)df_setImageWithResource:(id)resource targetSize:(CGSize)targetSize conte UIImageView *__weak weakSelf = self; DFImageRequest *request = [DFImageRequest requestWithResource:resource targetSize:targetSize contentMode:contentMode options:options]; [[DFImageManager sharedManager] requestImageForRequest:request completion:^(UIImage *image, NSDictionary *info) { - weakSelf.image = image; + if (image) { + weakSelf.image = image; + } }]; } diff --git a/DFImageManager/Tests/Tests/TDFImageManager.m b/DFImageManager/Tests/Tests/TDFImageManager.m index 31cd76b..fb3f532 100644 --- a/DFImageManager/Tests/Tests/TDFImageManager.m +++ b/DFImageManager/Tests/Tests/TDFImageManager.m @@ -144,6 +144,21 @@ - (void)testThatCancelsFetchOperationWithTwoHandlers { [self waitForExpectationsWithTimeout:3.0 handler:nil]; } +- (void)testThatCompletionHandlerForCancelledRequestIsCalled { + _fetcher.queue.suspended = YES; + + XCTestExpectation *expectation = [self expectationWithDescription:@""]; + DFImageRequestID *requestID = [_manager requestImageForResource:[TDFMockResource resourceWithID:@"ID01"] completion:^(UIImage *image, NSDictionary *info) { + NSError *error = info[DFImageInfoErrorKey]; + XCTAssertNotNil(error); + XCTAssertTrue([error.domain isEqualToString:DFImageManagerErrorDomain]); + XCTAssertEqual(error.code, DFImageManagerErrorCancelled); + [expectation fulfill]; + }]; + [requestID cancel]; + [self waitForExpectationsWithTimeout:3.0 handler:nil]; +} + #pragma mark - Operation Reuse - (void)testThatOperationsAreReused { @@ -325,6 +340,7 @@ - (void)testThatPriorityIsChanged { XCTAssertEqual(operation.queuePriority, (NSOperationQueuePriority)DFImageRequestPriorityVeryLow); [expectation fulfill]; }]; + [NSThread sleepForTimeInterval:0.05]; // Wait till operation is created [requestID setPriority:DFImageRequestPriorityVeryLow]; _fetcher.queue.suspended = NO;