RQShareFunction.m 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. //
  2. // RQShareFunction.m
  3. // LN_School
  4. //
  5. // Created by 张嵘 on 2018/10/16.
  6. // Copyright © 2018 Danson. All rights reserved.
  7. //
  8. #import "RQShareFunction.h"
  9. #import "TZImagePickerController.h"//第三方相册
  10. #import "TabBarController.h"
  11. #import "GKPhotoBrowser.h"
  12. #import <MOBFoundation/MobSDK+Privacy.h>
  13. #import "SMSDemoPolicyManager.h"
  14. #import "SLShotViewController.h"
  15. static RQShareFunction *_instance = nil;
  16. static dispatch_once_t onceToken;
  17. @interface RQShareFunction ()<GKPhotoBrowserDelegate>
  18. @property (nonatomic, strong) NSArray *dataSource;
  19. @property (nonatomic, weak) GKPhotoBrowser *browser;
  20. @property (nonatomic, strong) UIPageControl *pageControl;
  21. @property (assign, readwrite, nonatomic) BOOL isCanSave;
  22. @end
  23. @implementation RQShareFunction
  24. + (instancetype)shareManager {
  25. return [[self alloc] init];
  26. }
  27. - (instancetype)init{
  28. dispatch_once(&onceToken, ^{
  29. _instance = [super init];
  30. });
  31. return _instance;
  32. }
  33. - (void)setCurrentUserInterfaceStyle:(UIUserInterfaceStyle)currentUserInterfaceStyle {
  34. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  35. [userDefault setInteger:currentUserInterfaceStyle forKey:@"currentUserInterfaceStyle"];
  36. [userDefault synchronize];
  37. }
  38. - (UIUserInterfaceStyle)currentUserInterfaceStyle{
  39. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  40. if (@available(iOS 12.0, *)) {
  41. UIUserInterfaceStyle style = (UIUserInterfaceStyle)[userDefault integerForKey:@"currentUserInterfaceStyle"]? : UIUserInterfaceStyleUnspecified;
  42. return style;
  43. } else {
  44. return 0;
  45. }
  46. }
  47. - (NSArray *)typeOneCityCodeArr {
  48. return @[@"3501", @"3502"];
  49. }
  50. - (NSArray *)typeTwoCityCodeArr {
  51. return @[@"3503"];
  52. }
  53. // 时间转换为时间戳,精确到微秒
  54. - (NSInteger)getTimeStampWithDate:(NSDate *)date {
  55. return [[NSNumber numberWithDouble:[date timeIntervalSince1970] * 1000 * 1000] integerValue];
  56. }
  57. // 时间戳转换为时间
  58. - (NSDate *)getDateWithTimeStamp:(NSInteger)timeStamp {
  59. return [NSDate dateWithTimeIntervalSince1970:timeStamp * 0.001 * 0.001];
  60. }
  61. // 一个时间戳与当前时间的间隔(s)
  62. - (NSInteger)getIntervalsWithTimeStamp:(NSInteger)timeStamp {
  63. return [[NSDate date] timeIntervalSinceDate:[self getDateWithTimeStamp:timeStamp]];
  64. }
  65. #pragma mark - GetPhotos
  66. - (void)getPhotosWithGetPhotosWay:(GetPhotosWay)getPhotosWay size:(CGSize)size maxLength:(NSUInteger)maxLength maxImagesCount:(NSUInteger)maxImagesCount photosBlock:(PhotosBlock)photosBlock {
  67. if (getPhotosWay == GetPhotosWay_Camera) {
  68. if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
  69. SLShotViewController *vc = [[SLShotViewController alloc] init];
  70. [vc initTakePhotoBlock:^(UIImage * _Nonnull image) {
  71. if (image) {
  72. NSMutableArray *imagesArr = [NSMutableArray arrayWithObject:image];
  73. NSData *data;
  74. if (CGSizeEqualToSize(size, CGSizeZero)) {
  75. data = [self compressQualityWithImage:image MaxLength:maxLength];
  76. }else {
  77. data = [self compressQualityWithImage:[image scaledAndCutToSize:size] MaxLength:maxLength];
  78. }
  79. NSString *imgString = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
  80. NSMutableArray *imagesDataStrArr = [NSMutableArray arrayWithObject:imgString];
  81. if (photosBlock) {
  82. photosBlock(imagesArr, imagesDataStrArr);
  83. }
  84. }
  85. }];
  86. dispatch_async(dispatch_get_main_queue(), ^{
  87. vc.modalPresentationStyle = UIModalPresentationFullScreen;
  88. [[RQ_SHARE_FUNCTION topViewController] presentViewController:vc
  89. animated:NO
  90. completion:nil];
  91. });
  92. } else {
  93. NSLog(@"相机调用失败");
  94. }
  95. }else if (getPhotosWay == GetPhotosWay_Album) {
  96. if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum]) {
  97. TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:maxImagesCount ? maxImagesCount : 1 delegate:nil];
  98. imagePickerVc.naviBgColor = defGreen;
  99. imagePickerVc.iconThemeColor = defGreen;
  100. imagePickerVc.allowPickingVideo = NO;
  101. [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isStop) {
  102. NSMutableArray *imagesDataStrArr = [NSMutableArray array];
  103. @synchronized (imagesDataStrArr) {
  104. for (UIImage *image in photos) {
  105. NSData *data;
  106. if (CGSizeEqualToSize(size, CGSizeZero)) {
  107. data = [self compressQualityWithImage:image MaxLength:maxLength];
  108. }else {
  109. data = [self compressQualityWithImage:[image scaledAndCutToSize:size] MaxLength:maxLength];
  110. }
  111. NSString *imgString = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
  112. [imagesDataStrArr addObject:imgString];
  113. }
  114. }
  115. if (photosBlock) {
  116. photosBlock(photos, imagesDataStrArr);
  117. }
  118. }];
  119. dispatch_async(dispatch_get_main_queue(), ^{
  120. imagePickerVc.modalPresentationStyle = UIModalPresentationFullScreen;
  121. [[RQ_SHARE_FUNCTION topViewController] presentViewController:imagePickerVc animated:YES completion:nil];
  122. });
  123. }else{
  124. NSLog(@"相册调用失败");
  125. }
  126. }
  127. }
  128. #pragma mark - RQAlertViewController
  129. - (void)showAlertAtViewController:(nonnull UIViewController *)viewController
  130. WithTitle:(nullable NSString *)title
  131. message:(nullable NSString *)message
  132. alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle
  133. cancelButtonTitle:(nullable NSString *)cancelButtonTitle
  134. otherButtonTitles:(nullable NSArray *)otherButtonTitles
  135. otherButtonStyles:(nullable NSDictionary *)otherButtonStyles
  136. preferredActionTitle:(nullable NSString *)preferredActionTitle
  137. completion:(nullable RQAlertViewCompletion)completion {
  138. __block UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:alertControllerStyle];
  139. void (^alertActionHandler) (UIAlertAction *) = [^(UIAlertAction *action) {
  140. if (completion) {
  141. if (action.style == UIAlertActionStyleCancel) {
  142. completion(NSNotFound);
  143. }else {
  144. NSUInteger index = [alertController.actions indexOfObject:action];
  145. completion(cancelButtonTitle? index - 1 : index);
  146. }
  147. }
  148. alertController = nil;
  149. } copy];
  150. if (cancelButtonTitle) {
  151. UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:alertActionHandler];
  152. if (@available(iOS 9.0, *)) {
  153. [cancleAction setValue:defGreen forKey:@"_titleTextColor"];
  154. } else {
  155. // Fallback on earlier versions
  156. }
  157. [alertController addAction:cancleAction];
  158. }
  159. if (otherButtonTitles.count == 0) {
  160. dispatch_async(dispatch_get_main_queue(), ^{
  161. [[RQ_SHARE_FUNCTION topViewController] presentViewController:alertController animated:YES completion:nil];
  162. });
  163. }else {
  164. [otherButtonTitles.rac_sequence.signal subscribeNext:^(NSString * buttonTitle) {
  165. NSNumber *actionStyleNumber = [otherButtonStyles valueForKey:buttonTitle];
  166. UIAlertActionStyle actionStyle = UIAlertActionStyleDefault;
  167. if (actionStyleNumber) {
  168. actionStyle = [actionStyleNumber integerValue];
  169. }
  170. UIAlertAction *action = [UIAlertAction actionWithTitle:buttonTitle
  171. style:actionStyle
  172. handler:alertActionHandler];
  173. if (@available(iOS 9.0, *)) {
  174. [action setValue:defGreen forKey:@"_titleTextColor"];
  175. } else {
  176. // Fallback on earlier versions
  177. }
  178. [alertController addAction:action];
  179. ///Support for iOS9 add preferredAction for highlights the text of that action
  180. if ([alertController respondsToSelector:@selector(setPreferredAction:)]) {
  181. if ([preferredActionTitle isEqualToString:buttonTitle]) {
  182. if (@available(iOS 9.0, *)) {
  183. [alertController setPreferredAction:action];
  184. } else {
  185. // Fallback on earlier versions
  186. }
  187. }
  188. }
  189. } completed:^{
  190. dispatch_async(dispatch_get_main_queue(), ^{
  191. [[RQ_SHARE_FUNCTION topViewController] presentViewController:alertController animated:YES completion:nil];
  192. });
  193. }];
  194. }
  195. }
  196. - (void)showAlertWithTitle:(nullable NSString *)title
  197. message:(nullable NSString *)message
  198. alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle
  199. cancelButtonTitle:(nullable NSString *)cancelButtonTitle
  200. otherButtonTitles:(nullable NSArray *)otherButtonTitles
  201. otherButtonStyles:(nullable NSDictionary *)otherButtonStyles
  202. preferredActionTitle:(nullable NSString *)preferredActionTitle
  203. completion:(nullable RQAlertViewCompletion)completion{
  204. [self showAlertAtViewController:[RQ_SHARE_FUNCTION topViewController]
  205. WithTitle:title
  206. message:message
  207. alertControllerStyle:alertControllerStyle
  208. cancelButtonTitle:cancelButtonTitle
  209. otherButtonTitles:otherButtonTitles
  210. otherButtonStyles:otherButtonStyles
  211. preferredActionTitle:preferredActionTitle
  212. completion:completion];
  213. }
  214. - (void)showAlertWithTitle:(nullable NSString *)title
  215. message:(nullable NSString *)message
  216. alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle
  217. cancelButtonTitle:(nullable NSString *)cancelButtonTitle
  218. otherButtonTitles:(nullable NSArray *)otherButtonTitles
  219. otherButtonStyles:(nullable NSDictionary *)otherButtonStyles
  220. completion:(nullable RQAlertViewCompletion)completion {
  221. [self showAlertAtViewController:[RQ_SHARE_FUNCTION topViewController]
  222. WithTitle:title
  223. message:message
  224. alertControllerStyle:alertControllerStyle
  225. cancelButtonTitle:cancelButtonTitle
  226. otherButtonTitles:otherButtonTitles
  227. otherButtonStyles:otherButtonStyles
  228. preferredActionTitle:nil
  229. completion:completion];
  230. }
  231. #pragma mark - Custom Way
  232. - (UIViewController *)topViewController {
  233. return [RQ_SHARE_FUNCTION topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
  234. }
  235. - (UIViewController *)topViewController:(UIViewController*)rootViewController {
  236. if (rootViewController.presentedViewController == nil ||
  237. rootViewController.presentedViewController.beingDismissed) {
  238. return rootViewController;
  239. }
  240. if ([rootViewController.presentedViewController isMemberOfClass:[UINavigationController class]]) {
  241. UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
  242. UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
  243. return [RQ_SHARE_FUNCTION topViewController:lastViewController];
  244. }
  245. UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
  246. return [RQ_SHARE_FUNCTION topViewController:presentedViewController];
  247. }
  248. - (UIViewController *)currentViewController {
  249. UIViewController *resultVC;
  250. resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]];
  251. /// RQ Fixed : 这里必须要判断一下,否则取出来永远都是 RQMainTabBarViewController。这是架构上小缺(特)陷(性)。因为RQMainTabBarViewController的子控制器是UITabBarController,所以需要递归UITabBarController的所有的子控制器
  252. if ([resultVC isKindOfClass:[TabBarController class]]) {
  253. TabBarController *mainVc = (TabBarController *)resultVC;
  254. resultVC = [self _topViewController:mainVc.tabBarController];
  255. }
  256. while (resultVC.presentedViewController) {
  257. resultVC = [self _topViewController:resultVC.presentedViewController];
  258. }
  259. return resultVC;
  260. }
  261. - (UIViewController *)_topViewController:(UIViewController *)vc {
  262. if ([vc isKindOfClass:[UINavigationController class]]) {
  263. return [self _topViewController:[(UINavigationController *)vc topViewController]];
  264. } else if ([vc isKindOfClass:[UITabBarController class]]) {
  265. return [self _topViewController:[(UITabBarController *)vc selectedViewController]];
  266. } else {
  267. return vc;
  268. }
  269. }
  270. - (NSData *)compressQualityWithImage:(UIImage *)image MaxLength:(NSInteger)maxLength {
  271. CGFloat compression = 1;
  272. NSData *data = UIImageJPEGRepresentation(image, compression);
  273. if (data.length < maxLength) return data;
  274. CGFloat max = 1;
  275. CGFloat min = 0;
  276. NSData *lastData;
  277. for (int i = 0; i < 99; ++i) {
  278. compression = (max + min) / 2;
  279. data = UIImageJPEGRepresentation(image, compression);
  280. if (data.length == lastData.length) {
  281. return data;
  282. }else {
  283. lastData = data;
  284. }
  285. if (data.length < maxLength * 0.9) {
  286. min = compression;
  287. } else if (data.length > maxLength) {
  288. max = compression;
  289. } else {
  290. break;
  291. }
  292. }
  293. return data;
  294. }
  295. - (void)showGuidePicture {
  296. UIButton* btn = [[UIButton alloc] initWithFrame:kFrame];
  297. [myDelegate.window addSubview:btn];
  298. [btn setImage:[UIImage imageNamed:@"welGuide2.png"] forState:UIControlStateNormal];
  299. UIImageView* iv;
  300. iv = [[UIImageView alloc] initWithFrame:CGRectMake(3, 11, 70, 70)];
  301. [iv setImage:[UIImage imageNamed:@"welGuide1.png"]];
  302. [btn addSubview:iv];
  303. [btn addTarget:self action:@selector(removeBtn:) forControlEvents:UIControlEventTouchUpInside];
  304. }
  305. - (void)removeBtn:(UIButton *)btn {
  306. [btn removeFromSuperview];
  307. }
  308. #pragma mark - 检查版本更新
  309. - (void)checkVersion {
  310. /// 在当前页面有弹窗 以及在模拟计时页面 理论计时页面 模拟考试界面 不弹出更新提示
  311. NSArray *controllers = @[@"UIAlertController", @"ExerciseVC", @"ImitatePeriodVC", @"PeriodVC"];
  312. NSLog(@"string---Class-----%@",NSStringFromClass([RQ_SHARE_FUNCTION currentViewController].class));
  313. if ([controllers containsObject:NSStringFromClass([RQ_SHARE_FUNCTION currentViewController].class)]) {
  314. return;
  315. }
  316. if (![Util connectedToNetWork]) {
  317. return;
  318. }
  319. NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
  320. NSString *localVersion = [infoDic objectForKey:@"CFBundleShortVersionString"];
  321. NSString *URL = @"http://itunes.apple.com/cn/lookup?id=1214200225";
  322. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URL] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
  323. [request setHTTPMethod:@"POST"];
  324. NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
  325. //这个导致部分手机网络不好时候出现闪退情况
  326. if (!data) {
  327. return;
  328. }
  329. //如果data等于nil的时候 再去解析 会发生崩溃
  330. NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
  331. if (!dic) {
  332. return;
  333. }
  334. NSArray *infoArray = [dic objectForKey:@"results"];
  335. if ([infoArray count]) {
  336. NSDictionary *releaseInfo = [infoArray objectAtIndex:0];
  337. NSString *netVersion = [releaseInfo objectForKey:@"version"];
  338. //NSLog(@"AppStore-->%@,手机上-->%@",lastVersion,currentVersion);
  339. // 线上版本号
  340. NSInteger netInt = [[netVersion stringByReplacingOccurrencesOfString:@"." withString:@""] integerValue];
  341. // 本地版本号
  342. NSInteger localInt = [[localVersion stringByReplacingOccurrencesOfString:@"." withString:@""] integerValue];
  343. if (netInt > localInt) {
  344. NSLog(@"更新");
  345. [self updateVersion];
  346. }else{
  347. //已是最新版
  348. NSLog(@"不更");
  349. }
  350. }
  351. }];
  352. [task resume];
  353. }
  354. - (void)updateVersion {
  355. [RQ_SHARE_FUNCTION showAlertWithTitle:@"更新提示" message:@"有新的版本发布,请前往更新!!!" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:nil otherButtonTitles:@[@"确定"] otherButtonStyles:nil completion:^(NSUInteger selectedOtherButtonIndex) {
  356. if (selectedOtherButtonIndex == 0) {
  357. NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.apple.com/cn/app/ji-su-jia-pei-kua-jia-xiao-ban/id1214200225?l=en&mt=8"];
  358. [[UIApplication sharedApplication] openURL:url];
  359. }
  360. }];
  361. }
  362. /**
  363. * 展示大图
  364. *
  365. * @author ZhangRong
  366. * @date 2020-06-16 14:30:55
  367. *
  368. * @param dataSource 图片数组(Url数组)
  369. * @param currentIndex 当前标签
  370. * @param isCanSave 是否保存图片
  371. */
  372. - (void)showPhotoBrowserWithDataSource:(NSArray *)dataSource currentIndex:(NSInteger)currentIndex isCanSave:(BOOL)isCanSave {
  373. if (dataSource.count == 0) {
  374. ShowMsg(@"暂无图片");
  375. return;
  376. }
  377. NSMutableArray *photos = [NSMutableArray new];
  378. self.dataSource = dataSource;
  379. self.isCanSave = isCanSave;
  380. [self.dataSource enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  381. if ([obj isKindOfClass:[NSDictionary class]]) {
  382. GKPhoto *photo = [GKPhoto new];
  383. photo.url = [NSURL URLWithString:obj[@"IMGPATH"]];
  384. [photos addObject:photo];
  385. }else if ([obj isKindOfClass:[NSString class]]) {
  386. // 替换为中等尺寸图片
  387. if ([obj rangeOfString:@"thumbnail"].location != NSNotFound) {
  388. //这个要了没用噢 除非以后我们有清晰的图
  389. obj= [obj stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"];
  390. }
  391. NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  392. NSString *str = [obj stringByTrimmingCharactersInSet:whitespace];
  393. if (str && ![str hasPrefix:@"http"]){
  394. str = [imgPreFix stringByAppendingString:[obj stringByTrimmingCharactersInSet:whitespace]];
  395. }
  396. GKPhoto *photo = [GKPhoto new];
  397. photo.url = [NSURL URLWithString:str];
  398. [photos addObject:photo];
  399. }else if ([obj isKindOfClass:[UIImage class]]) {
  400. GKPhoto *photo = [GKPhoto new];
  401. photo.image = obj;
  402. [photos addObject:photo];
  403. }
  404. }];
  405. self.pageControl = [[UIPageControl alloc] init];
  406. self.pageControl.numberOfPages = photos.count;
  407. self.pageControl.currentPage = currentIndex;
  408. self.pageControl.hidesForSinglePage = YES;
  409. self.browser = [GKPhotoBrowser photoBrowserWithPhotos:photos currentIndex:currentIndex];
  410. _browser.delegate = self;
  411. _browser.showStyle = GKPhotoBrowserShowStyleNone; // 缩放显示
  412. _browser.hideStyle = GKPhotoBrowserHideStyleZoomScale; // 缩放隐藏
  413. _browser.loadStyle = GKPhotoBrowserLoadStyleDeterminate; // 不明确的加载方式带阴影
  414. _browser.maxZoomScale = 20.0f;
  415. _browser.doubleZoomScale = 2.0f;
  416. [_browser setupCoverViews:@[self.pageControl] layoutBlock:^(GKPhotoBrowser *photoBrowser, CGRect superFrame) {
  417. CGFloat pointY = 0;
  418. if (photoBrowser.isLandspace) {
  419. pointY = superFrame.size.height - 20;
  420. }else {
  421. pointY = superFrame.size.height - 10 - kSafeAreaBottomHeight;
  422. }
  423. self.pageControl.center = CGPointMake(superFrame.size.width * 0.5, pointY);
  424. }];
  425. [_browser showFromVC:[RQ_SHARE_FUNCTION topViewController]];
  426. }
  427. #pragma mark - GKPhotoBrowserDelegate
  428. - (void)photoBrowser:(GKPhotoBrowser *)browser didChangedIndex:(NSInteger)index {
  429. self.pageControl.currentPage = index;
  430. }
  431. - (void)photoBrowser:(GKPhotoBrowser *)browser longPressWithIndex:(NSInteger)index {
  432. if (!_isCanSave) return;
  433. [RQ_SHARE_FUNCTION showAlertWithTitle:nil message:nil alertControllerStyle:UIAlertControllerStyleActionSheet cancelButtonTitle:@"取消" otherButtonTitles:@[@"保存图片"] otherButtonStyles:nil completion:^(NSUInteger selectedOtherButtonIndex) {
  434. if (selectedOtherButtonIndex == 0) {
  435. GKPhoto *photo = self.browser.photos[self.browser.currentIndex];
  436. NSData *imageData = nil;
  437. if ([photo.image isKindOfClass:[SDAnimatedImage class]]) {
  438. imageData = [(SDAnimatedImage *)photo.image animatedImageData];
  439. }else {
  440. imageData = [photo.image sd_imageData];
  441. }
  442. if (!imageData) return;
  443. [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
  444. if (@available(iOS 9, *)) {
  445. PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];
  446. [request addResourceWithType:PHAssetResourceTypePhoto data:imageData options:nil];
  447. request.creationDate = [NSDate date];
  448. }
  449. } completionHandler:^(BOOL success, NSError *error) {
  450. dispatch_async(dispatch_get_main_queue(), ^{
  451. if (success) {
  452. NSLog(@"保存照片成功");
  453. ShowMsg(@"图片保存成功");
  454. } else if (error) {
  455. ShowMsg(@"保存保存失败");
  456. NSLog(@"保存照片出错:%@",error.localizedDescription);
  457. }
  458. });
  459. }];
  460. }
  461. }];
  462. }
  463. /**
  464. * Mob隐私判断
  465. *
  466. * @author ZhangRong
  467. * @date 2020-06-16 14:30:55
  468. */
  469. - (void)checkMobPolicyOnResult:(void (^_Nullable)(BOOL success))handler {
  470. //获取隐私协议
  471. [MobSDK getPrivacyPolicy:@"1" language:@"zh" compeletion:^(NSDictionary * _Nullable data, NSError * _Nullable error) {
  472. NSString *url = data[@"content"];
  473. if(url) {
  474. [SMSDemoPolicyManager show:url compeletion:^(BOOL accept) {
  475. //是否接受隐私协议
  476. [MobSDK uploadPrivacyPermissionStatus:accept onResult:^(BOOL success) {
  477. handler(success);
  478. }];
  479. }];
  480. }
  481. }];
  482. }
  483. @end