Commit 726b6580 by Dima Bart

Merge pull request #220 from Shopify/task/status-aggregate

Add internal API for aggregate checkout status operation
parents e7632aba fff851b0
......@@ -29,6 +29,7 @@
#import "BUYClient+Routing.h"
#import "BUYRequestOperation.h"
#import "BUYCheckoutOperation.h"
#import "BUYStatusOperation.h"
#import "BUYAddress.h"
#import "BUYCheckout.h"
#import "BUYGiftCard.h"
......@@ -104,7 +105,7 @@
- (BUYOperation *)completeCheckoutWithToken:(NSString *)checkoutToken paymentToken:(id<BUYPaymentToken>)paymentToken completion:(BUYDataCheckoutBlock)block
{
BUYCheckoutOperation *operation = [[BUYCheckoutOperation alloc] initWithClient:self checkoutToken:checkoutToken token:paymentToken completion:block];
BUYCheckoutOperation *operation = [BUYCheckoutOperation operationWithClient:self checkoutToken:checkoutToken token:paymentToken completion:block];
[self startOperation:operation];
return operation;
}
......@@ -152,6 +153,15 @@
}];
}
- (NSOperation *)pollCompletionStatusAndGetCheckoutWithToken:(NSString *)token start:(BOOL)start completion:(BUYDataCheckoutBlock)block
{
BUYStatusOperation *operation = [BUYStatusOperation operationWithClient:self checkoutToken:token completion:block];
if (start) {
[self startOperation:operation];
}
return operation;
}
- (NSOperation *)postCheckout:(NSDictionary *)checkoutJSON completion:(BUYDataCheckoutBlock)block
{
return [self postRequestForURL:[self urlForCheckouts] object:checkoutJSON completionHandler:^(NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
......
......@@ -35,6 +35,10 @@ typedef void (^BUYClientRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResp
@interface BUYClient (Internal)
@property (nonatomic, strong) NSOperationQueue *requestQueue;
- (NSOperation *)pollCompletionStatusAndGetCheckoutWithToken:(NSString *)token start:(BOOL)start completion:(BUYDataCheckoutBlock)block;
- (NSOperation *)getRequestForURL:(NSURL *)url completionHandler:(BUYClientRequestJSONCompletion)completionHandler;
- (NSOperation *)deleteRequestForURL:(NSURL *)url completionHandler:(BUYClientRequestJSONCompletion)completionHandler;
......
......@@ -24,7 +24,8 @@
// THE SOFTWARE.
//
#import <Buy/BUYOperation.h>
#import <Buy/BUYGroupOperation.h>
#import <Buy/BUYStatusOperation.h>
NS_ASSUME_NONNULL_BEGIN
@class BUYClient;
......@@ -32,11 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
@protocol BUYPaymentToken;
typedef void (^BUYCheckoutOperationCompletion)(BUYCheckout * _Nullable checkout, NSError * _Nullable error);
@interface BUYCheckoutOperation : BUYOperation
@property (strong, nonatomic, readonly, nonnull) BUYClient *client;
@interface BUYCheckoutOperation : BUYGroupOperation
+ (instancetype)operationWithClient:(BUYClient *)client checkoutToken:(NSString *)checkoutToken token:(id<BUYPaymentToken>)token completion:(BUYCheckoutOperationCompletion)completion;
- (instancetype)initWithClient:(BUYClient *)client checkoutToken:(NSString *)checkoutToken token:(id<BUYPaymentToken>)token completion:(BUYCheckoutOperationCompletion)completion;
......
......@@ -29,15 +29,15 @@
#import "BUYClient+Internal.h"
#import "BUYPaymentToken.h"
#import "BUYRequestOperation.h"
#import "BUYStatusOperation.h"
@interface BUYCheckoutOperation ()
@property (strong, nonatomic, readonly) BUYClient *client;
@property (strong, nonatomic, readonly) NSString *checkoutToken;
@property (strong, nonatomic, readonly) id<BUYPaymentToken> token;
@property (strong, nonatomic, readonly) BUYCheckoutOperationCompletion completion;
@property (strong, atomic) NSArray *operations;
@end
@implementation BUYCheckoutOperation
......@@ -51,7 +51,7 @@
- (instancetype)initWithClient:(BUYClient *)client checkoutToken:(NSString *)checkoutToken token:(id<BUYPaymentToken>)token completion:(BUYCheckoutOperationCompletion)completion
{
self = [super init];
self = [super initWithRequestQueue:client.requestQueue operations:nil];
if (self) {
_client = client;
_token = token;
......@@ -63,25 +63,23 @@
#pragma mark - Finishing -
- (void)finishWithCheckout:(BUYCheckout *)checkout
- (void)finishWithObject:(id)object
{
[super finishWithObject:object];
if (self.cancelled) {
return;
}
[self finishExecution];
self.completion(checkout, nil);
self.completion(object, nil);
}
- (void)finishWithError:(NSError *)error
{
[super finishWithError:error];
if (self.cancelled) {
return;
}
[self cancelAllOperations];
[self finishExecution];
self.completion(nil, error);
}
......@@ -93,44 +91,12 @@
return;
}
[super startExecution];
NSOperation *beginOperation = [self createBeginOperation];
NSOperation *pollOperation = [self createPollOperation];
NSOperation *getOperation = [self createGetOperation];
[pollOperation addDependency:beginOperation];
[getOperation addDependency:pollOperation];
self.operations = @[
beginOperation,
pollOperation,
getOperation,
[self createBeginOperation],
[self createStatusOperation],
];
[self startAllOperations];
}
- (void)cancelExecution
{
[super cancelExecution];
[self cancelAllOperations];
}
#pragma mark - Start / Stop -
- (void)startAllOperations
{
for (BUYRequestOperation *operation in self.operations) {
[self.client startOperation:operation];
}
}
- (void)cancelAllOperations
{
for (BUYRequestOperation *operation in self.operations) {
[operation cancel];
}
[super startExecution];
}
#pragma mark - Operations -
......@@ -144,25 +110,11 @@
}];
}
- (NSOperation *)createPollOperation
{
BUYRequestOperation *operation = (BUYRequestOperation *)[self.client getCompletionStatusOfCheckoutWithToken:self.checkoutToken start:NO completion:^(BUYStatus status, NSError *error) {
if (status != BUYStatusComplete) {
[self finishWithError:error];
}
}];
operation.pollingHandler = ^BOOL (NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
return response.statusCode == BUYStatusProcessing;
};
return operation;
}
- (NSOperation *)createGetOperation
- (NSOperation *)createStatusOperation
{
return [self.client getCheckoutWithToken:self.checkoutToken start:NO completion:^(BUYCheckout *checkout, NSError *error) {
return [self.client pollCompletionStatusAndGetCheckoutWithToken:self.checkoutToken start:NO completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout) {
[self finishWithCheckout:checkout];
[self finishWithObject:checkout];
} else {
[self finishWithError:error];
}
......
//
// BUYGroupOperation.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// 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 "BUYOperation.h"
@interface BUYGroupOperation : BUYOperation
@property (strong, atomic) NSArray<NSOperation *> *operations;
+ (instancetype)groupOperationWithRequestQueue:(NSOperationQueue *)queue operations:(NSArray<NSOperation *> *)operations;
- (instancetype)initWithRequestQueue:(NSOperationQueue *)queue operations:(NSArray<NSOperation *> *)operations;
- (void)finishWithObject:(id)object;
- (void)finishWithError:(NSError *)error;
@end
//
// BUYGroupOperation.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// 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 "BUYGroupOperation.h"
#import "NSArray+BUYAdditions.h"
@interface BUYGroupOperation ()
@property (weak, nonatomic) NSOperationQueue *queue;
@end
@implementation BUYGroupOperation
#pragma mark - Init -
+ (instancetype)groupOperationWithRequestQueue:(NSOperationQueue *)queue operations:(NSArray<NSOperation *> *)operations
{
return [[[self class] alloc] initWithRequestQueue:queue operations:operations];
}
- (instancetype)initWithRequestQueue:(NSOperationQueue *)queue operations:(NSArray<NSOperation *> *)operations
{
self = [super init];
if (self) {
_queue = queue;
self.operations = operations;
}
return self;
}
#pragma mark - Finishing -
- (void)finishWithObject:(id)object
{
if (self.cancelled) {
return;
}
[self finishExecution];
}
- (void)finishWithError:(NSError *)error
{
if (self.cancelled) {
return;
}
[self cancelAllOperations];
[self finishExecution];
}
#pragma mark - Execution -
- (void)startExecution
{
if (self.cancelled) {
return;
}
[super startExecution];
[self linkDependencies];
[self startAllOperations];
}
- (void)cancelExecution
{
[super cancelExecution];
[self cancelAllOperations];
}
#pragma mark - Dependencies -
- (void)linkDependencies
{
NSArray *tail = [self.operations buy_tail];
if (tail.count > 0) {
NSOperation *former = self.operations.firstObject;
for (NSOperation *latter in tail) {
[latter addDependency:former];
former = latter;
}
}
}
#pragma mark - Start / Stop -
- (void)startAllOperations
{
for (NSOperation *operation in self.operations) {
[self.queue addOperation:operation];
}
}
- (void)cancelAllOperations
{
for (NSOperation *operation in self.operations) {
[operation cancel];
}
}
@end
//
// BUYStatusOperation.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// 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 "BUYGroupOperation.h"
NS_ASSUME_NONNULL_BEGIN
@class BUYCheckout;
@class BUYClient;
typedef void (^BUYCheckoutOperationCompletion)(BUYCheckout * _Nullable checkout, NSError * _Nullable error);
@interface BUYStatusOperation : BUYGroupOperation
+ (instancetype)operationWithClient:(BUYClient *)client checkoutToken:(NSString *)checkoutToken completion:(BUYCheckoutOperationCompletion)completion;
- (instancetype)initWithClient:(BUYClient *)client checkoutToken:(NSString *)checkoutToken completion:(BUYCheckoutOperationCompletion)completion;
@end
NS_ASSUME_NONNULL_END
//
// BUYStatusOperation.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// 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 "BUYStatusOperation.h"
#import "BUYClient+Checkout.h"
#import "BUYClient+Internal.h"
#import "BUYRequestOperation.h"
@interface BUYStatusOperation ()
@property (strong, nonatomic, readonly) BUYClient *client;
@property (strong, nonatomic, readonly) NSString *checkoutToken;
@property (strong, nonatomic, readonly) BUYCheckoutOperationCompletion completion;
@end
@implementation BUYStatusOperation
#pragma mark - Init -
+ (instancetype)operationWithClient:(BUYClient *)client checkoutToken:(NSString *)checkoutToken completion:(BUYCheckoutOperationCompletion)completion
{
return [[[self class] alloc] initWithClient:client checkoutToken:checkoutToken completion:completion];
}
- (instancetype)initWithClient:(BUYClient *)client checkoutToken:(NSString *)checkoutToken completion:(BUYCheckoutOperationCompletion)completion
{
self = [super initWithRequestQueue:client.requestQueue operations:nil];
if (self) {
_client = client;
_completion = completion;
_checkoutToken = checkoutToken;
}
return self;
}
#pragma mark - Execution -
- (void)startExecution
{
if (self.cancelled) {
return;
}
self.operations = @[
[self createPollOperation],
[self createGetOperation],
];
[super startExecution];
}
#pragma mark - Finishing -
- (void)finishWithObject:(id)object
{
[super finishWithObject:object];
if (self.cancelled) {
return;
}
self.completion(object, nil);
}
- (void)finishWithError:(NSError *)error
{
[super finishWithError:error];
if (self.cancelled) {
return;
}
self.completion(nil, error);
}
#pragma mark - Operations -
- (NSOperation *)createPollOperation
{
BUYRequestOperation *operation = (BUYRequestOperation *)[self.client getCompletionStatusOfCheckoutWithToken:self.checkoutToken start:NO completion:^(BUYStatus status, NSError *error) {
if (status != BUYStatusComplete) {
[self finishWithError:error];
}
}];
operation.pollingHandler = ^BOOL (NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
return response.statusCode == BUYStatusProcessing;
};
return operation;
}
- (NSOperation *)createGetOperation
{
return [self.client getCheckoutWithToken:self.checkoutToken start:NO completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout) {
[self finishWithObject:checkout];
} else {
[self finishWithError:error];
}
}];
}
@end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment