// // KWMShoppingCart.m // iCemarose // // Created by lee on 2017/5/18. // Copyright © 2017年 kollway. All rights reserved. // #import "KWMShoppingCart.h" #import "KWMCartResult.h" #import "KWMShopCartData.h" #import <RegexKitLite/RegexKitLite.h> #import <RXCollections/RXCollection.h> @interface KWMShoppingCart () @property (nonatomic, strong) KWMCartResult *result; //@property (nonatomic, assign) CGFloat version; @property (nonatomic, strong) NSMutableArray<NSURLSessionDataTask *> *tasks; @end @implementation KWMShoppingCart - (NSMutableArray<KWMShopCartModel *> *)items { return (NSMutableArray *)_result.items; } - (NSNumber *)count { return _result.item_count; } - (void)setResult:(KWMCartResult *)result { _result = result; [[KWMShopCartData alloc] syncCartProducts:result.items]; } - (void)setResultNoSync:(KWMCartResult *)result { _result = result; } + (instancetype)sharedInstance { static KWMShoppingCart *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken,^{ instance = [[super allocWithZone:NULL] init]; instance.tasks = [[NSMutableArray alloc] init]; }); if (!instance.result) { [instance setResultNoSync:[KWMCartResult new]]; instance.result.items = [[[KWMShopCartData alloc] getALLItems] mutableCopy]; NSInteger count = 0; for (KWMShopCartModel *item in instance.items) { count += item.quantity; } instance.result.item_count = @(count); } return instance; } - (void) missionCompleted { [self.tasks removeObjectAtIndex:0]; [self.tasks.firstObject resume]; } - (void) addTasksObject:(NSURLSessionDataTask *)object { if (self.tasks.lastObject && [self.tasks.lastObject.currentRequest.URL.absoluteString isEqualToString:object.currentRequest.URL.absoluteString] && [object.currentRequest.URL.absoluteString isMatchedByRegex:@"cart.js$"]) { if(!self.sync) { return; } } [self.tasks addObject:object]; if (self.tasks.count == 1) { [object resume]; } } - (void)allItemsWithCallback:(ShoppingCartCallBack)callback { // CGFloat version = [[NSDate date] timeIntervalSince1970]; // _version = version; __weak typeof(self) this = self; id task = [[KWMAPIManager sharedManager] getCartSuccess:^(NSURLSessionDataTask *task, KWMCartResult *result) { [this missionCompleted]; // if (version == this.version) { [[KWMShoppingCart sharedInstance] setResult:result]; callback(nil,result); // } } failure:^(NSURLSessionDataTask *task, NSError *error) { [this missionCompleted]; callback(error,nil); }]; [self addTasksObject:task]; } - (void)increaseProductWithVariantId:(NSNumber *)variantId quantity:(NSInteger)quantity callback:(ShoppingCartCallBack)callback { // CGFloat version = [[NSDate date] timeIntervalSince1970]; // _version = version; __weak typeof(self) this = self; id task = [[KWMAPIManager sharedManager] addProductWithVariantId:variantId quantity:quantity success:^(NSURLSessionDataTask *task, KWMRequestResult *result) { [this missionCompleted]; // if (version == this.version) { [[KWMShoppingCart sharedInstance] allItemsWithCallback:^(NSError *error, KWMCartResult *cart) { if(this.sync)callback(error,cart); }]; // } } failure:^(NSURLSessionDataTask *task, NSError *error) { [this missionCompleted]; // callback(error,nil); }]; [self addTasksObject:task]; if(!this.sync)callback(nil,[self changeLocalCartWithVariantId:variantId quantity:quantity flag:1]); } - (void)changeProductWithVariantId:(NSNumber *)variantId quantity:(NSInteger)quantity callback:(ShoppingCartCallBack)callback { // CGFloat version = [[NSDate date] timeIntervalSince1970]; // _version = version; __weak typeof(self) this = self; id task = [[KWMAPIManager sharedManager] changeProductWithVariantId:variantId quantity:quantity success:^(NSURLSessionDataTask *task, KWMCartResult *result) { [this missionCompleted]; // if (version == this.version) { [[KWMShoppingCart sharedInstance] setResult:result]; if(this.sync)callback(nil,result); // } } failure:^(NSURLSessionDataTask *task, NSError *error) { [this missionCompleted]; // callback(error,nil); }]; [self addTasksObject:task]; if(!this.sync)callback(nil,[self changeLocalCartWithVariantId:variantId quantity:quantity flag:quantity ? 2 : 0]); } -(void)updateProductWithVariantIds:(NSArray<NSNumber *> *)variantIds quantitties:(NSArray<NSNumber *> *)quantites callback:(ShoppingCartCallBack)callback { // CGFloat version = [[NSDate date] timeIntervalSince1970]; // _version = version; __weak typeof(self) this = self; id task = [[KWMAPIManager sharedManager] updateProductWithVariantIds:variantIds quantities:quantites success:^(NSURLSessionDataTask *task, KWMCartResult *result) { [this missionCompleted]; // if (version == this.version) { [[KWMShoppingCart sharedInstance] setResult:result]; if(this.sync)callback(nil,result); // } } failure:^(NSURLSessionDataTask *task, NSError *error) { [this missionCompleted]; // callback(error,nil); }]; [self addTasksObject:task]; if(!this.sync) { for (int i=0; i<quantites.count && self.items.count; i++) { [self changeLocalCartWithVariantId:variantIds[i] quantity:quantites[i].integerValue flag:quantites[i].integerValue ? 2 : 0]; } callback(nil,self.result); } } - (void)deleteProductWithVariantId:(NSNumber *)variantId callback:(ShoppingCartCallBack)callback { [self changeProductWithVariantId:variantId quantity:0 callback:callback]; } - (void)clearCartWithCallback:(ShoppingCartCallBack)callback { NSMutableArray *quantity = [NSMutableArray new]; NSArray *ids = [self.items rx_mapWithBlock:^id(KWMShopCartModel* each) { [quantity addObject:@(0)]; return each.identifier; }]; [self setResult:[KWMCartResult new]]; __weak typeof(self) this = self; id task = [[KWMAPIManager sharedManager] updateProductWithVariantIds:ids quantities:quantity success:^(NSURLSessionDataTask *task, KWMCartResult *result) { [this missionCompleted]; // if (version == this.version) { [[KWMShoppingCart sharedInstance] setResult:result]; callback(nil,result); // } } failure:^(NSURLSessionDataTask *task, NSError *error) { [this missionCompleted]; callback(error,nil); }]; [self addTasksObject:task]; } - (KWMCartResult *) changeLocalCartWithVariantId:(NSNumber *) variantId quantity:(NSInteger) quantity flag:(NSInteger) flag { NSMutableArray<KWMShopCartModel *> *items= self.items; NSInteger count = self.result.item_count.integerValue; BOOL processed = NO; NSUInteger size = items.count; for (int i=0;i < size; i++) { KWMShopCartModel *item = items[i]; if (item.identifier.integerValue == variantId.integerValue) { switch (flag) { case 0: count -= item.quantity; [self.items removeObjectAtIndex:i]; break; case 1: count += quantity; item.quantity += quantity; break; default: count -= item.quantity - quantity; item.quantity = quantity; } processed = YES; break; } } if (!processed) { KWMShopCartModel *model = [[KWMShopCartModel alloc] init]; model.identifier = variantId.stringValue; model.quantity = quantity; count += quantity; // [items addObject:model]; [items insertObject:model atIndex:0]; } self.result.item_count = @(count); return self.result; } + (id)allocWithZone:(struct _NSZone *)zone { return [KWMShoppingCart sharedInstance]; } - (id)copy { return self; } - (id)mutableCopy { return self; } @end