Commit 0c2a0a2d by Brent Gulanowski Committed by GitHub

Merge pull request #228 from Shopify/task/remove-polling

Remove left over polling in BUYApplePayAuthorizationDelegate.
parents ef2635a2 9e50f380
......@@ -38,10 +38,11 @@
const NSTimeInterval PollDelay = 0.5;
typedef void (^AddressUpdateCompletion)(PKPaymentAuthorizationStatus, NSArray<PKShippingMethod *> * _Nonnull, NSArray<PKPaymentSummaryItem *> * _Nonnull);
@interface BUYApplePayAuthorizationDelegate ()
@property (nonatomic, strong) BUYCheckout *checkout;
@property (nonatomic, strong) NSArray *shippingRates;
@property (nonatomic, strong) NSError *lastError;
......@@ -102,10 +103,8 @@ const NSTimeInterval PollDelay = 0.5;
[self.client completeCheckoutWithToken:checkout.token paymentToken:token completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout && error == nil) {
self.checkout = checkout;
[self pollUntilCheckoutIsComplete:self.checkout completion:completion];
}
else {
completion(PKPaymentAuthorizationStatusSuccess);
} else {
self.lastError = error;
completion(PKPaymentAuthorizationStatusFailure);
}
......@@ -133,16 +132,20 @@ const NSTimeInterval PollDelay = 0.5;
[controller dismissViewControllerAnimated:YES completion:nil];
}
-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingAddress:(ABRecordRef)address completion:(void (^)(PKPaymentAuthorizationStatus, NSArray<PKShippingMethod *> * _Nonnull, NSArray<PKPaymentSummaryItem *> * _Nonnull))completion
-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingAddress:(ABRecordRef)address completion:(AddressUpdateCompletion)completion
{
self.checkout.shippingAddress = [self buyAddressWithABRecord:address];
if ([self.checkout.shippingAddress isValidAddressForShippingRates]) {
[self updateCheckoutWithAddressCompletion:completion];
}
}
-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingContact:(PKContact *)contact completion:(void (^)(PKPaymentAuthorizationStatus, NSArray<PKShippingMethod *> * _Nonnull, NSArray<PKPaymentSummaryItem *> * _Nonnull))completion
-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingContact:(PKContact *)contact completion:(AddressUpdateCompletion)completion
{
self.checkout.shippingAddress = [self buyAddressWithContact:contact];
if ([self.checkout.shippingAddress isValidAddressForShippingRates]) {
[self updateCheckoutWithAddressCompletion:completion];
}
}
-(void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didSelectShippingMethod:(PKShippingMethod *)shippingMethod completion:(void (^)(PKPaymentAuthorizationStatus, NSArray<PKPaymentSummaryItem *> * _Nonnull))completion
......@@ -163,7 +166,7 @@ const NSTimeInterval PollDelay = 0.5;
#pragma mark -
- (void)updateCheckoutWithAddressCompletion:(void (^)(PKPaymentAuthorizationStatus, NSArray *shippingMethods, NSArray *summaryItems))completion
- (void)updateCheckoutWithAddressCompletion:(AddressUpdateCompletion)completion
{
// This method call is internal to selection of shipping address that are returned as partial from PKPaymentAuthorizationViewController
// However, to ensure we never set partialAddresses to NO, we want to guard the setter. Should PKPaymentAuthorizationViewController ever
......@@ -172,108 +175,59 @@ const NSTimeInterval PollDelay = 0.5;
self.checkout.partialAddresses = @YES;
}
if ([self.checkout.shippingAddress isValidAddressForShippingRates]) {
[self.client updateCheckout:self.checkout completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout && error == nil) {
if (checkout && !error) {
self.checkout = checkout;
[self getShippingRates:self.checkout completion:completion];
}
else {
else if (error) {
self.lastError = error;
completion(PKPaymentAuthorizationStatusInvalidShippingPostalAddress, nil, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}
}];
if (checkout.requiresShipping) {
self.shippingRates = @[];
[self updateShippingRatesCompletion:completion];
}
else {
completion(PKPaymentAuthorizationStatusInvalidShippingPostalAddress, nil, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
completion(PKPaymentAuthorizationStatusSuccess, @[], [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}
}];
}
#pragma mark - internal
- (BUYShippingRate *)rateForShippingMethod:(PKShippingMethod *)method
- (void)updateShippingRatesCompletion:(AddressUpdateCompletion)completion
{
BUYShippingRate *rate = nil;
NSString *identifier = [method identifier];
for (BUYShippingRate *method in _shippingRates) {
if ([[method shippingRateIdentifier] isEqual:identifier]) {
rate = method;
break;
}
}
return rate;
}
[self.client getShippingRatesForCheckoutWithToken:self.checkout.token completion:^(NSArray *shippingRates, BUYStatus status, NSError *error) {
- (void)getShippingRates:(BUYCheckout *)checkout completion:(void (^)(PKPaymentAuthorizationStatus status, NSArray *shippingMethods, NSArray *summaryItems))completion
{
// We're now fetching the rates from Shopify. This will will calculate shipping rates very similarly to how our web checkout.
// We then turn our BUYShippingRate objects into PKShippingMethods for Apple to present to the user.
self.shippingRates = shippingRates;
NSArray *shippingMethods = [BUYShippingRate buy_convertShippingRatesToShippingMethods:shippingRates];
if ([self.checkout requiresShipping] == NO) {
completion(PKPaymentAuthorizationStatusSuccess, nil, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}
else {
[self fetchShippingRates:^(PKPaymentAuthorizationStatus status, NSArray *methods, NSArray *summaryItems) {
if (shippingMethods.count > 0) {
NSArray *shippingMethods = [BUYShippingRate buy_convertShippingRatesToShippingMethods:_shippingRates];
if ([shippingMethods count] > 0) {
[self selectShippingMethod:shippingMethods[0] completion:^(BUYCheckout *checkout, NSError *error) {
if (checkout && error == nil) {
if (checkout && !error) {
self.checkout = checkout;
}
completion(error ? PKPaymentAuthorizationStatusFailure : PKPaymentAuthorizationStatusSuccess, shippingMethods, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}];
}
else {
} else {
self.lastError = [NSError errorWithDomain:BUYShopifyError code:BUYShopifyError_NoShippingMethodsToAddress userInfo:nil];
completion(status, nil, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
completion(PKPaymentAuthorizationStatusInvalidShippingPostalAddress, @[], [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}
}];
}
}
- (void)fetchShippingRates:(void (^)(PKPaymentAuthorizationStatus, NSArray *, NSArray *))completion
{
// Fetch shipping rates. This may take several seconds to get back from our shipping providers. You have to poll here.
self.shippingRates = @[];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block BUYStatus shippingStatus = BUYStatusUnknown;
do {
[self.client getShippingRatesForCheckoutWithToken:self.checkout.token completion:^(NSArray *shippingRates, BUYStatus status, NSError *error) {
shippingStatus = status;
if (error) {
completion(PKPaymentAuthorizationStatusInvalidShippingPostalAddress, nil, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}
else if (shippingStatus == BUYStatusComplete) {
self.shippingRates = shippingRates;
if ([self.shippingRates count] == 0) {
// Shipping address is not supported and no shipping rates were returned
if (completion) {
completion(PKPaymentAuthorizationStatusInvalidShippingPostalAddress, nil, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}
} else {
if (completion) {
completion(PKPaymentAuthorizationStatusSuccess, self.shippingRates, [self.checkout buy_summaryItemsWithShopName:self.shopName]);
}
}
#pragma mark - Internal -
- (BUYShippingRate *)rateForShippingMethod:(PKShippingMethod *)method
{
BUYShippingRate *rate = nil;
NSString *identifier = [method identifier];
for (BUYShippingRate *method in self.shippingRates) {
if ([[method shippingRateIdentifier] isEqual:identifier]) {
rate = method;
break;
}
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
if (shippingStatus != BUYStatusComplete && shippingStatus != BUYStatusUnknown) {
// Adjust as you see fit for your polling rate.
[NSThread sleepForTimeInterval:PollDelay];
}
} while (shippingStatus == BUYStatusProcessing);
});
return rate;
}
- (void)selectShippingMethod:(PKShippingMethod *)shippingMethod completion:(BUYDataCheckoutBlock)block
......@@ -284,32 +238,4 @@ const NSTimeInterval PollDelay = 0.5;
[self.client updateCheckout:self.checkout completion:block];
}
- (void)pollUntilCheckoutIsComplete:(BUYCheckout *)checkout completion:(void (^)(PKPaymentAuthorizationStatus status))completion
{
// Poll until done. At this point, we've sent the payment information to the Payment Gateway for your shop, and we're waiting for it to come back.
// This is sometimes a slow process, so we need to poll until we've received confirmation that money has been authorized or captured.
__block BUYStatus checkoutStatus = BUYStatusUnknown;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
while (checkout.token && checkoutStatus != BUYStatusFailed && checkoutStatus != BUYStatusComplete) {
[self.client getCompletionStatusOfCheckoutWithToken:self.checkout.token completion:^(BUYStatus status, NSError *error) {
checkoutStatus = status;
self.lastError = error;
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
if (checkoutStatus != BUYStatusComplete) {
[NSThread sleepForTimeInterval:PollDelay];
}
}
dispatch_async(dispatch_get_main_queue(), ^{
completion(checkoutStatus == BUYStatusComplete ? PKPaymentAuthorizationStatusSuccess : PKPaymentAuthorizationStatusFailure);
});
});
}
@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