Commit a697e62d by Rune Madsen

Merge pull request #73 from Shopify/chore/runmad.update-checkouts-api-add-url-components

Updated API endpoints
parents 02da0c5e 6c34fca6
......@@ -32,6 +32,7 @@
#import "BUYAddress+Additions.h"
#import "BUYClientTestBase.h"
#import "BUYCollection+Additions.h"
#import "NSURLComponents+BUYAdditions.h"
@interface BUYClient ()
......@@ -213,60 +214,102 @@
[self testProductsInCollectionWithSortOrderCollectionDefault];
}
- (void)testQueryItemsConversion
{
NSDictionary *dictionary = @{@"collection_id" : @"1", @"limit" : @"25", @"page" : @"1", @"sort_by" : @"collection-default"};
NSURLComponents *components = [[NSURLComponents alloc] init];
[components setQueryItemsWithDictionary:dictionary];
NSSet *componentsQueryItems = [NSSet setWithArray:components.queryItems];
NSSet *queryItems = [NSSet setWithArray:@[[NSURLQueryItem queryItemWithName:@"collection_id" value:@"1"], [NSURLQueryItem queryItemWithName:@"limit" value:@"25"], [NSURLQueryItem queryItemWithName:@"page" value:@"1"], [NSURLQueryItem queryItemWithName:@"sort_by" value:@"collection-default"]]];
XCTAssertEqualObjects(componentsQueryItems, queryItems);
}
- (void)testProductsInCollectionWithSortOrderCollectionDefault
{
NSURLSessionDataTask *task = [self.client getProductsPage:1 inCollection:@1 sortOrder:BUYCollectionSortCollectionDefault completion:nil];
XCTAssertEqualObjects(task.originalRequest.URL.absoluteString, @"https://test_shop/api/channels/api_key/product_publications.json?collection_id=1&limit=25&page=1&sort_by=collection-default");
XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https");
XCTAssertEqualObjects(task.originalRequest.URL.host, @"test_shop");
XCTAssertEqualObjects(task.originalRequest.URL.path, @"/api/channels/api_key/product_publications.json");
NSSet *requestQueryItems = [NSSet setWithArray:[task.originalRequest.URL.query componentsSeparatedByString:@"&"]];
NSSet *queryItems = [NSSet setWithArray:@[@"collection_id=1", @"limit=25", @"page=1", @"sort_by=collection-default"]];
XCTAssertEqualObjects(requestQueryItems, queryItems);
}
- (void)testProductsInCollectionWithSortOrderBestSelling
{
NSURLSessionDataTask *task = [self.client getProductsPage:1 inCollection:@1 sortOrder:BUYCollectionSortBestSelling completion:nil];
XCTAssertEqualObjects(task.originalRequest.URL.absoluteString, @"https://test_shop/api/channels/api_key/product_publications.json?collection_id=1&limit=25&page=1&sort_by=best-selling");
XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https");
XCTAssertEqualObjects(task.originalRequest.URL.host, @"test_shop");
XCTAssertEqualObjects(task.originalRequest.URL.path, @"/api/channels/api_key/product_publications.json");
NSSet *requestQueryItems = [NSSet setWithArray:[task.originalRequest.URL.query componentsSeparatedByString:@"&"]];
NSSet *queryItems = [NSSet setWithArray:@[@"collection_id=1", @"limit=25", @"page=1", @"sort_by=best-selling"]];
XCTAssertEqualObjects(requestQueryItems, queryItems);
}
- (void)testProductsInCollectionWithSortOrderCreatedAscending
{
NSURLSessionDataTask *task = [self.client getProductsPage:1 inCollection:@1 sortOrder:BUYCollectionSortCreatedAscending completion:nil];
XCTAssertEqualObjects(task.originalRequest.URL.absoluteString, @"https://test_shop/api/channels/api_key/product_publications.json?collection_id=1&limit=25&page=1&sort_by=created-ascending");
XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https");
XCTAssertEqualObjects(task.originalRequest.URL.host, @"test_shop");
XCTAssertEqualObjects(task.originalRequest.URL.path, @"/api/channels/api_key/product_publications.json");
NSSet *requestQueryItems = [NSSet setWithArray:[task.originalRequest.URL.query componentsSeparatedByString:@"&"]];
NSSet *queryItems = [NSSet setWithArray:@[@"collection_id=1", @"limit=25", @"page=1", @"sort_by=created-ascending"]];
XCTAssertEqualObjects(requestQueryItems, queryItems);
}
- (void)testProductsInCollectionWithSortOrderCreatedDescending
{
NSURLSessionDataTask *task = [self.client getProductsPage:1 inCollection:@1 sortOrder:BUYCollectionSortCreatedDescending completion:nil];
XCTAssertEqualObjects(task.originalRequest.URL.absoluteString, @"https://test_shop/api/channels/api_key/product_publications.json?collection_id=1&limit=25&page=1&sort_by=created-descending");
XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https");
XCTAssertEqualObjects(task.originalRequest.URL.host, @"test_shop");
XCTAssertEqualObjects(task.originalRequest.URL.path, @"/api/channels/api_key/product_publications.json");
NSSet *requestQueryItems = [NSSet setWithArray:[task.originalRequest.URL.query componentsSeparatedByString:@"&"]];
NSSet *queryItems = [NSSet setWithArray:@[@"collection_id=1", @"limit=25", @"page=1", @"sort_by=created-descending"]];
XCTAssertEqualObjects(requestQueryItems, queryItems);
}
- (void)testProductsInCollectionWithSortOrderPriceAscending
{
NSURLSessionDataTask *task = [self.client getProductsPage:1 inCollection:@1 sortOrder:BUYCollectionSortPriceAscending completion:nil];
XCTAssertEqualObjects(task.originalRequest.URL.absoluteString, @"https://test_shop/api/channels/api_key/product_publications.json?collection_id=1&limit=25&page=1&sort_by=price-ascending");
XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https");
XCTAssertEqualObjects(task.originalRequest.URL.host, @"test_shop");
XCTAssertEqualObjects(task.originalRequest.URL.path, @"/api/channels/api_key/product_publications.json");
NSSet *requestQueryItems = [NSSet setWithArray:[task.originalRequest.URL.query componentsSeparatedByString:@"&"]];
NSSet *queryItems = [NSSet setWithArray:@[@"collection_id=1", @"limit=25", @"page=1", @"sort_by=price-ascending"]];
XCTAssertEqualObjects(requestQueryItems, queryItems);
}
- (void)testProductsInCollectionWithSortOrderPriceDescending
{
NSURLSessionDataTask *task = [self.client getProductsPage:1 inCollection:@1 sortOrder:BUYCollectionSortPriceDescending completion:nil];
XCTAssertEqualObjects(task.originalRequest.URL.absoluteString, @"https://test_shop/api/channels/api_key/product_publications.json?collection_id=1&limit=25&page=1&sort_by=price-descending");
XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https");
XCTAssertEqualObjects(task.originalRequest.URL.host, @"test_shop");
XCTAssertEqualObjects(task.originalRequest.URL.path, @"/api/channels/api_key/product_publications.json");
NSSet *requestQueryItems = [NSSet setWithArray:[task.originalRequest.URL.query componentsSeparatedByString:@"&"]];
NSSet *queryItems = [NSSet setWithArray:@[@"collection_id=1", @"limit=25", @"page=1", @"sort_by=price-descending"]];
XCTAssertEqualObjects(requestQueryItems, queryItems);
}
- (void)testProductsInCollectionWithSortOrderTitleAscending
{
NSURLSessionDataTask *task = [self.client getProductsPage:1 inCollection:@1 sortOrder:BUYCollectionSortTitleAscending completion:nil];
XCTAssertEqualObjects(task.originalRequest.URL.absoluteString, @"https://test_shop/api/channels/api_key/product_publications.json?collection_id=1&limit=25&page=1&sort_by=title-ascending");
XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https");
XCTAssertEqualObjects(task.originalRequest.URL.host, @"test_shop");
XCTAssertEqualObjects(task.originalRequest.URL.path, @"/api/channels/api_key/product_publications.json");
NSSet *requestQueryItems = [NSSet setWithArray:[task.originalRequest.URL.query componentsSeparatedByString:@"&"]];
NSSet *queryItems = [NSSet setWithArray:@[@"collection_id=1", @"limit=25", @"page=1", @"sort_by=title-ascending"]];
XCTAssertEqualObjects(requestQueryItems, queryItems);
}
- (void)testProductsInCollectionWithSortOrderTitleDescending
{
NSURLSessionDataTask *task = [self.client getProductsPage:1 inCollection:@1 sortOrder:BUYCollectionSortTitleDescending completion:nil];
XCTAssertEqualObjects(task.originalRequest.URL.absoluteString, @"https://test_shop/api/channels/api_key/product_publications.json?collection_id=1&limit=25&page=1&sort_by=title-descending");
XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https");
XCTAssertEqualObjects(task.originalRequest.URL.host, @"test_shop");
XCTAssertEqualObjects(task.originalRequest.URL.path, @"/api/channels/api_key/product_publications.json");
NSSet *requestQueryItems = [NSSet setWithArray:[task.originalRequest.URL.query componentsSeparatedByString:@"&"]];
NSSet *queryItems = [NSSet setWithArray:@[@"collection_id=1", @"limit=25", @"page=1", @"sort_by=title-descending"]];
XCTAssertEqualObjects(requestQueryItems, queryItems);
}
@end
......@@ -43,6 +43,10 @@
900396F71B69563400226B73 /* BUYCollection+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 900396F51B69563400226B73 /* BUYCollection+Additions.m */; };
900E7C841B5DA553006F3C81 /* BUYImageKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 900E7C811B5DA32F006F3C81 /* BUYImageKit.h */; };
900E7C851B5DA559006F3C81 /* BUYImageKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 900E7C821B5DA32F006F3C81 /* BUYImageKit.m */; };
901335461C187E0400410ED0 /* NSURLComponents+BUYAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 901335441C187E0400410ED0 /* NSURLComponents+BUYAdditions.h */; };
901335471C187E0400410ED0 /* NSURLComponents+BUYAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 901335441C187E0400410ED0 /* NSURLComponents+BUYAdditions.h */; };
901335481C187E0400410ED0 /* NSURLComponents+BUYAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 901335451C187E0400410ED0 /* NSURLComponents+BUYAdditions.m */; };
901335491C187E0400410ED0 /* NSURLComponents+BUYAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 901335451C187E0400410ED0 /* NSURLComponents+BUYAdditions.m */; };
901930E31BC5B9BC00D1134E /* BUYApplePayHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = BE33B4EE1B15FF4D0067982B /* BUYApplePayHelpers.m */; };
901930E41BC5B9BC00D1134E /* BUYOptionSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BE9496AF1B4D96D800B38949 /* BUYOptionSelectionViewController.m */; };
901930E51BC5B9BC00D1134E /* BUYVariantOptionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90516CA21B4D771400E35E45 /* BUYVariantOptionView.m */; };
......@@ -370,6 +374,8 @@
900396F51B69563400226B73 /* BUYCollection+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "BUYCollection+Additions.m"; sourceTree = "<group>"; };
900E7C811B5DA32F006F3C81 /* BUYImageKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYImageKit.h; sourceTree = "<group>"; };
900E7C821B5DA32F006F3C81 /* BUYImageKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYImageKit.m; sourceTree = "<group>"; };
901335441C187E0400410ED0 /* NSURLComponents+BUYAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLComponents+BUYAdditions.h"; sourceTree = "<group>"; };
901335451C187E0400410ED0 /* NSURLComponents+BUYAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLComponents+BUYAdditions.m"; sourceTree = "<group>"; };
901931701BC5B9BC00D1134E /* Buy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Buy.framework; sourceTree = BUILT_PRODUCTS_DIR; };
901931761BC5BC9100D1134E /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
903BCC7A1B7D1C2D00C21FEB /* BUYProductViewErrorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BUYProductViewErrorView.h; path = "Product View/BUYProductViewErrorView.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
......@@ -807,8 +813,6 @@
F70CE40E1A8BF1D90055BEB8 /* BUYApplePayAdditions.m */,
BE33B4ED1B15FF4D0067982B /* BUYApplePayHelpers.h */,
BE33B4EE1B15FF4D0067982B /* BUYApplePayHelpers.m */,
909944471B71B76800C40A33 /* UIFont+BUYAdditions.h */,
909944481B71B76800C40A33 /* UIFont+BUYAdditions.m */,
900E7C811B5DA32F006F3C81 /* BUYImageKit.h */,
900E7C821B5DA32F006F3C81 /* BUYImageKit.m */,
BE9496B61B4D96F100B38949 /* BUYProduct+Options.h */,
......@@ -823,12 +827,16 @@
90A446241B5EC03F009602AA /* NSDateFormatter+BUYAdditions.m */,
2AF52A9B1A7011DC0087DB2C /* NSDecimalNumber+BUYAdditions.h */,
2AF52A9C1A7011DC0087DB2C /* NSDecimalNumber+BUYAdditions.m */,
BE6D05971BD6BA6700772EBB /* NSDictionary+Additions.h */,
BE6D05981BD6BA6700772EBB /* NSDictionary+Additions.m */,
F76CFF1B19CB7BE30079C703 /* NSString+Trim.h */,
F76CFF1C19CB7BE30079C703 /* NSString+Trim.m */,
BE5DC39E1B71B13700B2BC1E /* NSURL+BUYAdditions.h */,
BE5DC39F1B71B13700B2BC1E /* NSURL+BUYAdditions.m */,
BE6D05971BD6BA6700772EBB /* NSDictionary+Additions.h */,
BE6D05981BD6BA6700772EBB /* NSDictionary+Additions.m */,
901335441C187E0400410ED0 /* NSURLComponents+BUYAdditions.h */,
901335451C187E0400410ED0 /* NSURLComponents+BUYAdditions.m */,
909944471B71B76800C40A33 /* UIFont+BUYAdditions.h */,
909944481B71B76800C40A33 /* UIFont+BUYAdditions.m */,
);
path = Utils;
sourceTree = "<group>";
......@@ -896,6 +904,7 @@
901931371BC5B9BC00D1134E /* BUYTaxLine.h in Headers */,
901931381BC5B9BC00D1134E /* BUYVariantSelectionViewController.h in Headers */,
901931391BC5B9BC00D1134E /* BUYOptionValueCell.h in Headers */,
901335471C187E0400410ED0 /* NSURLComponents+BUYAdditions.h in Headers */,
9019313A1BC5B9BC00D1134E /* BUYImage.h in Headers */,
9019313B1BC5B9BC00D1134E /* BUYOptionValue.h in Headers */,
9019313C1BC5B9BC00D1134E /* BUYShop.h in Headers */,
......@@ -971,6 +980,7 @@
BEB74A7D1B5564870005A300 /* BUYVariantSelectionViewController.h in Headers */,
BE10079B1B6165EC0031CEE7 /* BUYOptionValueCell.h in Headers */,
BE9A64591B503CD40033E558 /* BUYImage.h in Headers */,
901335461C187E0400410ED0 /* NSURLComponents+BUYAdditions.h in Headers */,
BE9A64681B503D080033E558 /* BUYOptionValue.h in Headers */,
BE9A64661B503D010033E558 /* BUYShop.h in Headers */,
BE9A644D1B503CA20033E558 /* BUYShippingRate.h in Headers */,
......@@ -1190,6 +1200,7 @@
901930E31BC5B9BC00D1134E /* BUYApplePayHelpers.m in Sources */,
901930E41BC5B9BC00D1134E /* BUYOptionSelectionViewController.m in Sources */,
901930E51BC5B9BC00D1134E /* BUYVariantOptionView.m in Sources */,
901335491C187E0400410ED0 /* NSURLComponents+BUYAdditions.m in Sources */,
901930E61BC5B9BC00D1134E /* BUYPresentationControllerForVariantSelection.m in Sources */,
901930E71BC5B9BC00D1134E /* NSDecimalNumber+BUYAdditions.m in Sources */,
901930E81BC5B9BC00D1134E /* BUYImage.m in Sources */,
......@@ -1284,6 +1295,7 @@
BE9A64751B503D370033E558 /* BUYApplePayHelpers.m in Sources */,
BEB74A7A1B55647C0005A300 /* BUYOptionSelectionViewController.m in Sources */,
BEB74A7C1B5564840005A300 /* BUYVariantOptionView.m in Sources */,
901335481C187E0400410ED0 /* NSURLComponents+BUYAdditions.m in Sources */,
BEB74A241B554BF20005A300 /* BUYPresentationControllerForVariantSelection.m in Sources */,
BE9A64711B503D260033E558 /* NSDecimalNumber+BUYAdditions.m in Sources */,
BE9A645A1B503CD90033E558 /* BUYImage.m in Sources */,
......
......@@ -27,17 +27,18 @@
#import "BUYAddress.h"
#import "BUYCart.h"
#import "BUYCheckout.h"
#import "BUYCheckout_Private.h"
#import "BUYCreditCard.h"
#import "BUYClient.h"
#import "BUYCollection.h"
#import "BUYCollection+Additions.h"
#import "BUYError.h"
#import "BUYGiftCard.h"
#import "BUYProduct.h"
#import "BUYShippingRate.h"
#import "BUYShop.h"
#import "BUYCheckout_Private.h"
#import "NSDecimalNumber+BUYAdditions.h"
#import "BUYError.h"
#import "BUYCollection.h"
#import "BUYCollection+Additions.h"
#import "NSURLComponents+BUYAdditions.h"
#if __has_include(<PassKit/PassKit.h>)
@import PassKit;
......@@ -110,9 +111,9 @@ NSString * const BUYVersionString = @"1.2.3";
- (NSURLSessionDataTask *)getShop:(BUYDataShopBlock)block
{
NSString *url = [NSString stringWithFormat:@"https://%@/meta.json", _shopDomain];
NSURLComponents *shopComponents = [self URLComponentsForShop];
return [self getRequestForURL:url completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
return [self getRequestForURL:shopComponents.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
BUYShop *shop = nil;
if (json && error == nil) {
shop = [[BUYShop alloc] initWithDictionary:json];
......@@ -123,9 +124,11 @@ NSString * const BUYVersionString = @"1.2.3";
- (NSURLSessionDataTask *)getProductsPage:(NSUInteger)page completion:(BUYDataProductListBlock)block
{
NSString *url = [NSString stringWithFormat:@"https://%@/api/channels/%@/product_publications.json?limit=%lu&page=%lu", self.shopDomain, self.channelId, (unsigned long)self.pageSize, (unsigned long)page];
NSURLComponents *components = [self URLComponentsForChannelsWithEndPoint:@"product_publications.json"
queryItems:@{@"limit" : [NSString stringWithFormat:@"%lu", (unsigned long)self.pageSize],
@"page" : [NSString stringWithFormat:@"%lu", (unsigned long)page]}];
return [self getRequestForURL:url completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
return [self getRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSArray *products = nil;
if (json && error == nil) {
......@@ -151,8 +154,10 @@ NSString * const BUYVersionString = @"1.2.3";
- (NSURLSessionDataTask *)getProductsByIds:(NSArray *)productIds completion:(BUYDataProductsBlock)block
{
NSString *url = [NSString stringWithFormat:@"https://%@/api/channels/%@/product_publications.json?product_ids=%@", self.shopDomain, self.channelId, [productIds componentsJoinedByString:@","]];
return [self getRequestForURL:url completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSURLComponents *components = [self URLComponentsForChannelsWithEndPoint:@"product_publications.json"
queryItems:@{@"product_ids" : [productIds componentsJoinedByString:@","]}];
return [self getRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSArray *products = nil;
if (json && error == nil) {
......@@ -167,9 +172,9 @@ NSString * const BUYVersionString = @"1.2.3";
- (NSURLSessionDataTask *)getCollections:(BUYDataCollectionsBlock)block
{
NSString *url = [NSString stringWithFormat:@"https://%@/api/channels/%@/collection_publications.json", self.shopDomain, self.channelId];
NSURLComponents *components = [self URLComponentsForChannelsWithEndPoint:@"collection_publications.json" queryItems:nil];
return [self getRequestForURL:url completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
return [self getRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSArray *collections = nil;
if (json && error == nil) {
......@@ -188,14 +193,13 @@ NSString * const BUYVersionString = @"1.2.3";
{
NSURLSessionDataTask *task = nil;
if (collectionId) {
NSMutableArray *parameters = [NSMutableArray array];
[parameters addObject:[NSString stringWithFormat:@"collection_id=%lu", collectionId.longValue]];
[parameters addObject:[NSString stringWithFormat:@"limit=%lu", (unsigned long)self.pageSize]];
[parameters addObject:[NSString stringWithFormat:@"page=%lu", (unsigned long)page]];
[parameters addObject:[NSString stringWithFormat:@"sort_by=%@", [BUYCollection sortOrderParameterForCollectionSort:sortOrder]]];
NSString *url = [NSString stringWithFormat:@"https://%@/api/channels/%@/product_publications.json?%@", self.shopDomain, self.channelId, [parameters componentsJoinedByString:@"&"]];
NSURLComponents *components = [self URLComponentsForChannelsWithEndPoint:@"product_publications.json"
queryItems:@{@"collection_id" : [NSString stringWithFormat:@"%lu", collectionId.longValue],
@"limit" : [NSString stringWithFormat:@"%lu", (unsigned long)self.pageSize],
@"page" : [NSString stringWithFormat:@"%lu", (unsigned long)page],
@"sort_by" : [BUYCollection sortOrderParameterForCollectionSort:sortOrder]}];
task = [self getRequestForURL:url completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
task = [self getRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSArray *products = nil;
if (json && error == nil) {
......@@ -223,6 +227,50 @@ NSString * const BUYVersionString = @"1.2.3";
return error;
}
#pragma mark - URL Components
- (NSURLComponents *)URLComponentsForChannelsWithEndPoint:(NSString *)endPoint queryItems:(NSDictionary*)queryItems
{
return [self URLComponentsForAPIPath:[NSString stringWithFormat:@"channels/%@", self.channelId] endPoint:endPoint queryItems:queryItems];
}
- (NSURLComponents *)URLComponentsForCheckoutsWithToken:(NSString *)checkoutToken endPoint:(NSString *)endPoint queryItems:(NSDictionary*)queryItems
{
NSMutableString *apiPath = [NSMutableString stringWithString:@"checkouts"];
if (checkoutToken) {
[apiPath appendFormat:@"/%@", checkoutToken];
} else {
[apiPath appendString:@".json"];
}
return [self URLComponentsForAPIPath:[apiPath copy] endPoint:endPoint queryItems:queryItems];
}
- (NSURLComponents *)URLComponentsForAPIPath:(NSString *)apiPath endPoint:(NSString *)endPoint queryItems:(NSDictionary*)queryItems
{
NSMutableArray *pathComponents = [NSMutableArray array];
[pathComponents addObject:@"api"];
[pathComponents addObject:apiPath];
if (endPoint) {
[pathComponents addObject:endPoint];
}
return [self URLComponentsForPathComponents:pathComponents queryItems:queryItems];
}
- (NSURLComponents *)URLComponentsForShop
{
return [self URLComponentsForPathComponents:@[@"meta.json"] queryItems:nil];
}
- (NSURLComponents *)URLComponentsForPathComponents:(NSArray*)pathComponents queryItems:(NSDictionary*)queryItems
{
NSURLComponents *components = [[NSURLComponents alloc] init];
components.scheme = @"https";
components.host = self.shopDomain;
components.path = [NSString stringWithFormat:@"/%@", [pathComponents componentsJoinedByString:@"/"]];
[components setQueryItemsWithDictionary:queryItems];
return components;
}
#pragma mark - Checkout
- (void)handleCheckoutResponse:(NSDictionary *)json error:(NSError *)error block:(BUYDataCheckoutBlock)block
......@@ -271,7 +319,9 @@ NSString * const BUYVersionString = @"1.2.3";
NSData *data = [NSJSONSerialization dataWithJSONObject:checkoutJSON options:0 error:&error];
if (data && error == nil) {
task = [self postRequestForURL:[NSString stringWithFormat:@"https://%@/anywhere/checkouts.json", _shopDomain] body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSURLComponents *components = [self URLComponentsForCheckoutsWithToken:nil endPoint:nil queryItems:nil];
task = [self postRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
[self handleCheckoutResponse:json error:error block:block];
}];
}
......@@ -287,12 +337,18 @@ NSString * const BUYVersionString = @"1.2.3";
}
else {
BUYGiftCard *giftCard = [[BUYGiftCard alloc] initWithDictionary:@{ @"code" : giftCardCode }];
task = [self postRequestForURL:[NSString stringWithFormat:@"https://%@/anywhere/checkouts/%@/gift_cards.json", _shopDomain, checkout.token] object:giftCard completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
if (error == nil) {
[self updateCheckout:checkout withGiftCardDictionary:json[@"gift_card"] addingGiftCard:YES];
}
block(checkout, error);
}];
NSURLComponents *components = [self URLComponentsForCheckoutsWithToken:checkout.token
endPoint:@"gift_cards.json"
queryItems:nil];
task = [self postRequestForURL:components.URL
object:giftCard
completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
if (error == nil) {
[self updateCheckout:checkout withGiftCardDictionary:json[@"gift_card"] addingGiftCard:YES];
}
block(checkout, error);
}];
}
return task;
......@@ -302,7 +358,8 @@ NSString * const BUYVersionString = @"1.2.3";
{
NSURLSessionDataTask *task = nil;
if (giftCard.identifier) {
task = [self deleteRequestForURL:[NSString stringWithFormat:@"https://%@/anywhere/checkouts/%@/gift_cards/%@.json", _shopDomain, checkout.token, giftCard.identifier] completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSURLComponents *components = [self URLComponentsForCheckoutsWithToken:checkout.token endPoint:[NSString stringWithFormat:@"gift_cards/%@.json", giftCard.identifier] queryItems:nil];
task = [self deleteRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
if (error == nil) {
[self updateCheckout:checkout withGiftCardDictionary:json[@"gift_card"] addingGiftCard:NO];
}
......@@ -327,6 +384,7 @@ NSString * const BUYVersionString = @"1.2.3";
}
checkout.giftCards = [giftCardArray copy];
checkout.paymentDue = [NSDecimalNumber buy_decimalNumberFromJSON:giftCardDictionary[@"checkout"][@"payment_due"]];
// Marking the checkout as clean. The properties we have updated above we don't need to re-sync with Shopify.
// There's also an issue with gift cards where syncing the gift card JSON won't work since the update endpoint
// doesn't accept the gift card without a gift card code (which we do not have).
......@@ -335,7 +393,8 @@ NSString * const BUYVersionString = @"1.2.3";
- (NSURLSessionDataTask *)getCheckout:(BUYCheckout *)checkout completion:(BUYDataCheckoutBlock)block
{
return [self getRequestForURL:[NSString stringWithFormat:@"https://%@/anywhere/checkouts/%@.json", _shopDomain, checkout.token] completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSURLComponents *components = [self URLComponentsForCheckoutsWithToken:checkout.token endPoint:nil queryItems:nil];
return [self getRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
[self handleCheckoutResponse:json error:error block:block];
}];
}
......@@ -347,7 +406,8 @@ NSString * const BUYVersionString = @"1.2.3";
NSURLSessionDataTask *task = nil;
if ([checkout hasToken]) {
task = [self patchRequestForURL:[NSString stringWithFormat:@"https://%@/anywhere/checkouts/%@.json", _shopDomain, checkout.token] body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSURLComponents *components = [self URLComponentsForCheckoutsWithToken:checkout.token endPoint:nil queryItems:nil];
task = [self patchRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
[self handleCheckoutResponse:json error:error block:block];
}];
}
......@@ -362,12 +422,12 @@ NSString * const BUYVersionString = @"1.2.3";
NSData *data = nil;
NSError *error = nil;
if (checkout.paymentSessionId.length > 0) {
NSDictionary *paymentJson = @{ @"payment_session_id" : checkout.paymentSessionId };
data = [NSJSONSerialization dataWithJSONObject:paymentJson options:0 error:&error];
}
if ((data && error == nil) || (checkout.paymentDue && checkout.paymentDue.floatValue == 0)) {
task = [self checkoutCompletionRequestWithCheckout:checkout body:data completion:block];
}
......@@ -412,7 +472,8 @@ NSString * const BUYVersionString = @"1.2.3";
- (NSURLSessionDataTask *)checkoutCompletionRequestWithCheckout:(BUYCheckout *)checkout body:(NSData *)body completion:(BUYDataCheckoutBlock)block
{
return [self postRequestForURL:[NSString stringWithFormat:@"https://%@/anywhere/checkouts/%@/complete.json", _shopDomain, checkout.token] body:body completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSURLComponents *components = [self URLComponentsForCheckoutsWithToken:checkout.token endPoint:@"complete.json" queryItems:nil];
return [self postRequestForURL:components.URL body:body completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
[self handleCheckoutResponse:json error:error block:block];
}];
}
......@@ -452,7 +513,8 @@ NSString * const BUYVersionString = @"1.2.3";
- (NSURLSessionDataTask *)getCompletionStatusOfCheckoutToken:(NSString *)token completion:(BUYDataCheckoutStatusBlock)block
{
return [self getRequestForURL:[NSString stringWithFormat:@"https://%@/anywhere/checkouts/%@/processing.json", _shopDomain, token] completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSURLComponents *components = [self URLComponentsForCheckoutsWithToken:token endPoint:@"processing.json" queryItems:nil];
return [self getRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
block([BUYClient statusForStatusCode:statusCode error:error], error);
}];
......@@ -464,7 +526,8 @@ NSString * const BUYVersionString = @"1.2.3";
{
NSURLSessionDataTask *task = nil;
if ([checkout hasToken]) {
task = [self getRequestForURL:[NSString stringWithFormat:@"https://%@/anywhere/checkouts/%@/shipping_rates.json?checkout", _shopDomain, checkout.token] completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSURLComponents *components = [self URLComponentsForCheckoutsWithToken:checkout.token endPoint:@"shipping_rates.json?checkout" queryItems:nil];
task = [self getRequestForURL:components.URL completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSArray *shippingRates = nil;
if (error == nil && json) {
shippingRates = [BUYShippingRate convertJSONArray:json[@"shipping_rates"]];
......@@ -552,7 +615,7 @@ NSString * const BUYVersionString = @"1.2.3";
return [[BUYError alloc] initWithDomain:kShopifyError code:statusCode userInfo:errorDictionary];
}
- (NSURLSessionDataTask *)requestForURL:(NSString *)url method:(NSString *)method object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (NSURLSessionDataTask *)requestForURL:(NSURL *)url method:(NSString *)method object:(id <BUYSerializable>)object completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
NSDictionary *json = [object jsonDictionaryForCheckout];
NSError *error = nil;
......@@ -569,9 +632,9 @@ NSString * const BUYVersionString = @"1.2.3";
[task resume];
}
- (NSURLSessionDataTask *)requestForURL:(NSString *)url method:(NSString *)method body:(NSData *)body completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (NSURLSessionDataTask *)requestForURL:(NSURL *)url method:(NSString *)method body:(NSData *)body completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.HTTPBody = body;
[request addValue:[self authorizationHeader] forHTTPHeaderField:@"Authorization"];
......@@ -609,7 +672,7 @@ NSString * const BUYVersionString = @"1.2.3";
- (NSURLSessionDataTask *)postPaymentRequestWithCheckout:(BUYCheckout *)checkout body:(NSData *)body completion:(BUYDataCreditCardBlock)block
{
return [self requestForURL:[checkout.paymentURL absoluteString] method:kPOST body:body completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
return [self requestForURL:checkout.paymentURL method:kPOST body:body completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSString *paymentSessionId = nil;
if (error == nil) {
paymentSessionId = json[@"id"];
......@@ -619,32 +682,32 @@ NSString * const BUYVersionString = @"1.2.3";
}];
}
- (NSURLSessionDataTask *)getRequestForURL:(NSString *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (NSURLSessionDataTask *)getRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
return [self requestForURL:url method:kGET body:nil completionHandler:completionHandler];
}
- (NSURLSessionDataTask *)postRequestForURL:(NSString *)url object:(id <BUYSerializable>)object 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
{
return [self requestForURL:url method:kPOST object:object completionHandler:completionHandler];
}
- (NSURLSessionDataTask *)postRequestForURL:(NSString *)url body:(NSData *)body completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (NSURLSessionDataTask *)postRequestForURL:(NSURL *)url body:(NSData *)body completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
return [self requestForURL:url method:kPOST body:body completionHandler:completionHandler];
}
- (NSURLSessionDataTask *)patchRequestForURL:(NSString *)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
{
return [self requestForURL:url method:kPATCH object:object completionHandler:completionHandler];
}
- (NSURLSessionDataTask *)patchRequestForURL:(NSString *)url body:(NSData *)body completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (NSURLSessionDataTask *)patchRequestForURL:(NSURL *)url body:(NSData *)body completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
return [self requestForURL:url method:kPATCH body:body completionHandler:completionHandler];
}
- (NSURLSessionDataTask *)deleteRequestForURL:(NSString *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
- (NSURLSessionDataTask *)deleteRequestForURL:(NSURL *)url completionHandler:(void (^)(NSDictionary *json, NSURLResponse *response, NSError *error))completionHandler
{
return [self requestForURL:url method:kDELETE body:nil completionHandler:completionHandler];
}
......
//
// NSURLComponents+BUYAdditions.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;
@interface NSURLComponents (BUYAdditions)
- (void)setQueryItemsWithDictionary:(NSDictionary*)namesAndValues;
@end
//
// NSURLComponents+BUYAdditions.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 "NSURLComponents+BUYAdditions.h"
@implementation NSURLComponents (BUYAdditions)
- (void)setQueryItemsWithDictionary:(NSDictionary*)dictionary
{
if (dictionary) {
NSMutableArray *queryItems = [NSMutableArray array];
for (NSString *key in [dictionary allKeys]) {
[queryItems addObject:[[NSURLQueryItem alloc] initWithName:key value:dictionary[key]]];
}
self.queryItems = [queryItems copy];
}
}
@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