RQShareFunction.m 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  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 "GKPhotoBrowser.h"
  11. //#import <MOBFoundation/MobSDK+Privacy.h>
  12. #import "SMSDemoPolicyManager.h"
  13. #import "SLShotViewController.h"
  14. #import "RQCustomWebViewViewController.h"
  15. static RQShareFunction *_instance = nil;
  16. static dispatch_once_t onceToken;
  17. @interface RQShareFunction ()<GKPhotoBrowserDelegate, IDMPhotoBrowserDelegate>
  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. - (void)setCurrentUserInterfaceStyle:(UIUserInterfaceStyle)currentUserInterfaceStyle {
  64. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  65. [userDefault setInteger:currentUserInterfaceStyle forKey:@"currentUserInterfaceStyle"];
  66. [userDefault synchronize];
  67. }
  68. - (UIUserInterfaceStyle)currentUserInterfaceStyle{
  69. NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
  70. if (@available(iOS 12.0, *)) {
  71. UIUserInterfaceStyle style = (UIUserInterfaceStyle)[userDefault integerForKey:@"currentUserInterfaceStyle"]? : UIUserInterfaceStyleUnspecified;
  72. return style;
  73. } else {
  74. return 0;
  75. }
  76. }
  77. // 理论计时不开启开启人脸比对模式 (不开启地市:台州-3310)
  78. - (NSArray *)theoryOfTimingNoOpenFaceToFaceArr {
  79. return @[@"3310"];
  80. }
  81. // 个人中心功能模块类型一(预约相关,模拟相关,资讯相关)(开启地市:福州-3501,厦门-3502,莆田-3503,泉州-3505)
  82. - (NSArray *)personalTypeOneCityCodeArr {
  83. return @[];
  84. }
  85. // 个人中心功能模块类型一(预约相关,资讯相关)(开启地市:温州-3303)
  86. - (NSArray *)personalTypeTwoCityCodeArr {
  87. return @[];
  88. }
  89. // 学车计时功能模块类型一(理论计时,实操计时,模拟计时,我的学时)(开启地市:福州-3501,厦门-3502,泉州-3505,温州-3303)
  90. - (NSArray *)timingTypeOneCityCodeArr {
  91. return @[];
  92. }
  93. // 学车计时功能模块类型二(理论计时,我的学时)(开启地市:莆田-3503)
  94. - (NSArray *)timingTypeTwoCityCodeArr {
  95. return @[];
  96. }
  97. // 理论计时类型一 (在科目二,科目三可以进行科目四的理论计时) (开启地市:福州-3501,莆田-3503,泉州-3505)
  98. - (NSArray *)theoryOfTimingTypeOneCityCodeArr {
  99. return @[];
  100. }
  101. // 理论计时类型二地市编号:null (在科目二可以进行科目四的理论计时)(开启地市:)
  102. - (NSArray *)theoryOfTimingTypeTwoCityCodeArr {
  103. return @[];
  104. }
  105. // 理论计时类型三 (在科目三可以进行科目四的理论计时)(开启地市:厦门-3502)
  106. - (NSArray *)theoryOfTimingTypeThreeCityCodeArr {
  107. return @[];
  108. }
  109. // 是否开启广告 默认0 不开通 1 开通
  110. - (BOOL)APP_AD {
  111. id object = [RQ_SHARE_FUNCTION getObjectWithKey:@"APP_AD"];
  112. BOOL appAd = [object boolValue];
  113. // return [RQ_SHARE_FUNCTION checkProxySetting]? NO : (object? appAd : YES);
  114. return object? appAd : YES;
  115. }
  116. //关闭插屏的时间(秒)
  117. - (NSInteger)APP_CLOSE {
  118. id object = [RQ_SHARE_FUNCTION getObjectWithKey:@"APP_CLOSE"];
  119. NSInteger appClose = [object integerValue];
  120. return appClose;
  121. }
  122. - (NSInteger)APP_AD_CYCLE {
  123. id object = [RQ_SHARE_FUNCTION getObjectWithKey:@"APP_AD_CYCLE"];
  124. NSInteger appAdCycle = [object integerValue];
  125. return appAdCycle;
  126. }
  127. //开屏广告展示概率
  128. - (NSInteger)APP_KP {
  129. id object = [RQ_SHARE_FUNCTION getObjectWithKey:@"APP_KP"];
  130. NSInteger appKp = [object integerValue];
  131. return appKp;
  132. }
  133. - (NSInteger)SP_COMPLAINT_DQBH {
  134. id object = [RQ_SHARE_FUNCTION getObjectWithKey:@"SP_COMPLAINT_DQBH"];
  135. NSInteger SP_COMPLAINT_DQBH = [object integerValue];
  136. return SP_COMPLAINT_DQBH;
  137. }
  138. // 是否开启社区 1:开启 0:关闭
  139. - (NSInteger)APP_OPEN_COMMUNITY {
  140. id object = [RQ_SHARE_FUNCTION getObjectWithKey:@"APP_OPEN_COMMUNITY"];
  141. NSInteger appOpenCommunity = [object integerValue];
  142. return appOpenCommunity;
  143. }
  144. //审核开关
  145. - (NSInteger)APP_SWITCH {
  146. id object = [RQ_SHARE_FUNCTION getObjectWithKey:@"APP_SWITCH"];
  147. NSInteger appSwitch = [object integerValue];
  148. return appSwitch;
  149. }
  150. - (CGFloat)RQADViewHeight {
  151. return RQ_SCREEN_WIDTH / 3.f;
  152. }
  153. - (void)setAPP_AD:(BOOL)APP_AD {
  154. [RQ_SHARE_FUNCTION saveObjectWithObject:[NSNumber numberWithBool:APP_AD] ForKey:@"APP_AD"];
  155. }
  156. - (void)setAPP_CLOSE:(NSInteger)APP_CLOSE {
  157. [RQ_SHARE_FUNCTION saveObjectWithObject:[NSNumber numberWithInteger:APP_CLOSE] ForKey:@"APP_CLOSE"];
  158. }
  159. - (void)setAPP_AD_CYCLE:(NSInteger)APP_AD_CYCLE {
  160. [RQ_SHARE_FUNCTION saveObjectWithObject:[NSNumber numberWithInteger:APP_AD_CYCLE] ForKey:@"APP_AD_CYCLE"];
  161. }
  162. - (void)setSP_COMPLAINT_DQBH:(NSInteger)SP_COMPLAINT_DQBH {
  163. [RQ_SHARE_FUNCTION saveObjectWithObject:[NSNumber numberWithInteger:SP_COMPLAINT_DQBH] ForKey:@"SP_COMPLAINT_DQBH"];
  164. }
  165. - (void)setAPP_OPEN_COMMUNITY:(NSInteger)APP_OPEN_COMMUNITY {
  166. [RQ_SHARE_FUNCTION saveObjectWithObject:[NSNumber numberWithInteger:APP_OPEN_COMMUNITY] ForKey:@"APP_OPEN_COMMUNITY"];
  167. }
  168. - (void)setAPP_KP:(NSInteger)APP_KP {
  169. [RQ_SHARE_FUNCTION saveObjectWithObject:[NSNumber numberWithInteger:APP_KP] ForKey:@"APP_KP"];
  170. }
  171. - (void)setAPP_SWITCH:(NSInteger)APP_SWITCH {
  172. [RQ_SHARE_FUNCTION saveObjectWithObject:[NSNumber numberWithInteger:APP_SWITCH] ForKey:@"APP_SWITCH"];
  173. }
  174. // 时间转换为时间戳,精确到微秒
  175. - (NSInteger)getTimeStampWithDate:(NSDate *)date {
  176. return [[NSNumber numberWithDouble:[date timeIntervalSince1970]] integerValue];
  177. }
  178. // 时间戳转换为时间
  179. - (NSDate *)getDateWithTimeStamp:(NSInteger)timeStamp {
  180. return [NSDate dateWithTimeIntervalSince1970:timeStamp];
  181. }
  182. // 一个时间戳与当前时间的间隔(s)
  183. - (NSInteger)getIntervalsWithTimeStamp:(NSInteger)timeStamp {
  184. return [[NSDate date] timeIntervalSinceDate:[self getDateWithTimeStamp:timeStamp]];
  185. }
  186. // 根据时间和formatter获取时间字符串
  187. - (NSString *)getTimeStrWithDate:(NSDate *)date formatter:(NSString *)formatterStr {
  188. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  189. formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
  190. // NSTimeZone *zone = [NSTimeZone systemTimeZone];
  191. // NSInteger interval = [zone secondsFromGMTForDate: date];
  192. // NSDate *localeDate = [date dateByAddingTimeInterval: interval];
  193. [formatter setDateFormat:formatterStr];
  194. NSString *dateStr = [formatter stringFromDate:date];
  195. return dateStr;
  196. }
  197. // 根据时间字符串和formatter获取时间戳(s)
  198. - (NSInteger)getTimeStampWithTimeStr:(NSString *)timeStr formatter:(NSString *)formatterStr {
  199. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  200. [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
  201. [formatter setDateFormat:formatterStr];
  202. NSDate *date = [formatter dateFromString:timeStr];
  203. NSInteger timeStamp = [self getTimeStampWithDate:date];
  204. return timeStamp * 1000;
  205. }
  206. // 一个时间戳与另一个时间戳的间隔(s)
  207. - (NSInteger)getIntervalsWithTimeStamp:(NSInteger)timeStamp anotherTimeStamp:(NSInteger)anotherTimeStamp {
  208. return [[self getDateWithTimeStamp:timeStamp] timeIntervalSinceDate:[self getDateWithTimeStamp:anotherTimeStamp]] * 0.001 * 0.001;
  209. }
  210. - (NSInteger)getTimeStampWithHour:(NSInteger)hour andMinute:(NSInteger)minute andDate:(NSDate *)date {
  211. NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
  212. NSTimeZone *timeZone = [[NSTimeZone alloc] initWithName:@"Asia/Shanghai"];
  213. [greCalendar setTimeZone: timeZone];
  214. NSDateComponents *dateComponents = [greCalendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
  215. // 定义一个NSDateComponents对象,设置一个时间点
  216. NSDateComponents *dateComponentsForDate = [[NSDateComponents alloc] init];
  217. [dateComponentsForDate setDay:dateComponents.day];
  218. [dateComponentsForDate setMonth:dateComponents.month];
  219. [dateComponentsForDate setYear:dateComponents.year];
  220. [dateComponentsForDate setHour:hour];
  221. [dateComponentsForDate setMinute:minute];
  222. NSDate *dateFromDateComponentsForDate = [greCalendar dateFromComponents:dateComponentsForDate];
  223. return [dateFromDateComponentsForDate timeIntervalSince1970];
  224. }
  225. #pragma mark - GetPhotos
  226. - (void)getPhotosWithGetPhotosWay:(GetPhotosWay)getPhotosWay size:(CGSize)size maxLength:(NSUInteger)maxLength maxImagesCount:(NSUInteger)maxImagesCount isCheckBody:(BOOL)isCheckBody photosBlock:(PhotosBlock)photosBlock {
  227. if (getPhotosWay == GetPhotosWay_Camera) {
  228. [RQPhotoManager fetchPhotosFromCamera:RQ_SHARE_FUNCTION.topViewController allowCrop:NO completion:^(UIImage * _Nonnull image, id _Nonnull asset) {
  229. if (image) {
  230. NSMutableArray *imagesArr = [NSMutableArray arrayWithObject:image];
  231. if (photosBlock) {
  232. photosBlock(imagesArr);
  233. }
  234. } else {
  235. if (photosBlock) {
  236. photosBlock(@[]);
  237. }
  238. }
  239. }];
  240. return;
  241. if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
  242. AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  243. if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied) {
  244. [RQ_SHARE_FUNCTION showAlertWithTitle:@"温馨提示" message:@"请在iPhone的“设置”-“隐私”-“相机”功能中,找到“极速驾培”打开相机访问权限" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"取消" otherButtonTitles:@[@"确定"] otherButtonStyles:nil showInWindow:NO completion:^(NSUInteger selectedOtherButtonIndex) {
  245. if (selectedOtherButtonIndex == 0) {
  246. NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
  247. if ([[UIApplication sharedApplication] canOpenURL:url]) {
  248. [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
  249. }
  250. }
  251. }];
  252. if (photosBlock) {
  253. photosBlock(@[]);
  254. }
  255. return;
  256. } else if (authStatus == AVAuthorizationStatusNotDetermined) {
  257. [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
  258. if (granted) {
  259. SLShotViewController *vc = [[SLShotViewController alloc] init];
  260. vc.isCheckBody = isCheckBody;
  261. [vc initTakePhotoBlock:^(UIImage * _Nullable image) {
  262. if (image) {
  263. NSMutableArray *imagesArr = [NSMutableArray arrayWithObject:image];
  264. if (photosBlock) {
  265. photosBlock(imagesArr);
  266. }
  267. } else {
  268. if (photosBlock) {
  269. photosBlock(@[]);
  270. }
  271. }
  272. }];
  273. dispatch_async(dispatch_get_main_queue(), ^{
  274. vc.modalPresentationStyle = UIModalPresentationFullScreen;
  275. [[RQ_SHARE_FUNCTION topViewController] presentViewController:vc
  276. animated:NO
  277. completion:nil];
  278. });
  279. } else {
  280. if (photosBlock) {
  281. photosBlock(@[]);
  282. }
  283. }
  284. }];
  285. return;
  286. } else if (authStatus == AVAuthorizationStatusAuthorized) {
  287. SLShotViewController *vc = [[SLShotViewController alloc] init];
  288. vc.isCheckBody = isCheckBody;
  289. [vc initTakePhotoBlock:^(UIImage * _Nullable image) {
  290. if (image) {
  291. NSMutableArray *imagesArr = [NSMutableArray arrayWithObject:image];
  292. if (photosBlock) {
  293. photosBlock(imagesArr);
  294. }
  295. } else {
  296. if (photosBlock) {
  297. photosBlock(@[]);
  298. }
  299. }
  300. }];
  301. dispatch_async(dispatch_get_main_queue(), ^{
  302. vc.modalPresentationStyle = UIModalPresentationFullScreen;
  303. [[RQ_SHARE_FUNCTION topViewController] presentViewController:vc
  304. animated:NO
  305. completion:nil];
  306. });
  307. } else {
  308. if (photosBlock) {
  309. photosBlock(@[]);
  310. }
  311. return;
  312. }
  313. } else {
  314. NSLog(@"相机调用失败");
  315. if (photosBlock) {
  316. photosBlock(@[]);
  317. }
  318. }
  319. }else if (getPhotosWay == GetPhotosWay_Album) {
  320. if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum]) {
  321. TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:maxImagesCount ? maxImagesCount : 1 delegate:nil];
  322. imagePickerVc.naviBgColor = RQ_MAIN_COLOR;
  323. imagePickerVc.iconThemeColor = RQ_MAIN_COLOR;
  324. imagePickerVc.allowPickingVideo = NO;
  325. [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isStop) {
  326. NSMutableArray *imagesDataStrArr = [NSMutableArray array];
  327. @synchronized (imagesDataStrArr) {
  328. for (UIImage *image in photos) {
  329. NSData *data;
  330. if (CGSizeEqualToSize(size, CGSizeZero)) {
  331. data = [UIImage resetSizeOfImageData:image maxSize:maxLength];
  332. }else {
  333. data = [UIImage resetSizeOfImageData:[image scaledAndCutToSize:size] maxSize:maxLength];
  334. }
  335. NSString *imgString = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
  336. [imagesDataStrArr addObject:imgString];
  337. }
  338. }
  339. if (photosBlock) {
  340. photosBlock(photos);
  341. }
  342. }];
  343. dispatch_async(dispatch_get_main_queue(), ^{
  344. imagePickerVc.modalPresentationStyle = UIModalPresentationFullScreen;
  345. [[RQ_SHARE_FUNCTION topViewController] presentViewController:imagePickerVc animated:YES completion:nil];
  346. });
  347. }else{
  348. NSLog(@"相册调用失败");
  349. }
  350. }
  351. }
  352. #pragma mark - RQAlertViewController
  353. - (void)showAlertAtViewController:(nonnull UIViewController *)viewController
  354. WithTitle:(nullable NSString *)title
  355. message:(nullable NSString *)message
  356. alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle
  357. cancelButtonTitle:(nullable NSString *)cancelButtonTitle
  358. otherButtonTitles:(nullable NSArray *)otherButtonTitles
  359. otherButtonStyles:(nullable NSDictionary *)otherButtonStyles
  360. preferredActionTitle:(nullable NSString *)preferredActionTitle
  361. showInWindow:(BOOL)showInWindow
  362. completion:(nullable RQAlertViewCompletion)completion {
  363. @weakify(self)
  364. __block UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:alertControllerStyle];
  365. void (^alertActionHandler) (UIAlertAction *) = [^(UIAlertAction *action) {
  366. if (completion) {
  367. if (action.style == UIAlertActionStyleCancel) {
  368. completion(NSNotFound);
  369. }else {
  370. NSUInteger index = [alertController.actions indexOfObject:action];
  371. completion(cancelButtonTitle? index - 1 : index);
  372. }
  373. }
  374. alertController = nil;
  375. } copy];
  376. if (cancelButtonTitle) {
  377. UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:alertActionHandler];
  378. if (@available(iOS 9.0, *)) {
  379. [cancleAction setValue:RQ_MAIN_COLOR forKey:@"_titleTextColor"];
  380. } else {
  381. // Fallback on earlier versions
  382. }
  383. [alertController addAction:cancleAction];
  384. }
  385. if (otherButtonTitles.count == 0) {
  386. dispatch_async(dispatch_get_main_queue(), ^{
  387. @strongify(self)
  388. if (showInWindow) {
  389. [[self getKeyWindow].rootViewController presentViewController:alertController animated:YES completion:nil];
  390. } else {
  391. [[RQ_SHARE_FUNCTION topViewController] presentViewController:alertController animated:YES completion:nil];
  392. }
  393. });
  394. }else {
  395. [otherButtonTitles.rac_sequence.signal subscribeNext:^(NSString * buttonTitle) {
  396. NSNumber *actionStyleNumber = [otherButtonStyles valueForKey:buttonTitle];
  397. UIAlertActionStyle actionStyle = UIAlertActionStyleDefault;
  398. if (actionStyleNumber) {
  399. actionStyle = [actionStyleNumber integerValue];
  400. }
  401. UIAlertAction *action = [UIAlertAction actionWithTitle:buttonTitle
  402. style:actionStyle
  403. handler:alertActionHandler];
  404. if (@available(iOS 9.0, *)) {
  405. [action setValue:RQ_MAIN_COLOR forKey:@"_titleTextColor"];
  406. } else {
  407. // Fallback on earlier versions
  408. }
  409. [alertController addAction:action];
  410. ///Support for iOS9 add preferredAction for highlights the text of that action
  411. if ([alertController respondsToSelector:@selector(setPreferredAction:)]) {
  412. if ([preferredActionTitle isEqualToString:buttonTitle]) {
  413. if (@available(iOS 9.0, *)) {
  414. [alertController setPreferredAction:action];
  415. } else {
  416. // Fallback on earlier versions
  417. }
  418. }
  419. }
  420. } completed:^{
  421. dispatch_async(dispatch_get_main_queue(), ^{
  422. @strongify(self)
  423. if (showInWindow) {
  424. [[self getKeyWindow].rootViewController presentViewController:alertController animated:YES completion:nil];
  425. } else {
  426. [[RQ_SHARE_FUNCTION topViewController] presentViewController:alertController animated:YES completion:nil];
  427. }
  428. });
  429. }];
  430. }
  431. }
  432. - (void)showAlertWithTitle:(nullable NSString *)title
  433. message:(nullable NSString *)message
  434. alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle
  435. cancelButtonTitle:(nullable NSString *)cancelButtonTitle
  436. otherButtonTitles:(nullable NSArray *)otherButtonTitles
  437. otherButtonStyles:(nullable NSDictionary *)otherButtonStyles
  438. preferredActionTitle:(nullable NSString *)preferredActionTitle
  439. showInWindow:(BOOL)showInWindow
  440. completion:(nullable RQAlertViewCompletion)completion{
  441. [self showAlertAtViewController:[RQ_SHARE_FUNCTION topViewController]
  442. WithTitle:title
  443. message:message
  444. alertControllerStyle:alertControllerStyle
  445. cancelButtonTitle:cancelButtonTitle
  446. otherButtonTitles:otherButtonTitles
  447. otherButtonStyles:otherButtonStyles
  448. preferredActionTitle:preferredActionTitle
  449. showInWindow:showInWindow
  450. completion:completion];
  451. }
  452. - (void)showAlertWithTitle:(nullable NSString *)title
  453. message:(nullable NSString *)message
  454. alertControllerStyle:(UIAlertControllerStyle)alertControllerStyle
  455. cancelButtonTitle:(nullable NSString *)cancelButtonTitle
  456. otherButtonTitles:(nullable NSArray *)otherButtonTitles
  457. otherButtonStyles:(nullable NSDictionary *)otherButtonStyles
  458. showInWindow:(BOOL)showInWindow
  459. completion:(nullable RQAlertViewCompletion)completion {
  460. [self showAlertAtViewController:[RQ_SHARE_FUNCTION topViewController]
  461. WithTitle:title
  462. message:message
  463. alertControllerStyle:alertControllerStyle
  464. cancelButtonTitle:cancelButtonTitle
  465. otherButtonTitles:otherButtonTitles
  466. otherButtonStyles:otherButtonStyles
  467. preferredActionTitle:nil
  468. showInWindow:showInWindow
  469. completion:completion];
  470. }
  471. - (void)showAlertWithMessage:(nullable NSString *)message
  472. completion:(nullable RQAlertViewCompletion)completion {
  473. [self showAlertAtViewController:[RQ_SHARE_FUNCTION topViewController]
  474. WithTitle:@""
  475. message:message
  476. alertControllerStyle:UIAlertControllerStyleAlert
  477. cancelButtonTitle:@"确定"
  478. otherButtonTitles:nil
  479. otherButtonStyles:nil
  480. preferredActionTitle:nil
  481. showInWindow:NO
  482. completion:completion];
  483. }
  484. #pragma mark - Custom Way
  485. - (UIViewController *)topViewController {
  486. return [RQ_SHARE_FUNCTION topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
  487. }
  488. - (UIViewController *)topViewController:(UIViewController*)rootViewController {
  489. if (rootViewController.presentedViewController == nil ||
  490. rootViewController.presentedViewController.beingDismissed) {
  491. return rootViewController;
  492. }
  493. if ([rootViewController.presentedViewController isMemberOfClass:[UINavigationController class]]) {
  494. UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
  495. UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
  496. return [RQ_SHARE_FUNCTION topViewController:lastViewController];
  497. }
  498. UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
  499. return [RQ_SHARE_FUNCTION topViewController:presentedViewController];
  500. }
  501. - (UIViewController *)currentViewController {
  502. UIViewController *resultVC;
  503. resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]];
  504. /// RQ Fixed : 这里必须要判断一下,否则取出来永远都是 RQMainTabBarViewController。这是架构上小缺(特)陷(性)。因为RQMainTabBarViewController的子控制器是UITabBarController,所以需要递归UITabBarController的所有的子控制器
  505. while (resultVC.presentedViewController) {
  506. resultVC = [self _topViewController:resultVC.presentedViewController];
  507. }
  508. return resultVC;
  509. }
  510. - (UIViewController *)_topViewController:(UIViewController *)vc {
  511. if ([vc isKindOfClass:[UINavigationController class]]) {
  512. return [self _topViewController:[(UINavigationController *)vc topViewController]];
  513. } else if ([vc isKindOfClass:[UITabBarController class]]) {
  514. return [self _topViewController:[(UITabBarController *)vc selectedViewController]];
  515. } else {
  516. return vc;
  517. }
  518. }
  519. //- (NSData *)compressQualityWithImage:(UIImage *)image MaxLength:(NSInteger)maxLength {
  520. // CGFloat compression = 1;
  521. // NSData *data = UIImageJPEGRepresentation(image, compression);
  522. // if (data.length < maxLength) {
  523. // return data;
  524. // }
  525. // CGFloat max = 1;
  526. // CGFloat min = 0;
  527. // NSData *lastData;
  528. // for (int i = 0; i < 99; ++i) {
  529. // compression = (max + min) / 2;
  530. // data = UIImageJPEGRepresentation(image, compression);
  531. // if (data.length == lastData.length) {
  532. // return data;
  533. // }else {
  534. // lastData = data;
  535. // }
  536. // if (data.length < maxLength * 0.9) {
  537. // min = compression;
  538. // } else if (data.length > maxLength) {
  539. // max = compression;
  540. // } else {
  541. // break;
  542. // }
  543. // }
  544. // return data;
  545. //}
  546. - (void)showGuidePicture {
  547. UIButton* btn = [[UIButton alloc] initWithFrame:kFrame];
  548. [myDelegate.window addSubview:btn];
  549. [btn setImage:[UIImage imageNamed:@"welGuide2.png"] forState:UIControlStateNormal];
  550. UIImageView* iv;
  551. iv = [[UIImageView alloc] initWithFrame:CGRectMake(3, 11, 70, 70)];
  552. [iv setImage:[UIImage imageNamed:@"welGuide1.png"]];
  553. [btn addSubview:iv];
  554. [btn addTarget:self action:@selector(removeBtn:) forControlEvents:UIControlEventTouchUpInside];
  555. }
  556. - (void)removeBtn:(UIButton *)btn {
  557. [btn removeFromSuperview];
  558. }
  559. #pragma mark - 检查版本更新
  560. - (void)checkVersion {
  561. /// 在当前页面有弹窗 以及在模拟计时页面 理论计时页面 模拟考试界面 不弹出更新提示
  562. NSArray *controllers = @[@"UIAlertController", @"ImitatePeriodVC", @"PeriodVC", @"NYTheoryTimeVC", @"NYGetjobTimeVC"];
  563. NSLog(@"string---Class-----%@",NSStringFromClass([RQ_SHARE_FUNCTION currentViewController].class));
  564. if (![Util connectedToNetWork]) {
  565. return;
  566. }
  567. NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
  568. NSString *localVersion = [infoDic objectForKey:@"CFBundleShortVersionString"];
  569. NSString *URL = @"http://itunes.apple.com/cn/lookup?id=1214200225";
  570. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URL] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
  571. [request setHTTPMethod:@"POST"];
  572. NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
  573. //这个导致部分手机网络不好时候出现闪退情况
  574. if (!data) {
  575. return;
  576. }
  577. //如果data等于nil的时候 再去解析 会发生崩溃
  578. NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
  579. if (!dic) {
  580. return;
  581. }
  582. NSArray *infoArray = [dic objectForKey:@"results"];
  583. if ([infoArray count]) {
  584. NSDictionary *releaseInfo = [infoArray objectAtIndex:0];
  585. NSString *netVersion = [releaseInfo objectForKey:@"version"];
  586. //NSLog(@"AppStore-->%@,手机上-->%@",lastVersion,currentVersion);
  587. // 线上版本号
  588. NSInteger netInt = [[netVersion stringByReplacingOccurrencesOfString:@"." withString:@""] integerValue];
  589. // 本地版本号
  590. NSInteger localInt = [[localVersion stringByReplacingOccurrencesOfString:@"." withString:@""] integerValue];
  591. if (netInt > localInt) {
  592. NSLog(@"更新");
  593. if (RQ_USER_MANAGER.isLogin) {
  594. [[[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  595. [subscriber sendNext:@1];
  596. [subscriber sendCompleted];
  597. return [RACDisposable disposableWithBlock:^{
  598. }];
  599. }] delay:2] subscribeCompleted:^{
  600. /// 检查版本更新
  601. if (RQ_AD_MANAGER.splashIsShow) {
  602. [[[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
  603. [subscriber sendNext:@1];
  604. [subscriber sendCompleted];
  605. return [RACDisposable disposableWithBlock:^{
  606. }];
  607. }] delay:5] subscribeCompleted:^{
  608. [RQ_SHARE_FUNCTION showAlertWithTitle:@"更新提示" message:[NSString stringWithFormat:@"本地版本为%@\nApp Store已发布%@\n请及时更新!",localVersion,netVersion] alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:(RQ_USER_MANAGER.qzgx == 1)? nil : @"取消" otherButtonTitles:@[@"确定"] otherButtonStyles:nil showInWindow:YES completion:^(NSUInteger selectedOtherButtonIndex) {
  609. if (selectedOtherButtonIndex == 0) {
  610. NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.apple.com/cn/app/ji-su-jia-pei-kua-jia-xiao-ban/id1214200225?l=en&mt=8"];
  611. [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
  612. }
  613. }];
  614. }];
  615. } else {
  616. [RQ_SHARE_FUNCTION showAlertWithTitle:@"更新提示" message:[NSString stringWithFormat:@"本地版本为%@\nApp Store已发布%@\n请及时更新!",localVersion,netVersion] alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:[controllers containsObject:NSStringFromClass([RQ_SHARE_FUNCTION currentViewController].class)]? @"取消" : nil otherButtonTitles:@[@"确定"] otherButtonStyles:nil showInWindow:YES completion:^(NSUInteger selectedOtherButtonIndex) {
  617. if (selectedOtherButtonIndex == 0) {
  618. NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.apple.com/cn/app/ji-su-jia-pei-kua-jia-xiao-ban/id1214200225?l=en&mt=8"];
  619. [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
  620. }
  621. }];
  622. }
  623. }];
  624. } else {
  625. return;
  626. }
  627. }else{
  628. //已是最新版
  629. NSLog(@"不更");
  630. }
  631. }
  632. }];
  633. [task resume];
  634. }
  635. /**
  636. * 展示大图
  637. *
  638. * @author ZhangRong
  639. * @date 2020-06-16 14:30:55
  640. *
  641. * @param dataSource 图片数组(Url数组)
  642. * @param currentIndex 当前标签
  643. * @param isCanSave 是否保存图片
  644. */
  645. - (void)showPhotoBrowserWithDataSource:(NSArray *)dataSource currentIndex:(NSInteger)currentIndex isCanSave:(BOOL)isCanSave {
  646. if (dataSource.count == 0) {
  647. ShowMsg(@"暂无图片");
  648. return;
  649. }
  650. NSMutableArray *photos = [NSMutableArray new];
  651. self.dataSource = dataSource;
  652. self.isCanSave = isCanSave;
  653. [self.dataSource enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  654. if ([obj isKindOfClass:[NSDictionary class]]) {
  655. // GKPhoto *photo = [GKPhoto new];
  656. // photo.url = [NSURL URLWithString:obj[@"IMGPATH"]];
  657. // [photos addObject:photo];
  658. IDMPhoto *photo = [IDMPhoto photoWithFilePath:obj[@"IMGPATH"]];
  659. [photos addObject:photo];
  660. }else if ([obj isKindOfClass:[NSString class]]) {
  661. // // 替换为中等尺寸图片
  662. // if ([obj rangeOfString:@"thumbnail"].location != NSNotFound) {
  663. // //这个要了没用噢 除非以后我们有清晰的图
  664. // obj= [obj stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"];
  665. // }
  666. // NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  667. // NSString *str = [obj stringByTrimmingCharactersInSet:whitespace];
  668. // if (str && ![str hasPrefix:@"http"]){
  669. // str = [imgPreFix stringByAppendingString:[obj stringByTrimmingCharactersInSet:whitespace]];
  670. // }
  671. // GKPhoto *photo = [GKPhoto new];
  672. // photo.url = [NSURL URLWithString:str];
  673. // [photos addObject:photo];
  674. IDMPhoto *photo = [IDMPhoto photoWithURL:[NSURL URLWithString:obj]];
  675. [photos addObject:photo];
  676. }else if ([obj isKindOfClass:[UIImage class]]) {
  677. // GKPhoto *photo = [GKPhoto new];
  678. // photo.image = obj;
  679. // [photos addObject:photo];
  680. IDMPhoto *photo = [IDMPhoto photoWithImage:obj];
  681. [photos addObject:photo];
  682. }
  683. }];
  684. [RQPhotoManager showPhotoBrowser:[RQ_SHARE_FUNCTION topViewController] photos:photos initialPageIndex:currentIndex delegate:self];
  685. // self.pageControl = [[UIPageControl alloc] init];
  686. // self.pageControl.numberOfPages = photos.count;
  687. // self.pageControl.currentPage = currentIndex;
  688. // self.pageControl.hidesForSinglePage = YES;
  689. //
  690. // self.browser = [GKPhotoBrowser photoBrowserWithPhotos:photos currentIndex:currentIndex];
  691. // _browser.delegate = self;
  692. // _browser.showStyle = GKPhotoBrowserShowStyleNone; // 缩放显示
  693. // _browser.hideStyle = GKPhotoBrowserHideStyleZoomScale; // 缩放隐藏
  694. // _browser.loadStyle = GKPhotoBrowserLoadStyleDeterminate; // 不明确的加载方式带阴影
  695. // _browser.maxZoomScale = 20.0f;
  696. // _browser.doubleZoomScale = 2.0f;
  697. // [_browser setupCoverViews:@[self.pageControl] layoutBlock:^(GKPhotoBrowser *photoBrowser, CGRect superFrame) {
  698. // CGFloat pointY = 0;
  699. // if (photoBrowser.isLandscape) {
  700. // pointY = superFrame.size.height - 20;
  701. // }else {
  702. // pointY = superFrame.size.height - 10 - kSafeAreaBottomHeight;
  703. // }
  704. //
  705. // self.pageControl.center = CGPointMake(superFrame.size.width * 0.5, pointY);
  706. // }];
  707. // [_browser showFromVC:[RQ_SHARE_FUNCTION topViewController]];
  708. }
  709. #pragma mark - GKPhotoBrowserDelegate
  710. - (void)photoBrowser:(GKPhotoBrowser *)browser didChangedIndex:(NSInteger)index {
  711. self.pageControl.currentPage = index;
  712. }
  713. - (void)photoBrowser:(GKPhotoBrowser *)browser longPressWithIndex:(NSInteger)index {
  714. if (!_isCanSave) return;
  715. [RQ_SHARE_FUNCTION showAlertWithTitle:nil message:nil alertControllerStyle:UIAlertControllerStyleActionSheet cancelButtonTitle:@"取消" otherButtonTitles:@[@"保存图片"] otherButtonStyles:nil showInWindow:NO completion:^(NSUInteger selectedOtherButtonIndex) {
  716. if (selectedOtherButtonIndex == 0) {
  717. GKPhoto *photo = self.browser.photos[self.browser.currentIndex];
  718. NSData *imageData = nil;
  719. if ([photo.image isKindOfClass:[SDAnimatedImage class]]) {
  720. imageData = [(SDAnimatedImage *)photo.image animatedImageData];
  721. }else {
  722. imageData = [photo.image sd_imageData];
  723. }
  724. if (!imageData) return;
  725. [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
  726. if (@available(iOS 9, *)) {
  727. PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];
  728. [request addResourceWithType:PHAssetResourceTypePhoto data:imageData options:nil];
  729. request.creationDate = [NSDate date];
  730. }
  731. } completionHandler:^(BOOL success, NSError *error) {
  732. dispatch_async(dispatch_get_main_queue(), ^{
  733. if (success) {
  734. NSLog(@"保存照片成功");
  735. ShowMsg(@"图片保存成功");
  736. } else if (error) {
  737. ShowMsg(@"保存保存失败");
  738. NSLog(@"保存照片出错:%@",error.localizedDescription);
  739. }
  740. });
  741. }];
  742. }
  743. }];
  744. }
  745. #pragma mark - IDMPhotoBrowserDelegate
  746. - (void)photoBrowser:(IDMPhotoBrowser *)photoBrowser didDismissActionSheetWithButtonIndex:(NSUInteger)buttonIndex photoIndex:(NSUInteger)photoIndex {
  747. }
  748. /**
  749. * Mob隐私判断
  750. *
  751. * @author ZhangRong
  752. * @date 2020-06-16 14:30:55
  753. */
  754. - (void)checkMobPolicyOnResult:(void (^_Nullable)(BOOL success))handler {
  755. //获取隐私协议
  756. // [MobSDK getPrivacyPolicy:@"1" language:@"zh" compeletion:^(NSDictionary * _Nullable data, NSError * _Nullable error) {
  757. //
  758. // NSString *url = data[@"content"];
  759. // if(url) {
  760. // [SMSDemoPolicyManager show:url compeletion:^(BOOL accept) {
  761. // //是否接受隐私协议
  762. // [MobSDK uploadPrivacyPermissionStatus:accept onResult:^(BOOL success) {
  763. // handler(success);
  764. // }];
  765. //
  766. // }];
  767. // }
  768. //
  769. // }];
  770. }
  771. - (void)saveObjectWithObject:(id)object ForKey:(NSString* )key {
  772. NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
  773. if (!object) {
  774. [ud removeObjectForKey:key];
  775. }else{
  776. [ud setObject:object forKey:key];
  777. }
  778. [ud synchronize];
  779. }
  780. - (id)getObjectWithKey:(NSString *)key {
  781. NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
  782. return [ud objectForKey:key];
  783. }
  784. // 检测抓包
  785. - (BOOL)checkProxySetting {
  786. NSDictionary *proxySettings = (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());
  787. NSArray *proxies = (__bridge NSArray *)(CFNetworkCopyProxiesForURL((__bridge CFURLRef _Nonnull)([NSURL URLWithString:@"https://www.baidu.com"]), (__bridge CFDictionaryRef _Nonnull)(proxySettings)));
  788. NSLog(@"\n%@",proxies);
  789. NSDictionary *settings = proxies[0];
  790. NSLog(@"%@",[settings objectForKey:(NSString *)kCFProxyHostNameKey]);
  791. NSLog(@"%@",[settings objectForKey:(NSString *)kCFProxyPortNumberKey]);
  792. NSLog(@"%@",[settings objectForKey:(NSString *)kCFProxyTypeKey]);
  793. if ([[settings objectForKey:(NSString *)kCFProxyTypeKey] isEqualToString:@"kCFProxyTypeNone"]) {
  794. NSLog(@"没设置代理");
  795. return NO;
  796. } else {
  797. NSLog(@"设置了代理");
  798. return YES;
  799. }
  800. }
  801. - (void)gotoWebViewWithUrlStr:(NSString *)url {
  802. RQCustomWebViewViewController *vc = [[RQCustomWebViewViewController alloc] init];
  803. vc.url = url;
  804. vc.modalPresentationStyle = UIModalPresentationFullScreen;
  805. vc.webType = WebTypeAd;
  806. RQBaseNavigationController *nav = [[RQBaseNavigationController alloc] initWithRootViewController:vc];
  807. [RQControllerHelper.topViewController presentViewController:nav animated:YES completion:nil];
  808. }
  809. // 前往小程序
  810. - (void)miniwithUserName:(NSString *)userName path:(NSString *)path {
  811. WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object];
  812. launchMiniProgramReq.userName = userName; ////拉起的小程序的username
  813. launchMiniProgramReq.path = path; ////拉起小程序页面的可带参路径,不填默认拉起小程序首页,对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar"。
  814. launchMiniProgramReq.miniProgramType = WXMiniProgramTypeRelease; ///拉起小程序的类型
  815. return [WXApi sendReq:launchMiniProgramReq completion:^(BOOL success) {
  816. }];
  817. }
  818. - (UIWindow *)getKeyWindow {
  819. if (@available(iOS 13.0, *)) {
  820. for (UIWindowScene* windowScene in [UIApplication sharedApplication].connectedScenes) {
  821. if (windowScene.activationState == UISceneActivationStateForegroundActive) {
  822. for (UIWindow *window in windowScene.windows) {
  823. if (window.isKeyWindow) {
  824. return window;
  825. break;
  826. }
  827. }
  828. }
  829. }
  830. } else {
  831. return [UIApplication sharedApplication].keyWindow;
  832. }
  833. return nil;
  834. }
  835. @end