// // RQShareFunction.m // LN_School // // Created by 张嵘 on 2018/10/16. // Copyright © 2018 Danson. All rights reserved. // #import "RQShareFunction.h" #import "TZImagePickerController.h"//第三方相册 #import "TabBarController.h" #import "GKPhotoBrowser.h" #import #import "SMSDemoPolicyManager.h" #import "SLShotViewController.h" static RQShareFunction *_instance = nil; static dispatch_once_t onceToken; @interface RQShareFunction () @property (nonatomic, strong) NSArray *dataSource; @property (nonatomic, weak) GKPhotoBrowser *browser; @property (nonatomic, strong) UIPageControl *pageControl; @property (assign, readwrite, nonatomic) BOOL isCanSave; @end @implementation RQShareFunction + (instancetype)shareManager { return [[self alloc] init]; } - (instancetype)init{ dispatch_once(&onceToken, ^{ _instance = [super init]; }); return _instance; } - (void)setCurrentUserInterfaceStyle:(UIUserInterfaceStyle)currentUserInterfaceStyle { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; [userDefault setInteger:currentUserInterfaceStyle forKey:@"currentUserInterfaceStyle"]; [userDefault synchronize]; } - (UIUserInterfaceStyle)currentUserInterfaceStyle{ NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; if (@available(iOS 12.0, *)) { UIUserInterfaceStyle style = (UIUserInterfaceStyle)[userDefault integerForKey:@"currentUserInterfaceStyle"]? : UIUserInterfaceStyleUnspecified; return style; } else { return 0; } } - (NSArray *)typeOneCityCodeArr { return @[@"3501", @"3502"]; } - (NSArray *)typeTwoCityCodeArr { return @[@"3503"]; } // 时间转换为时间戳,精确到微秒 - (NSInteger)getTimeStampWithDate:(NSDate *)date { return [[NSNumber numberWithDouble:[date timeIntervalSince1970] * 1000 * 1000] integerValue]; } // 时间戳转换为时间 - (NSDate *)getDateWithTimeStamp:(NSInteger)timeStamp { return [NSDate dateWithTimeIntervalSince1970:timeStamp * 0.001 * 0.001]; } // 一个时间戳与当前时间的间隔(s) - (NSInteger)getIntervalsWithTimeStamp:(NSInteger)timeStamp { return [[NSDate date] timeIntervalSinceDate:[self getDateWithTimeStamp:timeStamp]]; } #pragma mark - GetPhotos - (void)getPhotosWithGetPhotosWay:(GetPhotosWay)getPhotosWay size:(CGSize)size maxLength:(NSUInteger)maxLength maxImagesCount:(NSUInteger)maxImagesCount photosBlock:(PhotosBlock)photosBlock { if (getPhotosWay == GetPhotosWay_Camera) { if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { SLShotViewController *vc = [[SLShotViewController alloc] init]; [vc initTakePhotoBlock:^(UIImage * _Nonnull image) { if (image) { NSMutableArray *imagesArr = [NSMutableArray arrayWithObject:image]; NSData *data; if (CGSizeEqualToSize(size, CGSizeZero)) { data = [self compressQualityWithImage:image MaxLength:maxLength]; }else { data = [self compressQualityWithImage:[image scaledAndCutToSize:size] MaxLength:maxLength]; } NSString *imgString = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; NSMutableArray *imagesDataStrArr = [NSMutableArray arrayWithObject:imgString]; if (photosBlock) { photosBlock(imagesArr, imagesDataStrArr); } } }]; dispatch_async(dispatch_get_main_queue(), ^{ vc.modalPresentationStyle = UIModalPresentationFullScreen; [[RQ_SHARE_FUNCTION topViewController] presentViewController:vc animated:NO completion:nil]; }); } else { NSLog(@"相机调用失败"); } }else if (getPhotosWay == GetPhotosWay_Album) { if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum]) { TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:maxImagesCount ? maxImagesCount : 1 delegate:nil]; imagePickerVc.naviBgColor = defGreen; imagePickerVc.iconThemeColor = defGreen; imagePickerVc.allowPickingVideo = NO; [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray *photos, NSArray *assets, BOOL isStop) { NSMutableArray *imagesDataStrArr = [NSMutableArray array]; @synchronized (imagesDataStrArr) { for (UIImage *image in photos) { NSData *data; if (CGSizeEqualToSize(size, CGSizeZero)) { data = [self compressQualityWithImage:image MaxLength:maxLength]; }else { data = [self compressQualityWithImage:[image scaledAndCutToSize:size] MaxLength:maxLength]; } NSString *imgString = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; [imagesDataStrArr addObject:imgString]; } } if (photosBlock) { photosBlock(photos, imagesDataStrArr); } }]; dispatch_async(dispatch_get_main_queue(), ^{ imagePickerVc.modalPresentationStyle = UIModalPresentationFullScreen; [[RQ_SHARE_FUNCTION topViewController] presentViewController:imagePickerVc animated:YES completion:nil]; }); }else{ NSLog(@"相册调用失败"); } } } #pragma mark - RQAlertViewController - (void)showAlertAtViewController:(nonnull UIViewController *)viewController WithTitle:(nullable NSString *)title message:(nullable NSString *)message alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitles:(nullable NSArray *)otherButtonTitles otherButtonStyles:(nullable NSDictionary *)otherButtonStyles preferredActionTitle:(nullable NSString *)preferredActionTitle completion:(nullable RQAlertViewCompletion)completion { __block UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:alertControllerStyle]; void (^alertActionHandler) (UIAlertAction *) = [^(UIAlertAction *action) { if (completion) { if (action.style == UIAlertActionStyleCancel) { completion(NSNotFound); }else { NSUInteger index = [alertController.actions indexOfObject:action]; completion(cancelButtonTitle? index - 1 : index); } } alertController = nil; } copy]; if (cancelButtonTitle) { UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:alertActionHandler]; if (@available(iOS 9.0, *)) { [cancleAction setValue:defGreen forKey:@"_titleTextColor"]; } else { // Fallback on earlier versions } [alertController addAction:cancleAction]; } if (otherButtonTitles.count == 0) { dispatch_async(dispatch_get_main_queue(), ^{ [[RQ_SHARE_FUNCTION topViewController] presentViewController:alertController animated:YES completion:nil]; }); }else { [otherButtonTitles.rac_sequence.signal subscribeNext:^(NSString * buttonTitle) { NSNumber *actionStyleNumber = [otherButtonStyles valueForKey:buttonTitle]; UIAlertActionStyle actionStyle = UIAlertActionStyleDefault; if (actionStyleNumber) { actionStyle = [actionStyleNumber integerValue]; } UIAlertAction *action = [UIAlertAction actionWithTitle:buttonTitle style:actionStyle handler:alertActionHandler]; if (@available(iOS 9.0, *)) { [action setValue:defGreen forKey:@"_titleTextColor"]; } else { // Fallback on earlier versions } [alertController addAction:action]; ///Support for iOS9 add preferredAction for highlights the text of that action if ([alertController respondsToSelector:@selector(setPreferredAction:)]) { if ([preferredActionTitle isEqualToString:buttonTitle]) { if (@available(iOS 9.0, *)) { [alertController setPreferredAction:action]; } else { // Fallback on earlier versions } } } } completed:^{ dispatch_async(dispatch_get_main_queue(), ^{ [[RQ_SHARE_FUNCTION topViewController] presentViewController:alertController animated:YES completion:nil]; }); }]; } } - (void)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitles:(nullable NSArray *)otherButtonTitles otherButtonStyles:(nullable NSDictionary *)otherButtonStyles preferredActionTitle:(nullable NSString *)preferredActionTitle completion:(nullable RQAlertViewCompletion)completion{ [self showAlertAtViewController:[RQ_SHARE_FUNCTION topViewController] WithTitle:title message:message alertControllerStyle:alertControllerStyle cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitles otherButtonStyles:otherButtonStyles preferredActionTitle:preferredActionTitle completion:completion]; } - (void)showAlertWithTitle:(nullable NSString *)title message:(nullable NSString *)message alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitles:(nullable NSArray *)otherButtonTitles otherButtonStyles:(nullable NSDictionary *)otherButtonStyles completion:(nullable RQAlertViewCompletion)completion { [self showAlertAtViewController:[RQ_SHARE_FUNCTION topViewController] WithTitle:title message:message alertControllerStyle:alertControllerStyle cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitles otherButtonStyles:otherButtonStyles preferredActionTitle:nil completion:completion]; } #pragma mark - Custom Way - (UIViewController *)topViewController { return [RQ_SHARE_FUNCTION topViewController:[UIApplication sharedApplication].keyWindow.rootViewController]; } - (UIViewController *)topViewController:(UIViewController*)rootViewController { if (rootViewController.presentedViewController == nil || rootViewController.presentedViewController.beingDismissed) { return rootViewController; } if ([rootViewController.presentedViewController isMemberOfClass:[UINavigationController class]]) { UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController; UIViewController *lastViewController = [[navigationController viewControllers] lastObject]; return [RQ_SHARE_FUNCTION topViewController:lastViewController]; } UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController; return [RQ_SHARE_FUNCTION topViewController:presentedViewController]; } - (UIViewController *)currentViewController { UIViewController *resultVC; resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]]; /// RQ Fixed : 这里必须要判断一下,否则取出来永远都是 RQMainTabBarViewController。这是架构上小缺(特)陷(性)。因为RQMainTabBarViewController的子控制器是UITabBarController,所以需要递归UITabBarController的所有的子控制器 if ([resultVC isKindOfClass:[TabBarController class]]) { TabBarController *mainVc = (TabBarController *)resultVC; resultVC = [self _topViewController:mainVc.tabBarController]; } while (resultVC.presentedViewController) { resultVC = [self _topViewController:resultVC.presentedViewController]; } return resultVC; } - (UIViewController *)_topViewController:(UIViewController *)vc { if ([vc isKindOfClass:[UINavigationController class]]) { return [self _topViewController:[(UINavigationController *)vc topViewController]]; } else if ([vc isKindOfClass:[UITabBarController class]]) { return [self _topViewController:[(UITabBarController *)vc selectedViewController]]; } else { return vc; } } - (NSData *)compressQualityWithImage:(UIImage *)image MaxLength:(NSInteger)maxLength { CGFloat compression = 1; NSData *data = UIImageJPEGRepresentation(image, compression); if (data.length < maxLength) return data; CGFloat max = 1; CGFloat min = 0; NSData *lastData; for (int i = 0; i < 99; ++i) { compression = (max + min) / 2; data = UIImageJPEGRepresentation(image, compression); if (data.length == lastData.length) { return data; }else { lastData = data; } if (data.length < maxLength * 0.9) { min = compression; } else if (data.length > maxLength) { max = compression; } else { break; } } return data; } - (void)showGuidePicture { UIButton* btn = [[UIButton alloc] initWithFrame:kFrame]; [myDelegate.window addSubview:btn]; [btn setImage:[UIImage imageNamed:@"welGuide2.png"] forState:UIControlStateNormal]; UIImageView* iv; iv = [[UIImageView alloc] initWithFrame:CGRectMake(3, 11, 70, 70)]; [iv setImage:[UIImage imageNamed:@"welGuide1.png"]]; [btn addSubview:iv]; [btn addTarget:self action:@selector(removeBtn:) forControlEvents:UIControlEventTouchUpInside]; } - (void)removeBtn:(UIButton *)btn { [btn removeFromSuperview]; } #pragma mark - 检查版本更新 - (void)checkVersion { /// 在当前页面有弹窗 以及在模拟计时页面 理论计时页面 模拟考试界面 不弹出更新提示 NSArray *controllers = @[@"UIAlertController", @"ExerciseVC", @"ImitatePeriodVC", @"PeriodVC"]; NSLog(@"string---Class-----%@",NSStringFromClass([RQ_SHARE_FUNCTION currentViewController].class)); if ([controllers containsObject:NSStringFromClass([RQ_SHARE_FUNCTION currentViewController].class)]) { return; } if (![Util connectedToNetWork]) { return; } NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary]; NSString *localVersion = [infoDic objectForKey:@"CFBundleShortVersionString"]; NSString *URL = @"http://itunes.apple.com/cn/lookup?id=1214200225"; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URL] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10]; [request setHTTPMethod:@"POST"]; NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { //这个导致部分手机网络不好时候出现闪退情况 if (!data) { return; } //如果data等于nil的时候 再去解析 会发生崩溃 NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; if (!dic) { return; } NSArray *infoArray = [dic objectForKey:@"results"]; if ([infoArray count]) { NSDictionary *releaseInfo = [infoArray objectAtIndex:0]; NSString *netVersion = [releaseInfo objectForKey:@"version"]; //NSLog(@"AppStore-->%@,手机上-->%@",lastVersion,currentVersion); // 线上版本号 NSInteger netInt = [[netVersion stringByReplacingOccurrencesOfString:@"." withString:@""] integerValue]; // 本地版本号 NSInteger localInt = [[localVersion stringByReplacingOccurrencesOfString:@"." withString:@""] integerValue]; if (netInt > localInt) { NSLog(@"更新"); [self updateVersion]; }else{ //已是最新版 NSLog(@"不更"); } } }]; [task resume]; } - (void)updateVersion { [RQ_SHARE_FUNCTION showAlertWithTitle:@"更新提示" message:@"有新的版本发布,请前往更新!!!" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:nil otherButtonTitles:@[@"确定"] otherButtonStyles:nil completion:^(NSUInteger selectedOtherButtonIndex) { if (selectedOtherButtonIndex == 0) { NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.apple.com/cn/app/ji-su-jia-pei-kua-jia-xiao-ban/id1214200225?l=en&mt=8"]; [[UIApplication sharedApplication] openURL:url]; } }]; } /** * 展示大图 * * @author ZhangRong * @date 2020-06-16 14:30:55 * * @param dataSource 图片数组(Url数组) * @param currentIndex 当前标签 * @param isCanSave 是否保存图片 */ - (void)showPhotoBrowserWithDataSource:(NSArray *)dataSource currentIndex:(NSInteger)currentIndex isCanSave:(BOOL)isCanSave { if (dataSource.count == 0) { ShowMsg(@"暂无图片"); return; } NSMutableArray *photos = [NSMutableArray new]; self.dataSource = dataSource; self.isCanSave = isCanSave; [self.dataSource enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj isKindOfClass:[NSDictionary class]]) { GKPhoto *photo = [GKPhoto new]; photo.url = [NSURL URLWithString:obj[@"IMGPATH"]]; [photos addObject:photo]; }else if ([obj isKindOfClass:[NSString class]]) { // 替换为中等尺寸图片 if ([obj rangeOfString:@"thumbnail"].location != NSNotFound) { //这个要了没用噢 除非以后我们有清晰的图 obj= [obj stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"]; } NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSString *str = [obj stringByTrimmingCharactersInSet:whitespace]; if (str && ![str hasPrefix:@"http"]){ str = [imgPreFix stringByAppendingString:[obj stringByTrimmingCharactersInSet:whitespace]]; } GKPhoto *photo = [GKPhoto new]; photo.url = [NSURL URLWithString:str]; [photos addObject:photo]; }else if ([obj isKindOfClass:[UIImage class]]) { GKPhoto *photo = [GKPhoto new]; photo.image = obj; [photos addObject:photo]; } }]; self.pageControl = [[UIPageControl alloc] init]; self.pageControl.numberOfPages = photos.count; self.pageControl.currentPage = currentIndex; self.pageControl.hidesForSinglePage = YES; self.browser = [GKPhotoBrowser photoBrowserWithPhotos:photos currentIndex:currentIndex]; _browser.delegate = self; _browser.showStyle = GKPhotoBrowserShowStyleNone; // 缩放显示 _browser.hideStyle = GKPhotoBrowserHideStyleZoomScale; // 缩放隐藏 _browser.loadStyle = GKPhotoBrowserLoadStyleDeterminate; // 不明确的加载方式带阴影 _browser.maxZoomScale = 20.0f; _browser.doubleZoomScale = 2.0f; [_browser setupCoverViews:@[self.pageControl] layoutBlock:^(GKPhotoBrowser *photoBrowser, CGRect superFrame) { CGFloat pointY = 0; if (photoBrowser.isLandspace) { pointY = superFrame.size.height - 20; }else { pointY = superFrame.size.height - 10 - kSafeAreaBottomHeight; } self.pageControl.center = CGPointMake(superFrame.size.width * 0.5, pointY); }]; [_browser showFromVC:[RQ_SHARE_FUNCTION topViewController]]; } #pragma mark - GKPhotoBrowserDelegate - (void)photoBrowser:(GKPhotoBrowser *)browser didChangedIndex:(NSInteger)index { self.pageControl.currentPage = index; } - (void)photoBrowser:(GKPhotoBrowser *)browser longPressWithIndex:(NSInteger)index { if (!_isCanSave) return; [RQ_SHARE_FUNCTION showAlertWithTitle:nil message:nil alertControllerStyle:UIAlertControllerStyleActionSheet cancelButtonTitle:@"取消" otherButtonTitles:@[@"保存图片"] otherButtonStyles:nil completion:^(NSUInteger selectedOtherButtonIndex) { if (selectedOtherButtonIndex == 0) { GKPhoto *photo = self.browser.photos[self.browser.currentIndex]; NSData *imageData = nil; if ([photo.image isKindOfClass:[SDAnimatedImage class]]) { imageData = [(SDAnimatedImage *)photo.image animatedImageData]; }else { imageData = [photo.image sd_imageData]; } if (!imageData) return; [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ if (@available(iOS 9, *)) { PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset]; [request addResourceWithType:PHAssetResourceTypePhoto data:imageData options:nil]; request.creationDate = [NSDate date]; } } completionHandler:^(BOOL success, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ if (success) { NSLog(@"保存照片成功"); ShowMsg(@"图片保存成功"); } else if (error) { ShowMsg(@"保存保存失败"); NSLog(@"保存照片出错:%@",error.localizedDescription); } }); }]; } }]; } /** * Mob隐私判断 * * @author ZhangRong * @date 2020-06-16 14:30:55 */ - (void)checkMobPolicyOnResult:(void (^_Nullable)(BOOL success))handler { //获取隐私协议 [MobSDK getPrivacyPolicy:@"1" language:@"zh" compeletion:^(NSDictionary * _Nullable data, NSError * _Nullable error) { NSString *url = data[@"content"]; if(url) { [SMSDemoPolicyManager show:url compeletion:^(BOOL accept) { //是否接受隐私协议 [MobSDK uploadPrivacyPermissionStatus:accept onResult:^(BOOL success) { handler(success); }]; }]; } }]; } @end