vk-ios-sdk/library/Source/API/upload/VKUploadPhotoBase.m

142 lines
5.3 KiB
Objective-C
Executable File

//
// VKPhotoUploadBase.m
//
// Copyright (c) 2014 VK.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "VKUploadPhotoBase.h"
#import "VKUploadImage.h"
extern inline NSString *VKKeyPathFromOperationState(VKOperationState state);
extern inline BOOL VKStateTransitionIsValid(VKOperationState fromState, VKOperationState toState, BOOL isCancelled);
@interface VKUploadPhotoBase ()
@property(nonatomic, readwrite, strong) NSOperation *executionOperation;
@end
@implementation VKUploadPhotoBase
@dynamic executionOperation;
- (instancetype)initWithImage:(UIImage *)image parameters:(VKImageParameters *)parameters {
self = [super init];
self.image = image;
self.imageParameters = parameters;
return self;
}
- (NSOperation *)createExecutionOperation {
VKOperation *op = [VKUploadImageOperation operationWithUploadRequest:self];
[op setResponseQueue:self.responseQueue];
self.executionOperation = op;
return op;
}
- (VKRequest *)getServerRequest {
@throw [NSException exceptionWithName:@"Abstract function" reason:@"getServerRequest should be overriden" userInfo:nil];
}
- (VKRequest *)getSaveRequest:(VKResponse *)response {
@throw [NSException exceptionWithName:@"Abstract function" reason:@"getSaveRequest should be overriden" userInfo:nil];
}
- (NSString *)methodName {
return NSStringFromClass([self class]);
}
@end
@interface VKUploadImageOperation ()
@property(nonatomic, strong) VKUploadPhotoBase *uploadRequest;
@property(readwrite, nonatomic, assign) VKOperationState state;
@property(nonatomic, strong) VKRequest *lastLoadingRequest;
@end
@implementation VKUploadImageOperation
@dynamic state;
+ (instancetype)operationWithUploadRequest:(VKUploadPhotoBase *)uploadRequest {
VKUploadImageOperation *operation = [VKUploadImageOperation new];
operation.uploadRequest = uploadRequest;
return operation;
}
- (void)start {
void (^originalErrorBlock)(NSError *) = [_uploadRequest.errorBlock copy];
__weak VKUploadImageOperation *weakSelf = self;
_uploadRequest.errorBlock = ^(NSError *error) {
[weakSelf finish];
if (originalErrorBlock)
originalErrorBlock(error);
};
self.state = VKOperationExecutingState;
VKRequest *serverRequest = [_uploadRequest getServerRequest];
serverRequest.responseQueue = self.responseQueue;
serverRequest.completeBlock = ^(VKResponse *response) {
NSData *imageData = nil;
switch (_uploadRequest.imageParameters.imageType) {
case VKImageTypeJpg:
imageData = UIImageJPEGRepresentation(_uploadRequest.image, _uploadRequest.imageParameters.jpegQuality);
break;
case VKImageTypePng:
imageData = UIImagePNGRepresentation(_uploadRequest.image);
break;
default:
break;
}
_uploadRequest.image = nil;
VKRequest *postFileRequest = [VKRequest photoRequestWithPostUrl:response.json[@"upload_url"]
withPhotos:@[[VKUploadImage uploadImageWithData:imageData andParams:_uploadRequest.imageParameters]]];
postFileRequest.progressBlock = _uploadRequest.progressBlock;
postFileRequest.responseQueue = self.responseQueue;
self.lastLoadingRequest = postFileRequest;
[postFileRequest executeWithResultBlock:^(VKResponse *response) {
VKRequest *saveRequest = [_uploadRequest getSaveRequest:response];
saveRequest.responseQueue = self.responseQueue;
self.lastLoadingRequest = saveRequest;
[saveRequest executeWithResultBlock:^(VKResponse *response) {
response.request = _uploadRequest;
if (_uploadRequest.completeBlock) _uploadRequest.completeBlock(response);
[weakSelf finish];
} errorBlock:_uploadRequest.errorBlock];
} errorBlock:_uploadRequest.errorBlock];
};
serverRequest.errorBlock = _uploadRequest.errorBlock;
self.lastLoadingRequest = serverRequest;
[serverRequest start];
}
- (void)finish {
self.state = VKOperationFinishedState;
self.uploadRequest = nil;
self.lastLoadingRequest = nil;
}
- (void)cancel {
[super cancel];
[self.lastLoadingRequest cancel];
}
@end