RQShareFunction.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  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 "LocalNotificationManager.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)setShieldTopicIDArr:(NSArray *)shieldTopicIDArr {
  34. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  35. [userDefault setObject:shieldTopicIDArr forKey:@"shieldTopicIDArr"];
  36. [userDefault synchronize];
  37. }
  38. - (NSArray *)shieldTopicIDArr {
  39. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  40. NSArray *arr = (NSArray *)[userDefault objectForKey:@"shieldTopicIDArr"]? : [NSArray array];
  41. return arr;
  42. }
  43. - (void)setShieldPeopleIDArr:(NSArray *)shieldPeopleIDArr {
  44. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  45. [userDefault setObject:shieldPeopleIDArr forKey:@"shieldPeopleIDArr"];
  46. [userDefault synchronize];
  47. }
  48. - (NSArray *)shieldPeopleIDArr {
  49. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  50. NSArray *arr = (NSArray *)[userDefault objectForKey:@"shieldPeopleIDArr"]? : [NSArray array];
  51. return arr;
  52. }
  53. - (void)setAnnouncementIDArr:(NSArray *)announcementIDArr {
  54. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  55. [userDefault setObject:announcementIDArr forKey:@"announcementIDArr"];
  56. [userDefault synchronize];
  57. }
  58. - (NSArray *)announcementIDArr {
  59. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  60. NSArray *arr = (NSArray *)[userDefault objectForKey:@"announcementIDArr"]? : [NSArray array];
  61. return arr;
  62. }
  63. // 时间转换为时间戳,精确到微秒
  64. - (NSInteger)getTimeStampWithDate:(NSDate *)date {
  65. return [[NSNumber numberWithDouble:[date timeIntervalSince1970] * 1000 * 1000] integerValue];
  66. }
  67. // 时间戳转换为时间
  68. - (NSDate *)getDateWithTimeStamp:(NSInteger)timeStamp {
  69. return [NSDate dateWithTimeIntervalSince1970:timeStamp * 0.001 * 0.001];
  70. }
  71. // 一个时间戳与当前时间的间隔(s)
  72. - (NSInteger)getIntervalsWithTimeStamp:(NSInteger)timeStamp {
  73. return [[NSDate date] timeIntervalSinceDate:[self getDateWithTimeStamp:timeStamp]];
  74. }
  75. - (NSString *)getCurrentTimeString {
  76. NSDate *date = [NSDate date];
  77. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  78. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  79. NSString *dateString = [formatter stringFromDate:date];
  80. NSString *timeString = dateString;
  81. return timeString;
  82. }
  83. - (NSString *)getCurrentTimeStringWithTimeStamp:(NSInteger)timeStamp {
  84. NSDate *date = [NSDate date];
  85. NSInteger timeStamp0 = [self getTimeStampWithDate:date];
  86. NSInteger timeStamp1 = timeStamp0 + (timeStamp * 1000 * 1000);
  87. NSDate *date1 = [self getDateWithTimeStamp:timeStamp1];
  88. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  89. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  90. NSString *dateString = [formatter stringFromDate:date1];
  91. NSString *timeString = dateString;
  92. NSLog(@"%@",timeString);
  93. return timeString;
  94. }
  95. #pragma mark - RQAlertViewController
  96. - (void)showAlertAtViewController:(nonnull UIViewController *)viewController
  97. WithTitle:(nullable NSString *)title
  98. message:(nullable NSString *)message
  99. alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle
  100. cancelButtonTitle:(nullable NSString *)cancelButtonTitle
  101. otherButtonTitles:(nullable NSArray *)otherButtonTitles
  102. otherButtonStyles:(nullable NSDictionary *)otherButtonStyles
  103. preferredActionTitle:(nullable NSString *)preferredActionTitle
  104. completion:(nullable RQAlertViewCompletion)completion {
  105. __block UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:alertControllerStyle];
  106. void (^alertActionHandler) (UIAlertAction *) = [^(UIAlertAction *action) {
  107. if (completion) {
  108. if (action.style == UIAlertActionStyleCancel) {
  109. completion(NSNotFound);
  110. }else {
  111. NSUInteger index = [alertController.actions indexOfObject:action];
  112. completion(cancelButtonTitle? index - 1 : index);
  113. }
  114. }
  115. alertController = nil;
  116. } copy];
  117. if (cancelButtonTitle) {
  118. UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:alertActionHandler];
  119. if (@available(iOS 9.0, *)) {
  120. [cancleAction setValue:defGreen forKey:@"_titleTextColor"];
  121. } else {
  122. // Fallback on earlier versions
  123. }
  124. [alertController addAction:cancleAction];
  125. }
  126. if (otherButtonTitles.count == 0) {
  127. dispatch_async(dispatch_get_main_queue(), ^{
  128. [[RQ_SHARE_FUNCTION topViewController] presentViewController:alertController animated:YES completion:nil];
  129. });
  130. }else {
  131. [otherButtonTitles.rac_sequence.signal subscribeNext:^(NSString * buttonTitle) {
  132. NSNumber *actionStyleNumber = [otherButtonStyles valueForKey:buttonTitle];
  133. UIAlertActionStyle actionStyle = UIAlertActionStyleDefault;
  134. if (actionStyleNumber) {
  135. actionStyle = [actionStyleNumber integerValue];
  136. }
  137. UIAlertAction *action = [UIAlertAction actionWithTitle:buttonTitle
  138. style:actionStyle
  139. handler:alertActionHandler];
  140. if (@available(iOS 9.0, *)) {
  141. [action setValue:defGreen forKey:@"_titleTextColor"];
  142. } else {
  143. // Fallback on earlier versions
  144. }
  145. dispatch_async(dispatch_get_main_queue(), ^{
  146. [alertController addAction:action];
  147. });
  148. ///Support for iOS9 add preferredAction for highlights the text of that action
  149. if ([alertController respondsToSelector:@selector(setPreferredAction:)]) {
  150. if ([preferredActionTitle isEqualToString:buttonTitle]) {
  151. if (@available(iOS 9.0, *)) {
  152. [alertController setPreferredAction:action];
  153. } else {
  154. // Fallback on earlier versions
  155. }
  156. }
  157. }
  158. } completed:^{
  159. dispatch_async(dispatch_get_main_queue(), ^{
  160. [[RQ_SHARE_FUNCTION topViewController] presentViewController:alertController animated:YES completion:nil];
  161. });
  162. }];
  163. }
  164. }
  165. - (void)showAlertWithTitle:(nullable NSString *)title
  166. message:(nullable NSString *)message
  167. alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle
  168. cancelButtonTitle:(nullable NSString *)cancelButtonTitle
  169. otherButtonTitles:(nullable NSArray *)otherButtonTitles
  170. otherButtonStyles:(nullable NSDictionary *)otherButtonStyles
  171. preferredActionTitle:(nullable NSString *)preferredActionTitle
  172. completion:(nullable RQAlertViewCompletion)completion{
  173. [self showAlertAtViewController:[RQ_SHARE_FUNCTION topViewController]
  174. WithTitle:title
  175. message:message
  176. alertControllerStyle:alertControllerStyle
  177. cancelButtonTitle:cancelButtonTitle
  178. otherButtonTitles:otherButtonTitles
  179. otherButtonStyles:otherButtonStyles
  180. preferredActionTitle:preferredActionTitle
  181. completion:completion];
  182. }
  183. - (void)showAlertWithTitle:(nullable NSString *)title
  184. message:(nullable NSString *)message
  185. alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle
  186. cancelButtonTitle:(nullable NSString *)cancelButtonTitle
  187. otherButtonTitles:(nullable NSArray *)otherButtonTitles
  188. otherButtonStyles:(nullable NSDictionary *)otherButtonStyles
  189. completion:(nullable RQAlertViewCompletion)completion {
  190. [self showAlertAtViewController:[RQ_SHARE_FUNCTION topViewController]
  191. WithTitle:title
  192. message:message
  193. alertControllerStyle:alertControllerStyle
  194. cancelButtonTitle:cancelButtonTitle
  195. otherButtonTitles:otherButtonTitles
  196. otherButtonStyles:otherButtonStyles
  197. preferredActionTitle:nil
  198. completion:completion];
  199. }
  200. #pragma mark - Custom Way
  201. - (UIViewController *)topViewController {
  202. return [RQ_SHARE_FUNCTION topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
  203. }
  204. - (UIViewController *)topViewController:(UIViewController*)rootViewController {
  205. if (rootViewController.presentedViewController == nil ||
  206. rootViewController.presentedViewController.beingDismissed) {
  207. return rootViewController;
  208. }
  209. if ([rootViewController.presentedViewController isMemberOfClass:[UINavigationController class]]) {
  210. UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
  211. UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
  212. return [RQ_SHARE_FUNCTION topViewController:lastViewController];
  213. }
  214. UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
  215. return [RQ_SHARE_FUNCTION topViewController:presentedViewController];
  216. }
  217. - (UIViewController *)currentViewController {
  218. UIViewController *resultVC;
  219. resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]];
  220. /// RQ Fixed : 这里必须要判断一下,否则取出来永远都是 RQMainTabBarViewController。这是架构上小缺(特)陷(性)。因为RQMainTabBarViewController的子控制器是UITabBarController,所以需要递归UITabBarController的所有的子控制器
  221. if ([resultVC isKindOfClass:[TabBarController class]]) {
  222. TabBarController *mainVc = (TabBarController *)resultVC;
  223. resultVC = [self _topViewController:mainVc.tabBarController];
  224. }
  225. while (resultVC.presentedViewController) {
  226. resultVC = [self _topViewController:resultVC.presentedViewController];
  227. }
  228. return resultVC;
  229. }
  230. - (UIViewController *)_topViewController:(UIViewController *)vc {
  231. if ([vc isKindOfClass:[UINavigationController class]]) {
  232. return [self _topViewController:[(UINavigationController *)vc topViewController]];
  233. } else if ([vc isKindOfClass:[UITabBarController class]]) {
  234. return [self _topViewController:[(UITabBarController *)vc selectedViewController]];
  235. } else {
  236. return vc;
  237. }
  238. }
  239. - (NSData *)compressQualityWithImage:(UIImage *)image MaxLength:(NSInteger)maxLength {
  240. CGFloat compression = 1;
  241. NSData *data = UIImageJPEGRepresentation(image, compression);
  242. if (data.length < maxLength) return data;
  243. CGFloat max = 1;
  244. CGFloat min = 0;
  245. NSData *lastData;
  246. for (int i = 0; i < 99; ++i) {
  247. compression = (max + min) / 2;
  248. data = UIImageJPEGRepresentation(image, compression);
  249. if (data.length == lastData.length) {
  250. return data;
  251. }else {
  252. lastData = data;
  253. }
  254. if (data.length < maxLength * 0.9) {
  255. min = compression;
  256. } else if (data.length > maxLength) {
  257. max = compression;
  258. } else {
  259. break;
  260. }
  261. }
  262. return data;
  263. }
  264. /**
  265. * 展示大图
  266. *
  267. * @author ZhangRong
  268. * @date 2020-06-16 14:30:55
  269. *
  270. * @param dataSource 图片数组(Url数组)
  271. * @param currentIndex 当前标签
  272. * @param isCanSave 是否保存图片
  273. */
  274. - (void)showPhotoBrowserWithDataSource:(NSArray *)dataSource currentIndex:(NSInteger)currentIndex isCanSave:(BOOL)isCanSave {
  275. if (dataSource.count == 0) {
  276. ShowMsg(@"暂无图片");
  277. return;
  278. }
  279. NSMutableArray *photos = [NSMutableArray new];
  280. self.dataSource = dataSource;
  281. self.isCanSave = isCanSave;
  282. [self.dataSource enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  283. if ([obj isKindOfClass:[NSDictionary class]]) {
  284. GKPhoto *photo = [GKPhoto new];
  285. photo.url = [NSURL URLWithString:obj[@"IMGPATH"]];
  286. [photos addObject:photo];
  287. }else if ([obj isKindOfClass:[NSString class]]) {
  288. // 替换为中等尺寸图片
  289. if ([obj rangeOfString:@"thumbnail"].location != NSNotFound) {
  290. //这个要了没用噢 除非以后我们有清晰的图
  291. obj= [obj stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"];
  292. }
  293. NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  294. NSString *str = [obj stringByTrimmingCharactersInSet:whitespace];
  295. if (str && ![str hasPrefix:@"http"]){
  296. str = [imgPreFix stringByAppendingString:[obj stringByTrimmingCharactersInSet:whitespace]];
  297. }
  298. GKPhoto *photo = [GKPhoto new];
  299. photo.url = [NSURL URLWithString:str];
  300. [photos addObject:photo];
  301. }else if ([obj isKindOfClass:[UIImage class]]) {
  302. GKPhoto *photo = [GKPhoto new];
  303. photo.image = obj;
  304. [photos addObject:photo];
  305. }
  306. }];
  307. self.pageControl = [[UIPageControl alloc] init];
  308. self.pageControl.numberOfPages = photos.count;
  309. self.pageControl.currentPage = currentIndex;
  310. self.pageControl.hidesForSinglePage = YES;
  311. self.browser = [GKPhotoBrowser photoBrowserWithPhotos:photos currentIndex:currentIndex];
  312. _browser.delegate = self;
  313. _browser.showStyle = GKPhotoBrowserShowStyleNone; // 缩放显示
  314. _browser.hideStyle = GKPhotoBrowserHideStyleZoomScale; // 缩放隐藏
  315. _browser.loadStyle = GKPhotoBrowserLoadStyleDeterminate; // 不明确的加载方式带阴影
  316. _browser.maxZoomScale = 20.0f;
  317. _browser.doubleZoomScale = 2.0f;
  318. [_browser setupCoverViews:@[self.pageControl] layoutBlock:^(GKPhotoBrowser *photoBrowser, CGRect superFrame) {
  319. CGFloat pointY = 0;
  320. if (photoBrowser.isLandspace) {
  321. pointY = superFrame.size.height - 20;
  322. }else {
  323. pointY = superFrame.size.height - 10 - kSafeAreaBottomHeight;
  324. }
  325. self.pageControl.center = CGPointMake(superFrame.size.width * 0.5, pointY);
  326. }];
  327. [_browser showFromVC:[RQ_SHARE_FUNCTION topViewController]];
  328. }
  329. #pragma mark - GKPhotoBrowserDelegate
  330. - (void)photoBrowser:(GKPhotoBrowser *)browser didChangedIndex:(NSInteger)index {
  331. self.pageControl.currentPage = index;
  332. }
  333. - (void)photoBrowser:(GKPhotoBrowser *)browser longPressWithIndex:(NSInteger)index {
  334. if (!_isCanSave) return;
  335. [RQ_SHARE_FUNCTION showAlertWithTitle:nil message:nil alertControllerStyle:UIAlertControllerStyleActionSheet cancelButtonTitle:@"取消" otherButtonTitles:@[@"保存图片"] otherButtonStyles:nil completion:^(NSUInteger selectedOtherButtonIndex) {
  336. if (selectedOtherButtonIndex == 0) {
  337. GKPhoto *photo = self.browser.photos[self.browser.currentIndex];
  338. NSData *imageData = nil;
  339. if ([photo.image isKindOfClass:[SDAnimatedImage class]]) {
  340. imageData = [(SDAnimatedImage *)photo.image animatedImageData];
  341. }else {
  342. imageData = [photo.image sd_imageData];
  343. }
  344. if (!imageData) return;
  345. [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
  346. if (@available(iOS 9, *)) {
  347. PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];
  348. [request addResourceWithType:PHAssetResourceTypePhoto data:imageData options:nil];
  349. request.creationDate = [NSDate date];
  350. }
  351. } completionHandler:^(BOOL success, NSError *error) {
  352. dispatch_async(dispatch_get_main_queue(), ^{
  353. if (success) {
  354. NSLog(@"保存照片成功");
  355. ShowMsg(@"图片保存成功");
  356. } else if (error) {
  357. ShowMsg(@"保存保存失败");
  358. NSLog(@"保存照片出错:%@",error.localizedDescription);
  359. }
  360. });
  361. }];
  362. }
  363. }];
  364. }
  365. /**
  366. * Mob隐私判断
  367. *
  368. * @author ZhangRong
  369. * @date 2020-06-16 14:30:55
  370. */
  371. - (void)checkMobPolicyOnResult:(void (^_Nullable)(BOOL success))handler {
  372. //获取隐私协议
  373. [MobSDK getPrivacyPolicy:@"1" language:@"zh" compeletion:^(NSDictionary * _Nullable data, NSError * _Nullable error) {
  374. NSString *url = data[@"content"];
  375. if(url) {
  376. handler(YES);
  377. [SMSDemoPolicyManager show:url compeletion:^(BOOL accept) {
  378. //是否接受隐私协议
  379. [MobSDK uploadPrivacyPermissionStatus:accept onResult:^(BOOL success) {
  380. NSLog(@"%@",success? @"MobSDK隐私授权成功" : @"MobSDK隐私授权失败");
  381. }];
  382. }];
  383. }
  384. }];
  385. }
  386. @end