Commit e5aed2b3 by Dima Bart

Merge pull request #167 from Shopify/feature/nsoperation-aggregate

Migrate to NSOperation-based network requests.
parents d390ebc6 49ddbd7e
......@@ -88,12 +88,12 @@ extension OrdersViewController: UITableViewDataSource {
func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
let order = self.orders[section]
return "Order total: $\(order.totalPrice) \(order.currency)"
return "Order total: $\(order.totalPrice)"
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! LineItemCell
let lineItem = self.orders[indexPath.section].lineItems[indexPath.row]
let lineItem = self.orders[indexPath.section].lineItemsArray[indexPath.row]
cell.setLineItem(lineItem)
......@@ -106,9 +106,7 @@ extension OrdersViewController: UITableViewDataSource {
//
extension BUYOrder {
var lineItems: [BUYLineItem] {
var items = self.fulfilledLineItems
items.appendContentsOf(self.unfulfilledLineItems)
return items
var lineItemsArray: [BUYLineItem] {
return self.lineItems.array as! [BUYLineItem]
}
}
......@@ -1303,7 +1303,7 @@
NSString *apiKey = [self shouldUseMocks] ? BUYAPIKey_Placeholder : self.apiKey;
NSString *appId = [self shouldUseMocks] ? BUYAppId_Placeholder : self.appId;
BUYClient *testClient = [[BUYClient alloc] initWithShopDomain:shopDomain apiKey:apiKey appId:appId];
testClient.queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
testClient.callbackQueue = [NSOperationQueue new];
[testClient getShop:^(BUYShop *shop, NSError *error) {
BOOL isMainThread = [NSThread isMainThread];
......
//
// BUYOperationTests.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 <XCTest/XCTest.h>
#import "BUYOperation.h"
@interface BUYOperationTests : XCTestCase
@end
@implementation BUYOperationTests
#pragma mark - Init -
- (void)testInit
{
BUYOperation *operation = [[BUYOperation alloc] init];
XCTAssertNotNil(operation);
}
#pragma mark - State -
- (void)testNormalExecutionFlow
{
BUYOperation *operation = [[BUYOperation alloc] init];
XCTAssertTrue(operation.isReady);
[operation start];
XCTAssertTrue(operation.isExecuting);
[operation finishExecution];
XCTAssertTrue(operation.isFinished);
XCTAssertFalse(operation.isCancelled);
}
- (void)testCancelledExecutionFlow
{
BUYOperation *operation = [[BUYOperation alloc] init];
XCTAssertTrue(operation.isReady);
[operation start];
XCTAssertTrue(operation.isExecuting);
[operation cancel];
XCTAssertTrue(operation.isCancelled);
XCTAssertFalse(operation.isFinished);
[operation cancelExecution];
XCTAssertFalse(operation.isFinished); // State isn't changed if operation is cancelled
}
@end
......@@ -66,7 +66,7 @@ FOUNDATION_EXPORT const unsigned char BuyVersionString[];
#import <Buy/BUYClient+Customers.h>
#import <Buy/BUYClient+Checkout.h>
#import <Buy/BUYClient+Storefront.h>
#import <Buy/BUYClient+Checkout.h>
#import <Buy/BUYRequestOperation.h>
#import <Buy/BUYError.h>
#import <Buy/BUYError+BUYAdditions.h>
#import <Buy/BUYManagedObject.h>
......
......@@ -76,9 +76,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param checkout BUYCheckout to create on Shopify
* @param block (^BUYDataCheckoutBlock)(BUYCheckout *checkout, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)createCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
- (BUYRequestOperation *)createCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
/**
* Builds a checkout on Shopify using a Cart Token from an existing cart on your Shopify store's storefront.
......@@ -87,9 +87,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param cartToken Cart Token associated with an existing BUYCheckout on Shopify
* @param block (^BUYDataCheckoutBlock)(BUYCheckout *checkout, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)createCheckoutWithCartToken:(NSString *)cartToken completion:(BUYDataCheckoutBlock)block;
- (BUYRequestOperation *)createCheckoutWithCartToken:(NSString *)cartToken completion:(BUYDataCheckoutBlock)block;
/**
* Applies a gift card code to the checkout.
......@@ -98,9 +98,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param checkout An existing BUYCheckout on Shopify
* @param block (^BUYDataCheckoutBlock)(BUYCheckout *checkout, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)applyGiftCardWithCode:(NSString *)giftCardCode toCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
- (BUYRequestOperation *)applyGiftCardWithCode:(NSString *)giftCardCode toCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
/**
* Removes a gift card from the checkout.
......@@ -109,9 +109,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param checkout An existing BUYCheckout on Shopify
* @param block (^BUYDataCheckoutBlock)(BUYCheckout *checkout, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)removeGiftCard:(BUYGiftCard *)giftCard fromCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
- (BUYRequestOperation *)removeGiftCard:(BUYGiftCard *)giftCard fromCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
/**
* Retrieves an updated version of a BUYCheckout from Shopify.
......@@ -122,9 +122,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param checkout The BUYCheckout to retrieve (updated) from Shopify
* @param block (^BUYDataCheckoutBlock)(BUYCheckout *checkout, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
- (BUYRequestOperation *)getCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
/**
* Updates a given BUYCheckout on Shopify.
......@@ -137,9 +137,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param checkout The BUYCheckout to updated on Shopify
* @param block (^BUYDataCheckoutBlock)(BUYCheckout *checkout, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)updateCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
- (BUYRequestOperation *)updateCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
/**
* Finalizes the BUYCheckout and charges the payment provider (ex: Credit Card, Apple Pay, etc).
......@@ -153,9 +153,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param paymentToken Opaque payment token object. May be nil if the total checkout amount is equal to $0.00
* @param block (^BUYDataCheckoutBlock)(BUYCheckout *checkout, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)completeCheckout:(BUYCheckout *)checkout paymentToken:(_Nullable id<BUYPaymentToken>)paymentToken completion:(BUYDataCheckoutBlock)block;
- (BUYRequestOperation *)completeCheckout:(BUYCheckout *)checkout paymentToken:(_Nullable id<BUYPaymentToken>)paymentToken completion:(BUYDataCheckoutBlock)block;
/**
* Retrieve the status of a BUYCheckout. This checks the status of the current payment processing job for the provided checkout.
......@@ -164,9 +164,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param checkout The BUYCheckout to retrieve completion status for
* @param block (^BUYDataStatusBlock)(BUYCheckout *checkout, BUYStatus status, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getCompletionStatusOfCheckout:(BUYCheckout *)checkout completion:(BUYDataStatusBlock)block;
- (BUYRequestOperation *)getCompletionStatusOfCheckout:(BUYCheckout *)checkout completion:(BUYDataStatusBlock)block;
/**
* Retrieve the status of a checkout given a URL obtained in the UIApplicationDelegate method `application:sourceApplication:annotation`
......@@ -174,9 +174,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param url The URL resource used to open the application
* @param block (^BUYDataStatusBlock)(BUYCheckout *checkout, BUYStatus status, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getCompletionStatusOfCheckoutURL:(NSURL *)url completion:(BUYDataStatusBlock)block;
- (BUYRequestOperation *)getCompletionStatusOfCheckoutURL:(NSURL *)url completion:(BUYDataStatusBlock)block;
#pragma mark - Shipping Rates
......@@ -187,9 +187,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param checkout The BUYCheckout to retrieve shipping rates for
* @param block (^BUYDataShippingRatesBlock)(NSArray *shippingRates, BUYStatus status, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getShippingRatesForCheckout:(BUYCheckout *)checkout completion:(BUYDataShippingRatesBlock)block;
- (BUYRequestOperation *)getShippingRatesForCheckout:(BUYCheckout *)checkout completion:(BUYDataShippingRatesBlock)block;
#pragma mark - Payment Management
......@@ -207,9 +207,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* used (if provided) to help with fraud checking.
* @param block (^BUYDataCreditCardBlock)(BUYCheckout *checkout, NSString *paymentSessionId, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)storeCreditCard:(BUYCreditCard *)creditCard checkout:(BUYCheckout *)checkout completion:(BUYDataCreditCardBlock)block;
- (BUYRequestOperation *)storeCreditCard:(BUYCreditCard *)creditCard checkout:(BUYCheckout *)checkout completion:(BUYDataCreditCardBlock)block;
/**
* Convenience method to release all product inventory reservations by setting its
......@@ -219,9 +219,9 @@ typedef void (^BUYDataGiftCardBlock)(BUYGiftCard * _Nullable giftCard, NSError *
* @param checkout The BUYCheckout to expire
* @param block (^BUYDataCheckoutBlock)(BUYCheckout *checkout, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)removeProductReservationsFromCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
- (BUYRequestOperation *)removeProductReservationsFromCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block;
@end
......
......@@ -60,7 +60,7 @@
}
}
- (NSURLSessionDataTask *)createCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
- (BUYRequestOperation *)createCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
{
BUYAssert(checkout, @"Failed to create checkout. Invalid checkout object.");
......@@ -71,7 +71,7 @@
return [self postCheckout:json completion:block];
}
- (NSURLSessionDataTask *)createCheckoutWithCartToken:(NSString *)cartToken completion:(BUYDataCheckoutBlock)block
- (BUYRequestOperation *)createCheckoutWithCartToken:(NSString *)cartToken completion:(BUYDataCheckoutBlock)block
{
BUYAssert(cartToken, @"Failed to create checkout. Invalid cart token");
BUYCheckout *checkout = [self.modelManager checkoutwithCartToken:cartToken];
......@@ -81,14 +81,14 @@
return [self postCheckout:json completion:block];
}
- (NSURLSessionDataTask *)postCheckout:(NSDictionary *)checkoutJSON completion:(BUYDataCheckoutBlock)block
- (BUYRequestOperation *)postCheckout:(NSDictionary *)checkoutJSON completion:(BUYDataCheckoutBlock)block
{
return [self postRequestForURL:[self urlForCheckouts] object:checkoutJSON completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
[self handleCheckoutResponse:json error:error block:block];
}];
}
- (NSURLSessionDataTask *)applyGiftCardWithCode:(NSString *)giftCardCode toCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
- (BUYRequestOperation *)applyGiftCardWithCode:(NSString *)giftCardCode toCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
{
BUYAssertCheckout(checkout);
BUYAssert(giftCardCode.length > 0, @"Failed to apply gift card code. Invalid gift card code.");
......@@ -104,7 +104,7 @@
}];
}
- (NSURLSessionDataTask *)removeGiftCard:(BUYGiftCard *)giftCard fromCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
- (BUYRequestOperation *)removeGiftCard:(BUYGiftCard *)giftCard fromCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
{
BUYAssertCheckout(checkout);
BUYAssert(giftCard.identifier, @"Failed to remove gift card. Gift card must have a valid identifier.");
......@@ -135,7 +135,7 @@
[checkout markAsClean];
}
- (NSURLSessionDataTask *)getCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
- (BUYRequestOperation *)getCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
{
BUYAssertCheckout(checkout);
......@@ -145,7 +145,7 @@
}];
}
- (NSURLSessionDataTask *)updateCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
- (BUYRequestOperation *)updateCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
{
BUYAssertCheckout(checkout);
......@@ -155,7 +155,7 @@
}];
}
- (NSURLSessionDataTask*)completeCheckout:(BUYCheckout *)checkout paymentToken:(id<BUYPaymentToken>)paymentToken completion:(BUYDataCheckoutBlock)block
- (BUYRequestOperation*)completeCheckout:(BUYCheckout *)checkout paymentToken:(id<BUYPaymentToken>)paymentToken completion:(BUYDataCheckoutBlock)block
{
BUYAssertCheckout(checkout);
......@@ -169,14 +169,14 @@
}];
}
- (NSURLSessionDataTask *)getCompletionStatusOfCheckout:(BUYCheckout *)checkout completion:(BUYDataStatusBlock)block
- (BUYRequestOperation *)getCompletionStatusOfCheckout:(BUYCheckout *)checkout completion:(BUYDataStatusBlock)block
{
BUYAssertCheckout(checkout);
return [self getCompletionStatusOfCheckoutToken:checkout.token completion:block];
}
- (NSURLSessionDataTask *)getCompletionStatusOfCheckoutURL:(NSURL *)url completion:(BUYDataStatusBlock)block
- (BUYRequestOperation *)getCompletionStatusOfCheckoutURL:(NSURL *)url completion:(BUYDataStatusBlock)block
{
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
......@@ -193,7 +193,7 @@
return [self getCompletionStatusOfCheckoutToken:token completion:block];
}
- (NSURLSessionDataTask *)getCompletionStatusOfCheckoutToken:(NSString *)token completion:(BUYDataStatusBlock)block
- (BUYRequestOperation *)getCompletionStatusOfCheckoutToken:(NSString *)token completion:(BUYDataStatusBlock)block
{
NSURL *route = [self urlForCheckoutsProcessingWithToken:token];
return [self getRequestForURL:route completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
......@@ -204,7 +204,7 @@
#pragma mark - Shipping Rates
- (NSURLSessionDataTask *)getShippingRatesForCheckout:(BUYCheckout *)checkout completion:(BUYDataShippingRatesBlock)block
- (BUYRequestOperation *)getShippingRatesForCheckout:(BUYCheckout *)checkout completion:(BUYDataShippingRatesBlock)block
{
BUYAssertCheckout(checkout);
......@@ -225,7 +225,7 @@
#pragma mark - Payments
- (NSURLSessionDataTask *)storeCreditCard:(BUYCreditCard *)creditCard checkout:(BUYCheckout *)checkout completion:(BUYDataCreditCardBlock)completion
- (BUYRequestOperation *)storeCreditCard:(BUYCreditCard *)creditCard checkout:(BUYCheckout *)checkout completion:(BUYDataCreditCardBlock)completion
{
BUYAssertCheckout(checkout);
BUYAssert(creditCard, @"Failed to store credit card. No credit card provided.");
......@@ -246,7 +246,7 @@
}];
}
- (NSURLSessionDataTask *)removeProductReservationsFromCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
- (BUYRequestOperation *)removeProductReservationsFromCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
{
BUYAssertCheckout(checkout);
......
......@@ -74,9 +74,9 @@ typedef void (^BUYDataOrdersBlock)(NSArray <BUYOrder*> * _Nullable orders, NSErr
* @param customerID A customer ID retrieved from either customer creation or login
* @param block (BUYCustomer *customer, NSError *error)
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getCustomerWithID:(NSString *)customerID callback:(BUYDataCustomerBlock)block;
- (BUYRequestOperation *)getCustomerWithID:(NSString *)customerID callback:(BUYDataCustomerBlock)block;
/**
* POST /api/customers
......@@ -86,11 +86,11 @@ typedef void (^BUYDataOrdersBlock)(NSArray <BUYOrder*> * _Nullable orders, NSErr
* @param credentials Credentials object containing items for required fields
* @param block (BUYCustomer *customer, NSString *token, NSError *error)
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*
* @discussion The customer is automatically logged in using -loginCustomerWithCredentials:callback:
*/
- (NSURLSessionDataTask *)createCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block;
- (BUYRequestOperation *)createCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block;
/**
* POST /api/customers/customer_token
......@@ -100,9 +100,9 @@ typedef void (^BUYDataOrdersBlock)(NSArray <BUYOrder*> * _Nullable orders, NSErr
* @param credentials Credentials object containing items for required fields
* @param block (BUYCustomer *customer, NSString *token, NSError *error)
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)loginCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block;
- (BUYRequestOperation *)loginCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block;
/**
* POST /api/customers/recover
......@@ -111,9 +111,9 @@ typedef void (^BUYDataOrdersBlock)(NSArray <BUYOrder*> * _Nullable orders, NSErr
* @param email Email to send the password reset to
* @param block (BUYStatus status, NSError *error)
*
* @return the associated NSURLSessionDataTask
* @return the associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)recoverPasswordForCustomer:(NSString *)email callback:(BUYDataStatusBlock)block;
- (BUYRequestOperation *)recoverPasswordForCustomer:(NSString *)email callback:(BUYDataStatusBlock)block;
/**
* PUT /api/customers/:customer_id/customer_token/renew
......@@ -122,9 +122,9 @@ typedef void (^BUYDataOrdersBlock)(NSArray <BUYOrder*> * _Nullable orders, NSErr
* @param customerID ID of customer renewing token
* @param block (NSString *token, NSError *error)
*
* @return the associated NSURLSessionDataTask
* @return the associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)renewCustomerTokenWithID:(NSString *)customerID callback:(BUYDataTokenBlock)block;
- (BUYRequestOperation *)renewCustomerTokenWithID:(NSString *)customerID callback:(BUYDataTokenBlock)block;
/**
* PUT /api/customers/:customer_id/activate
......@@ -135,9 +135,9 @@ typedef void (^BUYDataOrdersBlock)(NSArray <BUYOrder*> * _Nullable orders, NSErr
* @param customerToken Token contained in activation URL
* @param block (BUYCustomer *customer, NSString *token, NSError *error)
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)activateCustomerWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block;
- (BUYRequestOperation *)activateCustomerWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block;
/**
* PUT /api/customers/:customer_id/reset
......@@ -148,9 +148,9 @@ typedef void (^BUYDataOrdersBlock)(NSArray <BUYOrder*> * _Nullable orders, NSErr
* @param customerToken Token contained in reset URL
* @param block (BUYCustomer *customer, NSString *token, NSError *error)
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)resetPasswordWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block;
- (BUYRequestOperation *)resetPasswordWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block;
/**
* GET /api/customers/:customer_id/orders
......@@ -159,9 +159,9 @@ typedef void (^BUYDataOrdersBlock)(NSArray <BUYOrder*> * _Nullable orders, NSErr
* @param token An auth token retrieved from customer creation or customer login API
* @param block (NSArray <BUYOrder*> *orders, NSError *error)
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getOrdersForCustomerWithCallback:(BUYDataOrdersBlock)block;
- (BUYRequestOperation *)getOrdersForCustomerWithCallback:(BUYDataOrdersBlock)block;
@end
......
......@@ -38,7 +38,7 @@
#pragma mark - Customer
- (NSURLSessionDataTask *)getCustomerWithID:(NSString *)customerID callback:(BUYDataCustomerBlock)block
- (BUYRequestOperation *)getCustomerWithID:(NSString *)customerID callback:(BUYDataCustomerBlock)block
{
NSURL *route = [self urlForCustomersWithID:customerID];
return [self getRequestForURL:route completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
......@@ -50,7 +50,7 @@
}];
}
- (NSURLSessionDataTask *)createCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block
- (BUYRequestOperation *)createCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block
{
NSURL *route = [self urlForCustomers];
return [self postRequestForURL:route object:credentials.JSONRepresentation completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
......@@ -63,7 +63,7 @@
}];
}
- (NSURLSessionDataTask *)createTokenForCustomerWithCredentials:(BUYAccountCredentials *)credentials customerJSON:(NSDictionary *)customerJSON callback:(BUYDataCustomerTokenBlock)block
- (BUYRequestOperation *)createTokenForCustomerWithCredentials:(BUYAccountCredentials *)credentials customerJSON:(NSDictionary *)customerJSON callback:(BUYDataCustomerTokenBlock)block
{
NSURL *route = [self urlForCustomersToken];
return [self postRequestForURL:route object:credentials.JSONRepresentation completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
......@@ -87,16 +87,15 @@
}];
}
- (NSURLSessionDataTask *)loginCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block
- (BUYRequestOperation *)loginCustomerWithCredentials:(BUYAccountCredentials *)credentials callback:(BUYDataCustomerTokenBlock)block
{
return [self createTokenForCustomerWithCredentials:credentials customerJSON:nil callback:block];
}
- (NSURLSessionDataTask *)recoverPasswordForCustomer:(NSString *)email callback:(BUYDataStatusBlock)block
- (BUYRequestOperation *)recoverPasswordForCustomer:(NSString *)email callback:(BUYDataStatusBlock)block
{
NSURL *route = [self urlForCustomersPasswordRecovery];
return [self postRequestForURL:route object:@{@"email": email} completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (!error) {
error = [self errorFromJSON:json response:response];
......@@ -106,13 +105,12 @@
}];
}
- (NSURLSessionDataTask *)renewCustomerTokenWithID:(NSString *)customerID callback:(BUYDataTokenBlock)block
- (BUYRequestOperation *)renewCustomerTokenWithID:(NSString *)customerID callback:(BUYDataTokenBlock)block
{
if (self.customerToken) {
NSURL *route = [self urlForCustomersTokenRenewalWithID:customerID];
return [self putRequestForURL:route object:nil completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSString *accessToken = nil;
if (json && !error) {
BUYAuthenticatedResponse *authenticatedResponse = [BUYAuthenticatedResponse responseWithJSON:json];
......@@ -132,7 +130,7 @@
}
}
- (NSURLSessionDataTask *)activateCustomerWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block
- (BUYRequestOperation *)activateCustomerWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block
{
NSURL *route = [self urlForCustomersActivationWithID:customerID parameters:@{
@"token": customerToken,
......@@ -150,7 +148,7 @@
}];
}
- (NSURLSessionDataTask *)resetPasswordWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block
- (BUYRequestOperation *)resetPasswordWithCredentials:(BUYAccountCredentials *)credentials customerID:(NSString *)customerID customerToken:(NSString *)customerToken callback:(BUYDataCustomerTokenBlock)block
{
NSURL *route = [self urlForCustomersPasswordResetWithID:customerID parameters:@{
@"token": customerToken,
......@@ -168,7 +166,7 @@
}];
}
- (NSURLSessionDataTask *)getOrdersForCustomerWithCallback:(BUYDataOrdersBlock)block
- (BUYRequestOperation *)getOrdersForCustomerWithCallback:(BUYDataOrdersBlock)block
{
NSURL *route = [self urlForCustomersOrders];
return [self getRequestForURL:route completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
......
......@@ -33,12 +33,12 @@ static NSString * const BUYClientCustomerAccessToken = @"X-Shopify-Customer-Acce
@interface BUYClient (Internal)
- (NSURLSessionDataTask *)getRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDataTask *)deleteRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (BUYRequestOperation *)getRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (BUYRequestOperation *)deleteRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDataTask *)postRequestForURL:(NSURL *)url object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDataTask *)putRequestForURL:(NSURL *)url object:(id<BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDataTask *)patchRequestForURL:(NSURL *)url object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (BUYRequestOperation *)postRequestForURL:(NSURL *)url object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (BUYRequestOperation *)putRequestForURL:(NSURL *)url object:(id<BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (BUYRequestOperation *)patchRequestForURL:(NSURL *)url object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler;
- (BUYStatus)statusForStatusCode:(NSUInteger)statusCode error:(NSError *)error;
- (NSError *)errorFromJSON:(NSDictionary *)json response:(NSURLResponse *)response;
......
......@@ -126,9 +126,9 @@ typedef void (^BUYDataProductListBlock)(NSArray<BUYProduct *> * _Nullable produc
*
* @param block (^BUYDataShopBlock)(BUYShop *shop, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getShop:(BUYDataShopBlock)block;
- (BUYRequestOperation *)getShop:(BUYDataShopBlock)block;
/**
* Fetches a single page of products for the shop.
......@@ -136,9 +136,9 @@ typedef void (^BUYDataProductListBlock)(NSArray<BUYProduct *> * _Nullable produc
* @param page Page to request. Pages start at 1.
* @param block (^BUYDataProductListBlock)(NSArray *products, NSUInteger page, BOOL reachedEnd, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getProductsPage:(NSUInteger)page completion:(BUYDataProductListBlock)block;
- (BUYRequestOperation *)getProductsPage:(NSUInteger)page completion:(BUYDataProductListBlock)block;
/**
* Fetches a single product by the ID of the product.
......@@ -146,9 +146,9 @@ typedef void (^BUYDataProductListBlock)(NSArray<BUYProduct *> * _Nullable produc
* @param productId Product ID
* @param block (^BUYDataProductBlock)(BUYProduct *product, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getProductById:(NSString *)productId completion:(BUYDataProductBlock)block;
- (BUYRequestOperation *)getProductById:(NSString *)productId completion:(BUYDataProductBlock)block;
/**
* Fetches a list of product by the ID of each product.
......@@ -156,18 +156,18 @@ typedef void (^BUYDataProductListBlock)(NSArray<BUYProduct *> * _Nullable produc
* @param productIds An array of `NSString` objects with Product IDs to fetch
* @param block (^BUYDataProductsBlock)(NSArray *products, NSError *error);
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getProductsByIds:(NSArray *)productIds completion:(BUYDataProductsBlock)block;
- (BUYRequestOperation *)getProductsByIds:(NSArray *)productIds completion:(BUYDataProductsBlock)block;
/**
* Fetches the collections on the shop
*
* @param block (^BUYDataCollectionsBlock)(NSArray *collections, NSError *error)
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getCollections:(BUYDataCollectionsBlock)block;
- (BUYRequestOperation *)getCollections:(BUYDataCollectionsBlock)block;
/**
* Fetches collections based off page
......@@ -175,9 +175,9 @@ typedef void (^BUYDataProductListBlock)(NSArray<BUYProduct *> * _Nullable produc
* @param page Index of the page requested
* @param block (^BUYDataCollectionsBlock)(NSArray *collections, NSError *error)
*
* @return The associated NSURLSessionDataTask
* @return The associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getCollectionsPage:(NSUInteger)page completion:(BUYDataCollectionsListBlock)block;
- (BUYRequestOperation *)getCollectionsPage:(NSUInteger)page completion:(BUYDataCollectionsListBlock)block;
/**
* Fetches the products in the given collection with the collection's
......@@ -187,9 +187,9 @@ typedef void (^BUYDataProductListBlock)(NSArray<BUYProduct *> * _Nullable produc
* @param collectionId The `collectionId` found in the BUYCollection object to fetch the products from
* @param block (NSArray *products, NSUInteger page, BOOL reachedEnd, NSError *error)
*
* @return the associated NSURLSessionDataTask
* @return the associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getProductsPage:(NSUInteger)page inCollection:(NSNumber *)collectionId completion:(BUYDataProductListBlock)block;
- (BUYRequestOperation *)getProductsPage:(NSUInteger)page inCollection:(NSNumber *)collectionId completion:(BUYDataProductListBlock)block;
/**
* Fetches the products in the given collection with a given sort order
......@@ -199,9 +199,9 @@ typedef void (^BUYDataProductListBlock)(NSArray<BUYProduct *> * _Nullable produc
* @param sortOrder The sort order that overrides the default collection sort order
* @param block (NSArray *products, NSUInteger page, BOOL reachedEnd, NSError *error)
*
* @return the associated NSURLSessionDataTask
* @return the associated BUYRequestOperation
*/
- (NSURLSessionDataTask *)getProductsPage:(NSUInteger)page inCollection:(NSNumber *)collectionId sortOrder:(BUYCollectionSort)sortOrder completion:(BUYDataProductListBlock)block;
- (BUYRequestOperation *)getProductsPage:(NSUInteger)page inCollection:(NSNumber *)collectionId sortOrder:(BUYCollectionSort)sortOrder completion:(BUYDataProductListBlock)block;
@end
......
......@@ -47,7 +47,7 @@ static NSString * const BUYCollectionsKey = @"collection_listings";
#pragma mark - API -
- (NSURLSessionDataTask *)getShop:(BUYDataShopBlock)block
- (BUYRequestOperation *)getShop:(BUYDataShopBlock)block
{
return [self getRequestForURL:[self urlForShop] completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
BUYShop *shop = nil;
......@@ -58,7 +58,7 @@ static NSString * const BUYCollectionsKey = @"collection_listings";
}];
}
- (NSURLSessionDataTask *)getProductsPage:(NSUInteger)page completion:(BUYDataProductListBlock)block
- (BUYRequestOperation *)getProductsPage:(NSUInteger)page completion:(BUYDataProductListBlock)block
{
NSURL *route = [self urlForProductListingsWithParameters:@{
@"limit" : @(self.pageSize),
......@@ -75,7 +75,7 @@ static NSString * const BUYCollectionsKey = @"collection_listings";
}];
}
- (NSURLSessionDataTask *)getProductById:(NSString *)productId completion:(BUYDataProductBlock)block;
- (BUYRequestOperation *)getProductById:(NSString *)productId completion:(BUYDataProductBlock)block;
{
BUYAssert(productId, @"Failed to get product by ID. Product ID must not be nil.");
......@@ -91,7 +91,7 @@ static NSString * const BUYCollectionsKey = @"collection_listings";
}];
}
- (NSURLSessionDataTask *)getProductsByIds:(NSArray *)productIds completion:(BUYDataProductsBlock)block
- (BUYRequestOperation *)getProductsByIds:(NSArray *)productIds completion:(BUYDataProductsBlock)block
{
BUYAssert(productIds, @"Failed to get product by IDs. Product IDs array must not be nil.");
......@@ -112,14 +112,14 @@ static NSString * const BUYCollectionsKey = @"collection_listings";
}];
}
- (NSURLSessionDataTask *)getCollections:(BUYDataCollectionsBlock)block
- (BUYRequestOperation *)getCollections:(BUYDataCollectionsBlock)block
{
return [self getCollectionsPage:1 completion:^(NSArray<BUYCollection *> *collections, NSUInteger page, BOOL reachedEnd, NSError *error) {
block(collections, error);
}];
}
- (NSURLSessionDataTask *)getCollectionsPage:(NSUInteger)page completion:(BUYDataCollectionsListBlock)block
- (BUYRequestOperation *)getCollectionsPage:(NSUInteger)page completion:(BUYDataCollectionsListBlock)block
{
NSURL *route = [self urlForCollectionListingsWithParameters:@{
@"limit" : @(self.pageSize),
......@@ -136,12 +136,12 @@ static NSString * const BUYCollectionsKey = @"collection_listings";
}];
}
- (NSURLSessionDataTask *)getProductsPage:(NSUInteger)page inCollection:(NSNumber *)collectionId completion:(BUYDataProductListBlock)block
- (BUYRequestOperation *)getProductsPage:(NSUInteger)page inCollection:(NSNumber *)collectionId completion:(BUYDataProductListBlock)block
{
return [self getProductsPage:page inCollection:collectionId sortOrder:BUYCollectionSortCollectionDefault completion:block];
}
- (NSURLSessionDataTask *)getProductsPage:(NSUInteger)page inCollection:(NSNumber *)collectionId sortOrder:(BUYCollectionSort)sortOrder completion:(BUYDataProductListBlock)block
- (BUYRequestOperation *)getProductsPage:(NSUInteger)page inCollection:(NSNumber *)collectionId sortOrder:(BUYCollectionSort)sortOrder completion:(BUYDataProductListBlock)block
{
BUYAssert(collectionId, @"Failed to get products page. Invalid collectionID.");
......
......@@ -27,6 +27,7 @@
@import Foundation;
@class BUYModelManager;
@class BUYRequestOperation;
/**
* A BUYStatus is associated with the completion of an enqueued job on Shopify.
......@@ -94,10 +95,14 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong, nonnull) BUYModelManager *modelManager;
/**
* Queue where callbacks will be called
* defaults to main queue
* Queue on which all request operation are executed
*/
@property (nonatomic, strong, nonnull) dispatch_queue_t queue;
@property (nonatomic, strong, readonly, nonnull) NSOperationQueue *requestQueue;
/**
* Queue on which network completion callbacks will be executed
*/
@property (nonatomic, strong, nonnull) NSOperationQueue *callbackQueue;
/**
* The page size for any paged request. This can range from 1-250. Default is 25
......
......@@ -27,17 +27,13 @@
#import "BUYClient+Internal.h"
#import "BUYAssert.h"
#import "BUYModelManager.h"
#import "BUYRequestOperation.h"
static NSString * const BUYClientJSONMimeType = @"application/json";
@interface BUYClient () <NSURLSessionDelegate>
@property (nonatomic, strong) NSString *shopDomain;
@property (nonatomic, strong) NSString *apiKey;
@property (nonatomic, strong) NSString *appId;
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSString *merchantId;
@end
......@@ -58,14 +54,15 @@ static NSString * const BUYClientJSONMimeType = @"application/json";
self = [super init];
if (self) {
self.modelManager = [BUYModelManager modelManager];
self.shopDomain = shopDomain;
self.apiKey = apiKey;
self.appId = appId;
self.applicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"] ?: @"";
self.queue = dispatch_get_main_queue();
self.session = [self urlSession];
self.pageSize = 25;
_modelManager = [BUYModelManager modelManager];
_shopDomain = shopDomain;
_apiKey = apiKey;
_appId = appId;
_applicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"] ?: @"";
_callbackQueue = [NSOperationQueue mainQueue];
_requestQueue = [NSOperationQueue new];
_session = [self urlSession];
_pageSize = 25;
}
return self;
}
......@@ -80,7 +77,7 @@ static NSString * const BUYClientJSONMimeType = @"application/json";
config.HTTPAdditionalHeaders = @{@"User-Agent": [NSString stringWithFormat:@"Mobile Buy SDK iOS/%@/%@", BUYClientVersionString, bundleIdentifier]};
return [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
return [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:self.requestQueue];
}
- (void)setPageSize:(NSUInteger)pageSize
......@@ -122,36 +119,36 @@ static NSString * const BUYClientJSONMimeType = @"application/json";
#pragma mark - Convenience Requests
- (NSURLSessionDataTask *)getRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (BUYRequestOperation *)getRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
return [self requestForURL:url method:@"GET" object:nil completionHandler:completionHandler];
}
- (NSURLSessionDataTask *)postRequestForURL:(NSURL *)url object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (BUYRequestOperation *)postRequestForURL:(NSURL *)url object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
return [self requestForURL:url method:@"POST" object:object completionHandler:completionHandler];
}
- (NSURLSessionDataTask *)putRequestForURL:(NSURL *)url object:(id<BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (BUYRequestOperation *)putRequestForURL:(NSURL *)url object:(id<BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
return [self requestForURL:url method:@"PUT" object:object completionHandler:completionHandler];
}
- (NSURLSessionDataTask *)patchRequestForURL:(NSURL *)url object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (BUYRequestOperation *)patchRequestForURL:(NSURL *)url object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
return [self requestForURL:url method:@"PATCH" object:object completionHandler:completionHandler];
}
- (NSURLSessionDataTask *)deleteRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (BUYRequestOperation *)deleteRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
return [self requestForURL:url method:@"DELETE" object:nil completionHandler:completionHandler];
}
#pragma mark - Generic Requests
- (void)startTask:(NSURLSessionDataTask *)task
- (void)startTask:(BUYRequestOperation *)task
{
[task resume];
[self.requestQueue addOperation:task];
}
- (NSString *)authorizationHeader
......@@ -160,7 +157,7 @@ static NSString * const BUYClientJSONMimeType = @"application/json";
return [NSString stringWithFormat:@"%@ %@", @"Basic", [data base64EncodedStringWithOptions:0]];
}
- (NSURLSessionDataTask *)requestForURL:(NSURL *)url method:(NSString *)method object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (BUYRequestOperation *)requestForURL:(NSURL *)url method:(NSString *)method object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
if (object) {
......@@ -176,26 +173,15 @@ static NSString * const BUYClientJSONMimeType = @"application/json";
}
request.HTTPMethod = method;
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *json = nil;
if (data.length > 2) { // 2 is the minimum amount of data {} for a JSON Object. Just ignore anything less.
json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
}
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
BOOL isSuccessful = (statusCode / 100) == 2;
if (!isSuccessful && !error) { // Only generate error if request failed
error = [self errorFromJSON:json response:response];
}
dispatch_async(self.queue, ^{
BUYRequestOperation *operation = [[BUYRequestOperation alloc] initWithSession:self.session request:request payload:object completion:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
[self.callbackQueue addOperationWithBlock:^{
completionHandler(json, response, error);
});
}];
}];
[self startTask:task];
return task;
[self startTask:operation];
return operation;
}
#pragma mark - NSURLSessionTaskDelegate
......@@ -229,7 +215,7 @@ static NSString * const BUYClientJSONMimeType = @"application/json";
- (void)enableApplePayWithMerchantId:(NSString *)merchantId
{
self.merchantId = merchantId;
_merchantId = merchantId;
}
@end
//
// BUYRouter.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 "BUYRouter.h"
#pragma mark - Route -
@interface BUYRoute ()
@property (strong, nonatomic) NSURLComponents *components;
@end
@implementation BUYRoute
+ (instancetype)routeWithFormat:(NSString *)format, ...
{
va_list list;
va_start(list, format);
NSString *URLString = [[NSString alloc] initWithFormat:format arguments:list];
va_end(list);
return [[[self class] alloc] initWithURLString:URLString];
}
- (instancetype)initWithURLString:(NSString *)URLString
{
self = [super init];
if (self) {
NSURL *url = [NSURL URLWithString:URLString];
_components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
}
return self;
}
- (void)setQueryItems:(NSDictionary *)queryItems
{
_queryItems = queryItems;
NSMutableArray *items = [NSMutableArray new];
[queryItems enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
[items addObject:[NSURLQueryItem queryItemWithName:key value:[NSString stringWithFormat:@"%@", value]]];
}];
[_components setQueryItems:items];
}
#pragma mark - Accessors -
- (NSURL *)URL
{
/* ---------------------------------
* All API requests should end with
* a .json suffix.
*/
return [_components.URL URLByAppendingPathExtension:@"json"];
}
#pragma mark - Mutation -
- (BUYRoute *)appendFormat:(NSString *)format, ...
{
va_list list;
va_start(list, format);
NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:list];
va_end(list);
if (formattedString.length > 0) {
_components.path = [_components.path stringByAppendingPathComponent:formattedString];
}
return self;
}
- (BUYRoute *)appendPath:(NSString *)path
{
return [self appendFormat:path];
}
- (BUYRoute *)appendIdentifier:(NSNumber *)identifier
{
return [self appendFormat:@"%@", identifier];
}
@end
#pragma mark - Router -
@interface BUYRouter ()
@property (strong, nonatomic) NSString *shopDomain;
@property (strong, nonatomic) NSString *appID;
@end
@implementation BUYRouter
#pragma mark - Init -
- (instancetype)initWithShopDomain:(NSString *)shopDomain appID:(NSString *)appID
{
self = [super init];
if (self) {
_shopDomain = shopDomain;
_appID = appID;
}
return self;
}
#pragma mark - API -
- (BUYRoute *)routeForAPI
{
return [BUYRoute routeWithFormat:@"https://%@/api/", self.shopDomain];
}
- (BUYRoute *)routeForApps
{
return [[self routeForAPI] appendFormat:@"/apps/%@", self.appID];
}
#pragma mark - Storefront -
- (BUYRoute *)routeForShop
{
return [[self routeForAPI] appendPath:@"/meta"];
}
- (BUYRoute *)routeForProductListings
{
return [[self routeForApps] appendPath:@"/product_listings"];
}
- (BUYRoute *)routeForCollectionListings
{
return [[self routeForApps] appendPath:@"/collection_listings"];
}
#pragma mark - Checkout -
- (BUYRoute *)routeForCheckouts
{
return [[self routeForAPI] appendPath:@"/checkouts"];
}
- (BUYRoute *)routeForCheckoutsWithToken:(NSString *)token
{
return [self routeForCheckoutsAction:@"" withToken:token];
}
- (BUYRoute *)routeForCheckoutsProcessingWithToken:(NSString *)token
{
return [self routeForCheckoutsAction:@"/processing" withToken:token];
}
- (BUYRoute *)routeForCheckoutsCompletionWithToken:(NSString *)token
{
return [self routeForCheckoutsAction:@"/complete" withToken:token];
}
- (BUYRoute *)routeForCheckoutsShippingRatesWithToken:(NSString *)token
{
return [self routeForCheckoutsAction:@"/shipping_rates" withToken:token];
}
- (BUYRoute *)routeForCheckoutsUsingGiftCard
{
return [[self routeForCheckouts] appendPath:@"/gift_cards"];
}
- (BUYRoute *)routeForCheckoutsUsingGiftCardWithToken:(NSString *)token
{
return [[[self routeForCheckouts] appendPath:@"/gift_cards"] appendPath:token];
}
- (BUYRoute *)routeForCheckoutsUsingGiftCard:(NSNumber *)giftCardID token:(NSString *)token
{
return [[[self routeForCheckoutsUsingGiftCard] appendIdentifier:giftCardID] appendPath:token];
}
#pragma mark - Customers -
- (BUYRoute *)routeForCustomers
{
return [[self routeForAPI] appendPath:@"/customers"];
}
- (BUYRoute *)routeForCustomersOrders
{
return [[self routeForCustomers] appendPath:@"/orders"];
}
- (BUYRoute *)routeForCustomersWithID:(NSString *)identifier
{
return [[self routeForCustomers] appendPath:identifier];
}
- (BUYRoute *)routeForCustomersActivationWithID:(NSString *)identifier
{
return [[self routeForCustomersWithID:identifier] appendPath:@"/activate"];
}
- (BUYRoute *)routeForCustomersToken
{
return [[self routeForCustomers] appendPath:@"/customer_token"];
}
- (BUYRoute *)routeForCustomersTokenRenewalWithID:(NSString *)customerID
{
return [[self routeForCustomersWithID:customerID] appendPath:@"/customer_token/renew"];
}
- (BUYRoute *)routeForCustomersPasswordRecovery
{
return [[self routeForCustomers] appendPath:@"/recover"];
}
- (BUYRoute *)routeForCustomersPasswordResetWithID:(NSString *)identifier
{
return [[self routeForCustomersWithID:identifier] appendPath:@"/reset"];
}
#pragma mark - Utilities -
- (BUYRoute *)routeForCheckoutsAction:(NSString *)action withToken:(NSString *)token
{
return [[[self routeForCheckouts] appendPath:action] appendPath:token];
}
@end
//
// BUYOperation.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 <Foundation/Foundation.h>
@interface BUYOperation : NSOperation
- (void)startExecution;
- (void)finishExecution;
- (void)cancelExecution;
@end
//
// BUYOperation.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 "BUYOperation.h"
typedef NS_ENUM(NSUInteger, BUYOperationState) {
BUYOperationStateExecuting = 1,
BUYOperationStateFinished = 2,
};
@interface BUYOperation ()
@property (atomic, assign) BUYOperationState state;
@end
@implementation BUYOperation
#pragma mark - KVO -
+ (NSSet *)keyPathsForValuesAffectingIsExecuting
{
return [NSSet setWithObject:@"state"];
}
+ (NSSet *)keyPathsForValuesAffectingIsFinished
{
return [NSSet setWithObject:@"state"];
}
#pragma mark - Concurrent -
- (BOOL)isAsynchronous
{
return YES;
}
#pragma mark - Accessors -
- (BOOL)isExecuting
{
return self.state == BUYOperationStateExecuting;
}
- (BOOL)isFinished
{
return self.state == BUYOperationStateFinished;
}
#pragma mark - Start -
- (void)start
{
[self startExecution];
}
- (void)cancel
{
[super cancel];
[self cancelExecution];
}
#pragma mark - Execution -
- (void)startExecution
{
self.state = BUYOperationStateExecuting;
}
- (void)finishExecution
{
self.state = BUYOperationStateFinished;
}
- (void)cancelExecution
{
}
@end
//
// BUYRequestOperation.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"
NS_ASSUME_NONNULL_BEGIN
@protocol BUYSerializable;
typedef void (^BUYRequestOperationCompletion)(NSDictionary * _Nullable json, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error);
typedef BOOL (^BUYRequestOperationPollingHandler)(NSDictionary * _Nullable json, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error);
@interface BUYRequestOperation : BUYOperation
@property (strong, nonatomic, readonly, nonnull) NSURLSession *session;
@property (strong, nonatomic, readonly, nonnull) NSURLRequest *originalRequest;
@property (strong, nonatomic, nullable) BUYRequestOperationPollingHandler pollingHandler;
+ (instancetype)operationWithSession:(NSURLSession *)session request:(NSURLRequest *)request payload:(id<BUYSerializable> _Nullable)payload completion:(BUYRequestOperationCompletion)completion;
- (instancetype)initWithSession:(NSURLSession *)session request:(NSURLRequest *)request payload:(id<BUYSerializable> _Nullable)payload completion:(BUYRequestOperationCompletion)completion;
@end
NS_ASSUME_NONNULL_END
//
// BUYRequestOperation.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 "BUYRequestOperation.h"
#import "BUYSerializable.h"
NSString * const kShopifyError = @"shopify";
typedef void (^BUYRequestJSONCompletion)(NSDictionary *json, NSHTTPURLResponse *response, NSError *error);
#pragma mark - NSURLResponse -
@interface NSHTTPURLResponse (Convenience)
@property (assign, nonatomic, readonly) BOOL successful;
@end
@implementation NSHTTPURLResponse (Convenience)
- (BOOL)successful {
return ((NSUInteger)(self.statusCode / 100)) == 2;
}
@end
#pragma mark - BUYOperation Private -
@interface BUYOperation (Private)
- (void)setExecuting:(BOOL)executing;
- (void)setFinished:(BOOL)finished;
@end
#pragma mark - BUYRequestOperation -
@interface BUYRequestOperation ()
@property (strong, atomic) NSURLSessionDataTask *runningTask;
@property (strong, nonatomic, readonly) BUYRequestOperationCompletion completion;
@end
@implementation BUYRequestOperation
#pragma mark - Init -
+ (instancetype)operationWithSession:(NSURLSession *)session request:(NSURLRequest *)request payload:(id<BUYSerializable>)payload completion:(BUYRequestOperationCompletion)completion {
return [[[self class] alloc] initWithSession:session request:request payload:payload completion:completion];
}
- (instancetype)initWithSession:(NSURLSession *)session request:(NSURLRequest *)request payload:(id<BUYSerializable>)payload completion:(BUYRequestOperationCompletion)completion
{
self = [super init];
if (self) {
_session = session;
_originalRequest = request;
_completion = completion;
}
return self;
}
#pragma mark - Completion -
- (void)finishWithJSON:(id)JSON response:(NSHTTPURLResponse *)response
{
[self finishExecution];
self.completion(JSON, response, nil);
}
- (void)finishWithError:(NSError *)error response:(NSHTTPURLResponse *)response
{
[self finishExecution];
self.completion(nil, response, error);
}
#pragma mark - Start -
- (void)startExecution
{
if (self.isCancelled) {
return;
}
[super startExecution];
NSURLRequest *request = self.originalRequest;
NSURLSessionDataTask *task = [self requestUsingPollingIfNeeded:request completion:^(NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
if (response.successful) {
[self finishWithJSON:json response:response];
} else {
[self finishWithError:error response:response];
}
}];
self.runningTask = task;
[task resume];
}
- (void)cancelExecution
{
[super cancelExecution];
[self.runningTask cancel];
}
#pragma mark - Requests -
- (NSURLSessionDataTask *)requestUsingPollingIfNeeded:(NSURLRequest *)request completion:(BUYRequestJSONCompletion)completion
{
if (self.isCancelled) {
return nil;
}
return [self request:request completion:^(NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
if (self.isCancelled) {
return;
}
/* ---------------------------------
* If a polling handler is provided
* and it returns YES for continue
* polling, we recursively continue
* the polling process.
*/
if (self.pollingHandler && self.pollingHandler(json, response, error)) {
NSURLSessionDataTask *task = [self requestUsingPollingIfNeeded:request completion:completion];
self.runningTask = task;
[task resume];
} else {
completion(json, response, error);
}
}];
}
- (NSURLSessionDataTask *)request:(NSURLRequest *)request completion:(BUYRequestJSONCompletion)completion
{
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.originalRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *json = nil;
if (data.length > 2) { // 2 is the minimum amount of data {} for a JSON Object. Just ignore anything less.
json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
}
NSHTTPURLResponse *httpResponse = (id)response;
if (!httpResponse.successful && !error) {
error = [[NSError alloc] initWithDomain:kShopifyError code:httpResponse.statusCode userInfo:json];
}
completion(json, httpResponse, error);
}];
return task;
}
@end
//
// BUYClient+Checkout.h
// BUYClient+CheckoutHelpers.h
// Mobile Buy SDK
//
// Created by Shopify.
......
//
// BUYClient+Checkout.m
// BUYClient+CheckoutHelpers.m
// Mobile Buy SDK
//
// Created by Shopify.
......@@ -28,7 +28,7 @@
@implementation BUYClient (CheckoutHelpers)
- (NSURLSessionDataTask *)handleCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)completion
- (BUYRequestOperation *)handleCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)completion
{
if ([checkout hasToken]) {
return [self updateCheckout:checkout completion:completion];
......
......@@ -29,18 +29,11 @@
*/
#import "BUYAccountCredentials.h"
#import "BUYApplePayAdditions.h"
#import "BUYApplePayHelpers.h"
#import "BUYAddress.h"
#import "BUYCart.h"
#import "BUYCartLineItem.h"
#import "BUYCheckout.h"
#import "BUYCheckoutAttribute.h"
#import "BUYClient+Test.h"
#import "BUYClient.h"
#import "BUYClient+Customers.h"
#import "BUYClient+Storefront.h"
#import "BUYClient+Checkout.h"
#import "BUYCollection.h"
#import "BUYCreditCard.h"
#import "BUYCustomer.h"
......@@ -58,6 +51,7 @@
#import "BUYShop.h"
#import "BUYTaxLine.h"
#import "BUYApplePayAdditions.h"
#import "BUYApplePayHelpers.h"
#import "BUYApplePayPaymentProvider.h"
#import "BUYPaymentController.h"
......@@ -67,6 +61,8 @@
#import "BUYClient.h"
#import "BUYClient+Customers.h"
#import "BUYClient+Checkout.h"
#import "BUYClient+Storefront.h"
#import "BUYRequestOperation.h"
#import "BUYError.h"
#import "BUYError+BUYAdditions.h"
#import "BUYManagedObject.h"
......@@ -79,6 +75,7 @@
#import "BUYPaymentToken.h"
#import "NSArray+BUYAdditions.h"
#import "NSDate+BUYAdditions.h"
#import "NSDateFormatter+BUYAdditions.h"
#import "NSDecimalNumber+BUYAdditions.h"
#import "NSDictionary+BUYAdditions.h"
......
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