// // KWMBaseVC.m // iBallsoul // // Created by Yaotian on 3/25/16. // Copyright © 2016 kwm. All rights reserved. // #import "KWMBaseVC.h" #import "KWMAPIManager.h" #import "KWMImageUtil.h" #import "KWMImageUtil.h" #import "UIColor+SAMAdditions.h" #import "RTSpinKitView.h" #import "MBProgressHUD.h" #import "PSPDFAlertView.h" #import "KWMStringUtil.h" #import "KWMSuperLoadingView.h" @interface KWMBaseVC () @end @implementation KWMBaseVC{ UIView *vLoadingContainer; // RTSpinKitView *loadingView; KWMSuperLoadingView *loadingView; int showLoadingCount; MBProgressHUD *toastHUD; } + (NSString *)kwmTag { return NSStringFromClass([self class]); } + (KWMBaseVC *)findControllerBy:(NSString *)controllerId fromStoryboard:(NSString *)storyboardName { UIStoryboard *myStoryboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil]; KWMBaseVC *baseController = [myStoryboard instantiateViewControllerWithIdentifier:controllerId]; return baseController; } - (void)viewDidLoad { [super viewDidLoad]; self.extendedLayoutIncludesOpaqueBars = YES; // self.view.backgroundColor = [UIColor sam_colorWithHex:@"#F1F1F1"]; // [self setupForDismissKeyboard]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // [self.navigationController setNavigationBarHidden:NO]; // [MobClick beginLogPageView:[NSStringFromClass(self Class)]]; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [notificationCenter addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; [notificationCenter addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self hideLoading]; // [MobClick endLogPageView:[NSStringFromClass(self Class)]]; NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:UIKeyboardWillShowNotification object:nil]; [notificationCenter removeObserver:self name:UIKeyboardWillHideNotification object:nil]; [notificationCenter removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil]; } - (void)keyboardWillHide:(NSNotification *)notification { if (self.keyboardHeight <= 0) { return; } self.keyboardHeight = 0; } - (void)keyboardWillShow:(NSNotification *)notification { if (self.keyboardHeight > 0) { return; } self.keyboardHeight = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height; } - (void)keyboardWillChangeFrame:(NSNotification *)notification { self.keyboardHeight = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height; } - (KWMAPIManager *)api { if (_api == nil) { _api = [KWMAPIManager sharedManager]; } return _api; } - (BUYClient *)client { if (_client == nil){ _client = [[BUYClient alloc] initWithShopDomain:Shopify_SHOP_DOMAIN apiKey:Shopify_API_KEY appId:Shopify_APP_ID]; } _client.pageSize = 20; NSDictionary *tokenDic = [[NSUserDefaults standardUserDefaults] objectForKey:@"token"]; NSString *path = NSHomeDirectory();//主目录 NSLog(@"NSHomeDirectory:%@",path); if (tokenDic != nil) { BUYCustomerToken *token = [BUYCustomerToken customerTokenWithJSONDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:@"token"]]; if (token != nil) { _client.customerToken = token; } } return _client; } - (KWMUserDao *)userDao { if (_userDao == nil) { _userDao = [KWMUserDao shareDao]; } return _userDao; } - (AppDelegate *)appDelegate { if(_appDelegate == nil){ _appDelegate = (AppDelegate *) [UIApplication sharedApplication].delegate; } return _appDelegate; } - (void)showLoading { // UIView * contentView = (self.navigationController.view != nil) ? self.navigationController.view : self.view; UIView *contentView = self.view; [self showLoading:contentView cancelable:NO]; } - (void)showLoading:(UIView *)view cancelable:(BOOL)isCancelable loadingBg:(UIColor *) color{ if(view == nil){ return; } showLoadingCount++; if (loadingView == nil) { //初始化加载页面 // loadingView = [[RTSpinKitView alloc] initWithStyle:RTSpinKitViewStylePlane color:[UIColor sam_colorWithHex:@"#242424"]]; loadingView = [[KWMSuperLoadingView alloc] initWithFrame:CGRectMake((UI_SCREEN_WIDTH-30)*0.5, (UI_SCREEN_HEITHT - 30)*0.5, 30, 30)]; vLoadingContainer = [[UIView alloc] initWithFrame:CGRectZero]; vLoadingContainer.frame = view.frame; vLoadingContainer.backgroundColor = color; CGPoint center = vLoadingContainer.center; center.y = center.y; loadingView.center = center; [loadingView initLoadingView]; [loadingView startAnimation]; [vLoadingContainer addSubview:loadingView]; [view addSubview:vLoadingContainer]; }else{ vLoadingContainer.backgroundColor = color; } vLoadingContainer.hidden = NO; loadingView.hidden = NO; vLoadingContainer.userInteractionEnabled = YES; // [loadingView startAnimating]; [loadingView startAnimation]; [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; NSLog(@"showLoading count=%d", showLoadingCount); } - (void)showLoading:(UIView *)view cancelable:(BOOL)isCancelable { [self showLoading:view cancelable:isCancelable loadingBg:[UIColor clearColor]]; } -(void) hideLoading:(BOOL)isDelay{ showLoadingCount--; if(showLoadingCount <= 0){ showLoadingCount = 0; if(loadingView != nil){ loadingView.hidden = YES; vLoadingContainer.hidden = YES; // [loadingView stopAnimating]; [loadingView stopAnimation]; } } [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; NSLog(@"hideLoading count=%d", showLoadingCount); } - (void)hideLoading { // if (showLoadingCount <= 0) { // return; // } // // //隐藏图标显示登录页面 CABasicAnimation *theAnimation; theAnimation=[CABasicAnimation animationWithKeyPath:@"opacity"]; theAnimation.duration= 0.6f; theAnimation.autoreverses = NO; theAnimation.repeatCount = 0; theAnimation.removedOnCompletion = NO; theAnimation.fromValue=[NSNumber numberWithFloat:1.0]; theAnimation.toValue=[NSNumber numberWithFloat:0.0]; [loadingView.layer addAnimation:theAnimation forKey:@"animateOpacity"]; [self performSelector:@selector(hideLoading:) withObject:nil afterDelay:0.5f]; } - (void)showToast:(NSString *)message{ if (message.length >= 40) { [self showDialog:message]; return; } if(toastHUD != nil){ [toastHUD hide:NO]; toastHUD = nil; } UIView * contentView = self.navigationController.view != nil ? self.navigationController.view : self.view; if(contentView == nil){ return; } CGSize widthSize = [KWMStringUtil boundingRectWithSize:CGSizeMake(UI_SCREEN_WIDTH - 100, 0) text:message testSize:15]; UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, widthSize.width, widthSize.height)]; view.backgroundColor = [UIColor clearColor]; UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, widthSize.width, widthSize.height)]; [messageLabel setFont:[UIFont systemFontOfSize:15.0]]; messageLabel.textColor = [UIColor whiteColor]; messageLabel.text = message; messageLabel.numberOfLines = 0; [view addSubview:messageLabel]; toastHUD = [MBProgressHUD showHUDAddedTo:contentView animated:YES]; toastHUD.userInteractionEnabled = NO; toastHUD.mode = MBProgressHUDModeCustomView; toastHUD.customView = view; toastHUD.removeFromSuperViewOnHide = YES; [toastHUD hide:YES afterDelay:2]; } - (void)showDialog:(NSString *)message{ PSPDFAlertView *alertView = [[PSPDFAlertView alloc] initWithTitle:message]; [alertView addButtonWithTitle:@"确定" block:nil]; [alertView show]; } - (void)showEmptyView:(NSInteger)type setTips:(NSString *)tips{ //TODO 显示数据为空的界面 } - (void)hideEmptyView { } - (void)reLoadData { NSAssert(NO, @"调用尚未实现的方法"); } - (void)loadData { NSAssert(NO, @"调用尚未实现的方法"); } //显示错误信息 - (void)showError:(NSError *)error{ if ([error.domain isEqualToString:NSURLErrorDomain]) { [self showToast:@"网络已断开,请重新连接"]; return; } if (!error.userInfo){ return; } if ([self isCheckOutError:error]){ return; } if ([self isSignUpError:error]){ return; } if ([self isNormalError:error]){ return; } //如果并不是shopify error,则正常吐司。 [self showToast:[error localizedDescription]]; } -(BOOL)isCheckOutError:(NSError *)error{ //虽然errorsFromCheckoutJSON里面有判断了,但为了保险起见,还是加上判断 NSDictionary *errorsDictionary = error.userInfo[@"errors"]; if(!errorsDictionary || ![errorsDictionary isKindOfClass:[NSDictionary class]]){ return NO; } NSDictionary *customerDictionary = errorsDictionary[@"checkout"]; if(!customerDictionary || ![customerDictionary isKindOfClass:[NSDictionary class]]){ return NO; } NSArray<BUYError *> *errors = [BUYError errorsFromCheckoutJSON:error.userInfo]; // 现在下单时不会报quantity错误了。所以这段代码注释 // if(errors && errors.count > 0){ // NSString *quantityRemainingMessage = [errors.firstObject quantityRemainingMessage]; // } if([self checkBuyErrors:errors]){ return YES; } return NO; } -(BOOL)isSignUpError:(NSError *)error{ NSDictionary *errorsDictionary = error.userInfo[@"errors"]; if(!errorsDictionary || ![errorsDictionary isKindOfClass:[NSDictionary class]]){ return NO; } NSDictionary *customerDictionary = errorsDictionary[@"customer"]; if(!customerDictionary || ![customerDictionary isKindOfClass:[NSDictionary class]]){ return NO; } NSArray<BUYError *> *errors = [BUYError errorsFromSignUpJSON:error.userInfo]; if([self checkBuyErrors:errors]){ return YES; } return NO; } - (BOOL)isNormalError:(NSError *)error{ NSString *toast = [self getErrorMessage:error]; if(![KWMStringUtil isEmpty:toast]){ if([toast isEqualToString:@"Unidentified customer"]){ toast = @"登录已失效,请重新登录"; } [self showToast:toast]; return YES; } return NO; } //判断buyerror是否有效,有效则吐司错误 -(BOOL)checkBuyErrors:(NSArray<BUYError *>*)errors{ if(errors!=nil && errors.count>0){ for(BUYError *error in errors){ if(error != nil && error != NULL && ![error isKindOfClass:[NSNull class]]){ NSString *key = error.key; if(key == nil){ break; } if([error.key isEqualToString:@"quantity"]){ key = @"商品剩余不足"; }else if([error.key isEqualToString:@"address"]){ key = @"地址出错"; } NSString *toast = [NSString stringWithFormat:@"%@, %@",key,error.message]; [self showToast:toast]; return YES; } } } return NO; } //获取key为message/error的错误信息 - (NSString *)getErrorMessage:(NSError *)error{ NSString *errorString; errorString = [self getErrorMessageForKey:@"message = \"" error:error]; if(![KWMStringUtil isEmpty:errorString]){ return errorString; } errorString = [self getErrorMessageForKey:@"error = \"" error:error]; if(![KWMStringUtil isEmpty:errorString]){ return errorString; } errorString = [self getErrorMessageForKey:@"errors = \"" error:error]; if(![KWMStringUtil isEmpty:errorString]){ return errorString; } return @""; } -(NSString *)getErrorMessageForKey:(NSString *)key error:(NSError *)error{ NSString *errorString = [self dictionaryToString:error.userInfo]; NSRange startRange = [errorString rangeOfString:key]; if (startRange.location != NSNotFound) { NSString *errorString2 = [errorString substringFromIndex:startRange.location + startRange.length]; NSRange endRange = [errorString2 rangeOfString:@"\""]; if(endRange.location != NSNotFound){ NSString *errorMessage = [errorString2 substringToIndex:endRange.location]; return errorMessage; } }else{ NSLog(@"Not Found"); } return @""; } //字典转换为字符串 - (NSString*)dictionaryToString:(NSDictionary *)dic{ NSString *a = [NSString stringWithFormat:@"%@",dic]; return a; } - (BOOL)hasError:(id)result{ NSInteger code = -1; NSString *message; if ([result isKindOfClass:[KWMRequestResult class]]) { KWMRequestResult *r = result; code = r.code; message = r.message; } if ([result isKindOfClass:[KWMRequestListResult class]]) { KWMRequestListResult *r = result; code = r.code; message = r.message; } BOOL isError = code != 0; if (isError) { if (code == 1) { //未登录,已经在APIManager里面发广播了 }else{ [self showToast:message]; } } return isError; } -(BOOL)hasCemaroseError:(KWMCemaroseResult *)result{ BOOL isError = NO; if(!result){ [self showToast:@"获取数据失败"]; isError = YES; }else if(result.success && !result.success.boolValue){ [self showToast:result.msg]; isError = YES; } return isError; } - (void)popDelay { [self popDelay:0.3f]; } - (void)popDelay:(NSTimeInterval)sec { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(sec * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.navigationController popViewControllerAnimated:YES]; }); } - (void (^)(NSURLSessionDataTask *, NSError *))defaultFailure { __weak KWMBaseVC *weakSelf = self; return ^(NSURLSessionDataTask *task, NSError *error) { [weakSelf hideLoading]; [weakSelf showError:error]; }; } - (void)transparentNavigationBar { [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; self.navigationController.navigationBar.shadowImage = [UIImage new]; self.navigationController.navigationBar.translucent = YES; self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self; } - (void)unTransparentNavigationBar { UIImage *image = [KWMImageUtil createColorImage:[UIColor sam_colorWithHex:@"FF982B"]]; [self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault]; self.navigationController.navigationBar.shadowImage = [UIImage new]; self.navigationController.navigationBar.translucent = NO; } - (UIBarButtonItem *)createBarButtonItem:(NSString *)title image:(UIImage *)image action:(SEL)action{ UIButton *btnView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)]; btnView.backgroundColor = [UIColor clearColor]; // btnView.titleLabel.textColor = [UIColor whiteColor]; // [btnView setTitle:title forState:UIControlStateNormal]; [btnView setImage:image forState:UIControlStateNormal]; [btnView addTarget:self action:action forControlEvents:UIControlEventTouchUpInside]; return [[UIBarButtonItem alloc] initWithCustomView:btnView]; } - (void)showPresentation:(UIViewController *)vc size:(CGSize)size tapOutsideClose:(BOOL)tapOutsideClose style:(MZFormSheetPresentationTransitionStyle)style { MZFormSheetPresentationViewController *mz = [[MZFormSheetPresentationViewController alloc] initWithContentViewController:vc]; mz.presentationController.shouldDismissOnBackgroundViewTap = tapOutsideClose; mz.presentationController.movementActionWhenKeyboardAppears = MZFormSheetActionWhenKeyboardAppearsCenterVertically; mz.contentViewControllerTransitionStyle = style; if (size.width > 0 && size.height > 0) { mz.presentationController.contentViewSize = size; } mz.presentationController.shouldCenterVertically = YES; [self presentViewController:mz animated:YES completion:nil]; } /**将URL转成UIImage*/ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { __block UIImage *sharImage; if (!(options & SDWebImageDelayPlaceholder)) { dispatch_main_async_safe(^{ sharImage = placeholder; }); } if (url) { __weak __typeof(self)wself = self; id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!wself) return; dispatch_main_sync_safe(^{ if (!wself) return; if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) { completedBlock(image, error, cacheType, url); return; } else if (image) { sharImage = image; } else { if ((options & SDWebImageDelayPlaceholder)) { sharImage = placeholder; } } if (completedBlock && finished) { completedBlock(image, error, cacheType, url); } }); }]; } else { dispatch_main_async_safe(^{ NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; if (completedBlock) { completedBlock(nil, error, SDImageCacheTypeNone, url); } }); } } @end