VerificationManager.m 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. //
  2. // VerificationManager.m
  3. // Filmage Screen
  4. //
  5. // Created by 朱东勇 on 2018/2/8.
  6. // Copyright © 2018年 kdan mobile. All rights reserved.
  7. //
  8. #import "VerificationManager.h"
  9. #import "NSNULL+Filtration.h"
  10. #import "NSObject+DeviceInfo.h"
  11. #import "JSONKit.h"
  12. #import "ASIFormDataRequest.h"
  13. const NSString *kDeviceVerifyFinishNotification = @"kDeviceVerifyFinishNotification";
  14. const NSString *kDeviceActivateStatusChangeNotification = @"kDeviceActivateNotification";
  15. static VerificationManager *__verificationManager = nil;
  16. @interface VerificationManager ()
  17. @property (nonatomic, strong) NSTimer *timer;
  18. @property (nonatomic) BOOL isVerifing;
  19. @end
  20. @implementation VerificationManager
  21. + (VerificationManager*)manager {
  22. #if VERSION_DMG
  23. if (!__verificationManager)
  24. __verificationManager = [[VerificationManager alloc] init];
  25. #else
  26. return nil;
  27. #endif
  28. return __verificationManager;
  29. }
  30. + (VerificationManager*)defaultManager {
  31. #if VERSION_DMG
  32. if (!__verificationManager)
  33. __verificationManager = [[VerificationManager alloc] init];
  34. #else
  35. return nil;
  36. #endif
  37. return __verificationManager;
  38. }
  39. - (instancetype)init {
  40. self = [super init];
  41. self.autoVerification = YES;
  42. #if !DEBUG // 非测试环境时
  43. #if kTestMode // 测试模式时 报错
  44. //#error 服务器未切换到正式服务器!
  45. #endif
  46. #endif
  47. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  48. [self verificationWithComplention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  49. }];
  50. });
  51. return self;
  52. }
  53. #pragma mark - Setter & Getter
  54. - (ActivityStatus)status {
  55. return self.detailInfo.status;
  56. }
  57. - (BOOL)needUpgradeLicense {
  58. if ([self.detailInfo[@"device"][@"product_code"] isEqualToString:@"com.brother.pdfreaderpro.mac.product_1"] ||
  59. [self.detailInfo[@"device"][@"product_code"] isEqualToString:@"com.brother.pdfreaderpro.cross.platform.product_1"]) {
  60. return YES;
  61. }
  62. // if ([self.detailInfo[@"subscription"][@"product"][@"code"] isEqualToString:@"com.brother.pdfreaderpro.mac.product_1"]) {
  63. // return YES;
  64. // }
  65. return NO;
  66. }
  67. - (BOOL)secondTrialEnabled {
  68. return self.detailInfo.repeatTrial;
  69. }
  70. - (NSInteger)trialTimes {
  71. return self.detailInfo.trialTimes;
  72. }
  73. - (NSString *)licenseCode {
  74. return self.detailInfo.licenseCode;
  75. }
  76. - (NSString *)email {
  77. return self.detailInfo.email?:@"";
  78. }
  79. - (NSString *)accountName {
  80. return self.detailInfo.accountName;
  81. }
  82. - (BOOL)allowUnbind {
  83. return self.detailInfo.allowUnbind;
  84. }
  85. - (NSInteger)unbindTimes {
  86. return self.detailInfo.unbindTimes;
  87. }
  88. - (NSString*)udid {
  89. //#if DEBUG
  90. // NSString *cachePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"uuid.plist"];
  91. // NSMutableDictionary *info = [[NSDictionary dictionaryWithContentsOfFile:cachePath] mutableCopy];
  92. //
  93. // if (!info) {
  94. // info = [NSMutableDictionary dictionary];
  95. //
  96. // [info setValue:[NSString stringWithFormat:@"TestInvate%.0f", [NSDate date].timeIntervalSince1970]
  97. // forKey:@"uuid"];
  98. //
  99. //
  100. // [[NSFileManager defaultManager] createDirectoryAtPath:NSTemporaryDirectory()
  101. // withIntermediateDirectories:YES
  102. // attributes:nil
  103. // error:nil];
  104. // [info writeToFile:cachePath atomically:YES];
  105. // }
  106. //
  107. // return info[@"uuid"]?:(GetHardwareUUID()?:@"");
  108. //#endif
  109. return GetHardwareUUID()?:@"";
  110. }
  111. - (NSString*)bundleIdentify {
  112. return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]?:@"";
  113. }
  114. - (void)setDetailInfo:(NSDictionary *)detailInfo {
  115. NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  116. [defaults setValue:[detailInfo JSONData]
  117. forKey:@"detailInfo"];
  118. [defaults synchronize];
  119. }
  120. - (NSDictionary*)detailInfo {
  121. NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  122. return [[[defaults valueForKey:@"detailInfo"] objectFromJSONData] filterNullObject];
  123. }
  124. //
  125. //- (void)setIsTest:(BOOL)isTest {
  126. // _isTest = isTest;
  127. //
  128. // [self verificationWithComplention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  129. //
  130. // }];
  131. //}
  132. - (void)setAutoVerification:(BOOL)autoVerification {
  133. _autoVerification = autoVerification;
  134. [self restartTimer];
  135. }
  136. #pragma mark - Timer
  137. - (void)restartTimer {
  138. if (self.timer)
  139. [self.timer invalidate];
  140. self.timer = nil;
  141. if (self.autoVerification &&
  142. self.status != ActivityStatusNone) {
  143. self.timer = [NSTimer scheduledTimerWithTimeInterval:60 * 60//一个小时更新一次
  144. target:self
  145. selector:@selector(verificationFire)
  146. userInfo:nil
  147. repeats:NO];
  148. }
  149. }
  150. - (void)verificationFire {
  151. [self verificationWithComplention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  152. }];
  153. }
  154. #pragma mark - Interface
  155. - (void)activateDeviceWithInfo:(NSDictionary*)info
  156. complention:(ActivityComplention)complention {
  157. if (![info[@"cdkey"] length]) {
  158. //激活码为空
  159. NSError *error = [NSError errorWithDomain:@""
  160. code:ActivityErrorTypeCDKeyEmpty
  161. userInfo:nil];
  162. if (complention)
  163. complention(NO, nil, error);
  164. return;
  165. }
  166. if (![self isValidLicenseCode:info[@"cdkey"]]) {
  167. //激活码格式不正确
  168. NSError *error = [NSError errorWithDomain:@"激活失败"
  169. code:ActivityErrorTypeFormatError
  170. userInfo:nil];
  171. if (complention)
  172. complention(NO, @{@"errors":@"FormatError"}, error);
  173. return;
  174. }
  175. __block ActivityComplention tComplention = complention;
  176. __block VerificationManager *weak_self = self;
  177. //Process Params
  178. NSString *app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] description];
  179. if (!app_version.length)
  180. app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] description];
  181. NSDictionary *params =
  182. @{
  183. @"data":@{
  184. //激活信息
  185. @"subscription":@{
  186. @"app_code":[self bundleIdentify]?:@"",
  187. @"email":info[@"email"]?:@"",
  188. @"cdkey":info[@"cdkey"]?:@"",
  189. },
  190. //设备信息
  191. @"device":@{
  192. @"unique_sn":[self udid]?:@"",
  193. @"model":GetProductName()?:@"",
  194. @"os":GetSystemVersion()?:@"",
  195. @"time_zone":[[NSTimeZone localTimeZone] localizedName:NSTimeZoneNameStyleShortDaylightSaving locale:[NSLocale currentLocale]]?:@"",
  196. @"language":[[NSLocale currentLocale] localeIdentifier]?:@"",
  197. @"app_version":app_version?:@"",
  198. @"platform":@"DMG"
  199. }
  200. }
  201. };
  202. NSMutableData *postData = [VerificationManager mutableDataWithDic:params];
  203. //Send Request
  204. NSString *urlString = [kVerificationServer stringByAppendingString:@"api/auth_devices/activate"];
  205. NSURL *url = [NSURL URLWithString:urlString];
  206. ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
  207. request.requestMethod = @"POST";
  208. [request setPostBody:postData];
  209. NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]];
  210. NSMutableDictionary *requestHeaders = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  211. postLength, @"Content-Length", nil];
  212. request.defaultResponseEncoding = NSUTF8StringEncoding;
  213. // [request setAuthenticationScheme:@"https"];//设置验证方式
  214. // [request setValidatesSecureCertificate:NO];//设置验证证书
  215. [request setRequestHeaders:requestHeaders];
  216. [request addRequestHeader:@"Content-Type" value:@"application/json"];
  217. [request addRequestHeader:@"Accept" value:@"application/vnd.api+json;version=1"];
  218. __block void(^processRequest)(void) = ^{
  219. dispatch_async(dispatch_get_main_queue(), ^{
  220. NSDictionary *info = [[request.responseString objectFromJSONString] filterNullObject];
  221. NSError *error = request.error;
  222. if (info && [info isKindOfClass:[NSDictionary class]]) {
  223. if ([info valueForKey:@"errors"]) {
  224. NSString *detailKey = [[info[@"errors"] firstObject] valueForKey:@"detail_key"];
  225. if ([detailKey isEqualToString:@"exceed_max_device_num"]) {
  226. error = [NSError errorWithDomain:@"激活失败"
  227. code:ActivityErrorTypeOutNumber
  228. userInfo:info];
  229. }else if ([detailKey isEqualToString:@"invalid_activate_info"]) {
  230. error = [NSError errorWithDomain:@"激活失败"
  231. code:ActivityErrorTypeInvalidInfo
  232. userInfo:info];
  233. }else if ([detailKey isEqualToString:@"invalid_license_key"]) {
  234. error = [NSError errorWithDomain:@"激活失败"
  235. code:ActivityErrorTypeCDKeyNotExist
  236. userInfo:info];
  237. }else if ([detailKey isEqualToString:@"license_not_match_product"]) {
  238. error = [NSError errorWithDomain:@"激活失败"
  239. code:ActivityErrorTypeNotMatchProduct
  240. userInfo:info];
  241. }else if ([detailKey isEqualToString:@"license_expired"]) {
  242. error = [NSError errorWithDomain:@"激活失败"
  243. code:ActivityErrorTypeCDKeyExpire
  244. userInfo:info];
  245. }else {
  246. error = [NSError errorWithDomain:@"激活失败"
  247. code:ActivityErrorTypeUnknow
  248. userInfo:info];
  249. }
  250. }else if ([info valueForKey:@"error"]) {
  251. error = [NSError errorWithDomain:@"激活失败"
  252. code:ActivityErrorTypeUnknow
  253. userInfo:info];
  254. }
  255. }else {
  256. if(error) {
  257. error = [NSError errorWithDomain:error.domain code:ActivityErrorTypeNetworkDisable userInfo:error.userInfo];
  258. } else {
  259. error = [NSError errorWithDomain:@"激活失败"
  260. code:ActivityErrorTypeUnknow
  261. userInfo:@{}];
  262. }
  263. }
  264. if (!error) {
  265. NSMutableDictionary *dic = [weak_self.detailInfo?:@{} mutableCopy];
  266. for (NSString *key in info[@"data"]) {
  267. [dic setValue:info[@"data"][key] forKey:key];
  268. }
  269. weak_self.detailInfo = dic;
  270. NSString *notificationName = (NSString *)kDeviceActivateStatusChangeNotification;
  271. [[NSNotificationCenter defaultCenter] postNotificationName:notificationName
  272. object:self
  273. userInfo:info];
  274. [weak_self verificationWithComplention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  275. }];
  276. }
  277. [weak_self restartTimer];
  278. if (tComplention)
  279. tComplention(weak_self.status, info, error);
  280. });
  281. };
  282. [request setFailedBlock:^{
  283. processRequest();
  284. }];
  285. [request setCompletionBlock:^{
  286. processRequest();
  287. }];
  288. [request startAsynchronous];
  289. }
  290. - (void)verificationWithComplention:(ActivityComplention)complention {
  291. __block ActivityComplention tComplention = complention;
  292. __block VerificationManager *weak_self = self;
  293. if (!self.isVerifing) {
  294. self.isVerifing = YES;
  295. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  296. //Process Params
  297. NSString *app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] description];
  298. if (!app_version.length)
  299. app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] description];
  300. NSString *platform = @"DMG";
  301. #if VERSION_FREE
  302. #if VERSION_DMG
  303. #else
  304. platform = @"AppleStore";
  305. #endif
  306. #else
  307. platform = @"AppleStorePro";
  308. #endif
  309. NSDictionary *params =
  310. @{
  311. @"data":@{
  312. //验证信息
  313. @"subscription":@{
  314. @"app_code":[self bundleIdentify]?:@"",
  315. // @"email":info[@"email"]?:@"",
  316. // @"cdkey":info[@"cdkey"]?:@"",
  317. },
  318. //设备信息
  319. @"device":@{
  320. @"unique_sn":[self udid]?:@"",
  321. @"model":GetProductName()?:@"",
  322. @"os":GetSystemVersion()?:@"",
  323. @"time_zone":[[NSTimeZone localTimeZone] localizedName:NSTimeZoneNameStyleShortDaylightSaving locale:[NSLocale currentLocale]]?:@"",
  324. @"language":[[NSLocale currentLocale] localeIdentifier]?:@"",
  325. @"app_version":app_version?:@"",
  326. @"platform":platform?:@"AppleStore"
  327. }
  328. }
  329. };
  330. NSMutableData *postData = [VerificationManager mutableDataWithDic:params];
  331. //Send Request
  332. NSString *urlString = [kVerificationServer stringByAppendingString:@"api/auth_devices/verify"];
  333. NSURL *url = [NSURL URLWithString:urlString];
  334. ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
  335. request.requestMethod = @"POST";
  336. [request setPostBody:postData];
  337. NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]];
  338. NSMutableDictionary *requestHeaders = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  339. postLength, @"Content-Length", nil];
  340. // [request setAuthenticationScheme:@"https"];//设置验证方式
  341. // [request setValidatesSecureCertificate:NO];//设置验证证书
  342. [request setRequestHeaders:requestHeaders];
  343. [request addRequestHeader:@"Content-Type" value:@"application/json"];
  344. [request addRequestHeader:@"Accept" value:@"application/vnd.api+json;version=1"];
  345. __block void(^processRequest)(void) = ^{
  346. dispatch_async(dispatch_get_main_queue(), ^{
  347. NSDictionary *info = [[request.responseString objectFromJSONString] filterNullObject];
  348. ActivityStatus status = weak_self.status;
  349. if ([info valueForKey:@"data"] &&
  350. [[info valueForKey:@"data"] valueForKey:@"device"]) {
  351. ActivityStatus tStatus = [(NSDictionary*)info[@"data"] status];
  352. //存储信息,并发送更新通知
  353. weak_self.detailInfo = info[@"data"];
  354. // if (status != tStatus ||
  355. // [[info valueForKey:@"data"] valueForKey:@"invite"]) {
  356. //发送通知
  357. NSString *notificationName = (NSString *)kDeviceActivateStatusChangeNotification;
  358. [[NSNotificationCenter defaultCenter] postNotificationName:notificationName
  359. object:weak_self
  360. userInfo:info];
  361. // }
  362. }
  363. [[NSNotificationCenter defaultCenter] postNotificationName:(NSString *)kDeviceVerifyFinishNotification
  364. object:nil
  365. userInfo:nil];
  366. weak_self.isVerifing = NO;
  367. //重置计时器
  368. [weak_self restartTimer];
  369. if (tComplention)
  370. tComplention(weak_self.status, info, request.error);
  371. });
  372. };
  373. [request setFailedBlock:^{
  374. processRequest();
  375. }];
  376. [request setCompletionBlock:^{
  377. processRequest();
  378. }];
  379. [request startAsynchronous];
  380. });
  381. }else {
  382. __block void(^waitBlock)(void) = ^{
  383. if (weak_self.isVerifing) {
  384. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  385. waitBlock();
  386. });
  387. }else {
  388. if (tComplention)
  389. tComplention(weak_self.status, @{@"data":weak_self.detailInfo?:@{}}, nil);
  390. waitBlock = NULL;
  391. }
  392. };
  393. waitBlock();
  394. }
  395. }
  396. - (void)trialForDays:(float)days
  397. complention:(ActivityComplention)complention {
  398. [self trialForDays:days email:nil name:nil complention:complention];
  399. }
  400. - (void)trialForDays:(float)days
  401. email:(NSString*)email
  402. name:(NSString*)name
  403. complention:(ActivityComplention)complention {
  404. __block ActivityComplention tComplention = complention;
  405. __block VerificationManager *weak_self = self;
  406. //Process Params
  407. NSString *app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] description];
  408. if (!app_version.length)
  409. app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] description];
  410. NSDictionary *params =
  411. @{
  412. @"data":@{
  413. //激活信息
  414. @"subscription":@{
  415. @"app_code":[self bundleIdentify]?:@"",
  416. @"trail_days":@(MAX(days, 1)),
  417. @"email":email?:@"",
  418. @"contact_name":name?:@""
  419. },
  420. //设备信息
  421. @"device":@{
  422. @"unique_sn":[self udid]?:@"",
  423. @"model":GetProductName()?:@"",
  424. @"os":GetSystemVersion()?:@"",
  425. @"time_zone":[[NSTimeZone localTimeZone] localizedName:NSTimeZoneNameStyleShortDaylightSaving locale:[NSLocale currentLocale]]?:@"",
  426. @"language":[[NSLocale currentLocale] localeIdentifier]?:@"",
  427. @"app_version":app_version?:@""
  428. }
  429. }
  430. };
  431. NSMutableData *postData = [VerificationManager mutableDataWithDic:params];
  432. //Send Request
  433. NSString *urlString = [kVerificationServer stringByAppendingString:@"api/auth_devices/trial"];
  434. NSURL *url = [NSURL URLWithString:urlString];
  435. ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
  436. request.requestMethod = @"POST";
  437. [request setPostBody:postData];
  438. NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]];
  439. NSMutableDictionary *requestHeaders = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  440. postLength, @"Content-Length", nil];
  441. request.defaultResponseEncoding = NSUTF8StringEncoding;
  442. // [request setAuthenticationScheme:@"https"];//设置验证方式
  443. // [request setValidatesSecureCertificate:NO];//设置验证证书
  444. [request setRequestHeaders:requestHeaders];
  445. [request addRequestHeader:@"Content-Type" value:@"application/json"];
  446. [request addRequestHeader:@"Accept" value:@"application/vnd.api+json;version=1"];
  447. __block void(^processRequest)(void) = ^{
  448. dispatch_async(dispatch_get_main_queue(), ^{
  449. NSDictionary *info = [[request.responseString objectFromJSONString] filterNullObject];
  450. ActivityStatus status = weak_self.status;
  451. if ([info valueForKey:@"data"] &&
  452. [[info valueForKey:@"data"] valueForKey:@"device"]) {
  453. ActivityStatus tStatus = [(NSDictionary*)info[@"data"] status];
  454. //存储信息,并发送更新通知
  455. NSMutableDictionary *dic = [weak_self.detailInfo?:@{} mutableCopy];
  456. for (NSString *key in info[@"data"]) {
  457. [dic setValue:info[@"data"][key] forKey:key];
  458. }
  459. weak_self.detailInfo = dic;
  460. if (status != tStatus) {
  461. //发送通知
  462. NSString *notificationName = (NSString *)kDeviceActivateStatusChangeNotification;
  463. [[NSNotificationCenter defaultCenter] postNotificationName:notificationName
  464. object:self
  465. userInfo:info];
  466. }
  467. }
  468. //重置计时器
  469. [weak_self restartTimer];
  470. if (tComplention)
  471. tComplention(weak_self.status, info, request.error);
  472. });
  473. };
  474. [request setFailedBlock:^{
  475. processRequest();
  476. }];
  477. [request setCompletionBlock:^{
  478. processRequest();
  479. }];
  480. [request startAsynchronous];
  481. }
  482. - (void)getCodeWithEmail:(NSString*)email
  483. complention:(ActivityComplention)complention {
  484. __block ActivityComplention tComplention = complention;
  485. __block VerificationManager *weak_self = self;
  486. //Process Params
  487. NSString *app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] description];
  488. if (!app_version.length)
  489. app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] description];
  490. NSString *platform = @"DMG";
  491. #ifdef AppStore_Version
  492. #if Lite_Version
  493. platform = @"AppleStore";
  494. #else
  495. platform = @"AppleStorePro";
  496. #endif
  497. #endif
  498. NSDictionary *params =
  499. @{
  500. @"data":@{
  501. @"app_code":[self bundleIdentify]?:@"",
  502. @"email":email?:@"",
  503. @"unique_sn":[self udid]?:@"",
  504. @"platform":platform?:@"AppleStore"
  505. }
  506. };
  507. NSMutableData *postData = [VerificationManager mutableDataWithDic:params];
  508. //Send Request
  509. NSString *urlString = [kVerificationServer stringByAppendingString:@"api/invites/getCode"];
  510. NSURL *url = [NSURL URLWithString:urlString];
  511. ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
  512. request.requestMethod = @"POST";
  513. [request setPostBody:postData];
  514. NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]];
  515. NSMutableDictionary *requestHeaders = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  516. postLength, @"Content-Length", nil];
  517. request.defaultResponseEncoding = NSUTF8StringEncoding;
  518. // [request setAuthenticationScheme:@"https"];//设置验证方式
  519. // [request setValidatesSecureCertificate:NO];//设置验证证书
  520. [request setRequestHeaders:requestHeaders];
  521. [request addRequestHeader:@"Content-Type" value:@"application/json"];
  522. [request addRequestHeader:@"Accept" value:@"application/vnd.api+json;version=1"];
  523. __block void(^processRequest)(void) = ^{
  524. dispatch_async(dispatch_get_main_queue(), ^{
  525. NSDictionary *info = [[request.responseString objectFromJSONString] filterNullObject];
  526. if ([info valueForKey:@"data"] &&
  527. [[info valueForKey:@"data"] valueForKey:@"email"] &&
  528. [[info valueForKey:@"data"] valueForKey:@"share_code"]) {
  529. //存储信息,并发送更新通知
  530. NSMutableDictionary *dic = [weak_self.detailInfo?:@{} mutableCopy];
  531. [dic setValue:info[@"data"] forKey:@"invite"];
  532. weak_self.detailInfo = dic;
  533. [weak_self verificationWithComplention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  534. }];
  535. }
  536. //重置计时器
  537. [weak_self restartTimer];
  538. if (tComplention)
  539. tComplention(weak_self.status, info, request.error);
  540. });
  541. };
  542. [request setFailedBlock:^{
  543. processRequest();
  544. }];
  545. [request setCompletionBlock:^{
  546. processRequest();
  547. }];
  548. [request startAsynchronous];
  549. }
  550. //使用邀请码
  551. - (void)userCode:(NSString*)code
  552. complention:(ActivityComplention)complention {
  553. __block ActivityComplention tComplention = complention;
  554. __block VerificationManager *weak_self = self;
  555. //Process Params
  556. NSString *app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] description];
  557. if (!app_version.length)
  558. app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] description];
  559. BOOL iszhcn = !([NSLocalizedString(@"Language", nil) isEqualToString:@"English"] &&
  560. [NSLocalizedString(@"Language", nil) isEqualToString:@"Français"]);
  561. NSString *platform = @"DMG";
  562. #ifdef AppStore_Version
  563. #if Lite_Version
  564. platform = @"AppleStore";
  565. #else
  566. platform = @"AppleStorePro";
  567. #endif
  568. #endif
  569. NSDictionary *params =
  570. @{
  571. @"data":@{
  572. @"app_code":[self bundleIdentify]?:@"",
  573. @"code":code?:@"",
  574. @"unique_sn":[self udid]?:@"",
  575. @"lang":@(iszhcn),
  576. @"platform":platform?:@"AppleStore"
  577. }
  578. };
  579. NSMutableData *postData = [VerificationManager mutableDataWithDic:params];
  580. //Send Request
  581. NSString *urlString = [kVerificationServer stringByAppendingString:@"api/invites/activeInvite"];
  582. NSURL *url = [NSURL URLWithString:urlString];
  583. ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
  584. request.requestMethod = @"POST";
  585. [request setPostBody:postData];
  586. NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]];
  587. NSMutableDictionary *requestHeaders = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  588. postLength, @"Content-Length", nil];
  589. request.defaultResponseEncoding = NSUTF8StringEncoding;
  590. // [request setAuthenticationScheme:@"https"];//设置验证方式
  591. // [request setValidatesSecureCertificate:NO];//设置验证证书
  592. [request setRequestHeaders:requestHeaders];
  593. [request addRequestHeader:@"Content-Type" value:@"application/json"];
  594. [request addRequestHeader:@"Accept" value:@"application/vnd.api+json;version=1"];
  595. __block void(^processRequest)(void) = ^{
  596. dispatch_async(dispatch_get_main_queue(), ^{
  597. NSDictionary *info = [[request.responseString objectFromJSONString] filterNullObject];
  598. ActivityStatus status = weak_self.status;
  599. if ([info valueForKey:@"data"] &&
  600. [[info valueForKey:@"data"] valueForKey:@"device"]) {
  601. ActivityStatus tStatus = [(NSDictionary*)info[@"data"] status];
  602. weak_self.detailInfo = info[@"data"];
  603. if (status != tStatus) {
  604. //发送通知
  605. NSString *notificationName = (NSString *)kDeviceActivateStatusChangeNotification;
  606. [[NSNotificationCenter defaultCenter] postNotificationName:notificationName
  607. object:self
  608. userInfo:info];
  609. }
  610. [weak_self verificationWithComplention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  611. }];
  612. }
  613. //重置计时器
  614. [weak_self restartTimer];
  615. if (tComplention)
  616. tComplention(weak_self.status, info, request.error);
  617. });
  618. };
  619. [request setFailedBlock:^{
  620. processRequest();
  621. }];
  622. [request setCompletionBlock:^{
  623. processRequest();
  624. }];
  625. [request startAsynchronous];
  626. }
  627. - (void)modifyEmail:(NSString*)email
  628. complention:(ActivityComplention)complention {
  629. __block ActivityComplention tComplention = complention;
  630. __block VerificationManager *weak_self = self;
  631. //Process Params
  632. NSString *app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] description];
  633. if (!app_version.length)
  634. app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] description];
  635. BOOL iszhcn = !([NSLocalizedString(@"Language", nil) isEqualToString:@"English"] &&
  636. [NSLocalizedString(@"Language", nil) isEqualToString:@"Français"]);
  637. NSDictionary *params =
  638. @{
  639. @"data":@{
  640. @"app_code":[self bundleIdentify]?:@"",
  641. @"email":email?:@"",
  642. @"unique_sn":[self udid]?:@"",
  643. @"lang":@(iszhcn),
  644. }
  645. };
  646. NSMutableData *postData = [VerificationManager mutableDataWithDic:params];
  647. //Send Request
  648. NSString *urlString = [kVerificationServer stringByAppendingString:@"api/invites/updateEmail"];
  649. NSURL *url = [NSURL URLWithString:urlString];
  650. ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
  651. request.requestMethod = @"POST";
  652. [request setPostBody:postData];
  653. NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]];
  654. NSMutableDictionary *requestHeaders = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  655. postLength, @"Content-Length", nil];
  656. request.defaultResponseEncoding = NSUTF8StringEncoding;
  657. // [request setAuthenticationScheme:@"https"];//设置验证方式
  658. // [request setValidatesSecureCertificate:NO];//设置验证证书
  659. [request setRequestHeaders:requestHeaders];
  660. [request addRequestHeader:@"Content-Type" value:@"application/json"];
  661. [request addRequestHeader:@"Accept" value:@"application/vnd.api+json;version=1"];
  662. __block void(^processRequest)(void) = ^{
  663. dispatch_async(dispatch_get_main_queue(), ^{
  664. NSDictionary *info = [[request.responseString objectFromJSONString] filterNullObject];
  665. if ([info valueForKey:@"data"] &&
  666. [[info valueForKey:@"data"] valueForKey:@"email"] &&
  667. [[info valueForKey:@"data"] valueForKey:@"share_code"]) {
  668. //存储信息,并发送更新通知
  669. NSMutableDictionary *dic = [weak_self.detailInfo?:@{} mutableCopy];
  670. [dic setValue:info[@"data"] forKey:@"invite"];
  671. weak_self.detailInfo = dic;
  672. [weak_self verificationWithComplention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  673. }];
  674. }
  675. //重置计时器
  676. [weak_self restartTimer];
  677. if (tComplention)
  678. tComplention(weak_self.status, info, request.error);
  679. });
  680. };
  681. [request setFailedBlock:^{
  682. processRequest();
  683. }];
  684. [request setCompletionBlock:^{
  685. processRequest();
  686. }];
  687. [request startAsynchronous];
  688. }
  689. //给好友发送邀请码
  690. - (void)sendInvateEmails:(NSString*)emails
  691. code:(NSString*)code
  692. complention:(ActivityComplention)complention {
  693. __block ActivityComplention tComplention = complention;
  694. __block VerificationManager *weak_self = self;
  695. //Process Params
  696. NSString *app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] description];
  697. if (!app_version.length)
  698. app_version = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] description];
  699. BOOL iszhcn = !([NSLocalizedString(@"Language", nil) isEqualToString:@"English"] &&
  700. [NSLocalizedString(@"Language", nil) isEqualToString:@"Français"]);
  701. NSDictionary *params =
  702. @{
  703. @"data":@{
  704. @"app_code":[self bundleIdentify]?:@"",
  705. @"email":emails?:@"",
  706. @"code":[code stringByReplacingOccurrencesOfString:@" " withString:@""]?:@"",
  707. @"unique_sn":[self udid]?:@"",
  708. @"lang":@(iszhcn),
  709. }
  710. };
  711. NSMutableData *postData = [VerificationManager mutableDataWithDic:params];
  712. //Send Request
  713. NSString *urlString = [kVerificationServer stringByAppendingString:@"api/invites/shareEmail"];
  714. NSURL *url = [NSURL URLWithString:urlString];
  715. ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
  716. request.requestMethod = @"POST";
  717. [request setPostBody:postData];
  718. NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]];
  719. NSMutableDictionary *requestHeaders = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  720. postLength, @"Content-Length", nil];
  721. request.defaultResponseEncoding = NSUTF8StringEncoding;
  722. // [request setAuthenticationScheme:@"https"];//设置验证方式
  723. // [request setValidatesSecureCertificate:NO];//设置验证证书
  724. [request setRequestHeaders:requestHeaders];
  725. [request addRequestHeader:@"Content-Type" value:@"application/json"];
  726. [request addRequestHeader:@"Accept" value:@"application/vnd.api+json;version=1"];
  727. __block void(^processRequest)(void) = ^{
  728. dispatch_async(dispatch_get_main_queue(), ^{
  729. NSDictionary *info = [[request.responseString objectFromJSONString] filterNullObject];
  730. //重置计时器
  731. [weak_self restartTimer];
  732. if (tComplention)
  733. tComplention(weak_self.status, info, request.error);
  734. [weak_self verificationWithComplention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  735. }];
  736. });
  737. };
  738. [request setFailedBlock:^{
  739. processRequest();
  740. }];
  741. [request setCompletionBlock:^{
  742. processRequest();
  743. }];
  744. [request startAsynchronous];
  745. }
  746. #pragma mark - Data Formatter
  747. - (BOOL)isValidLicenseCode:(NSString *)cdKey {
  748. NSString *validKey = [cdKey stringByReplacingOccurrencesOfString:@" " withString:@""];
  749. if (validKey.length != 19) {
  750. return NO;
  751. }
  752. //计算字符串长度
  753. NSInteger str_length = [validKey length];
  754. NSString *regex = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
  755. for (int i = 0; i<str_length; i++) {
  756. NSString *subStr = [validKey substringWithRange:NSMakeRange(i, 1)];
  757. if([regex rangeOfString:subStr].location == NSNotFound) {
  758. return NO;
  759. }
  760. }
  761. return YES;
  762. }
  763. + (NSString*)postStringWithObject:(id)value {
  764. NSString *string;
  765. if ([value isKindOfClass:[NSArray class]]) {
  766. string = @"[";
  767. BOOL isFirst = YES;
  768. for (id object in value) {
  769. if (isFirst) {
  770. isFirst = NO;
  771. }else {
  772. string = [string stringByAppendingString:@","];
  773. }
  774. string = [string stringByAppendingString:[VerificationManager postStringWithObject:object]];
  775. }
  776. string = [string stringByAppendingString:@"]"];
  777. }else if ([value isKindOfClass:[NSDictionary class]]) {
  778. string = @"{";
  779. BOOL isFirst = YES;
  780. for (NSString *key in [value allKeys]) {
  781. if (isFirst) {
  782. isFirst = NO;
  783. }else {
  784. string = [string stringByAppendingString:@","];
  785. }
  786. string = [string stringByAppendingFormat:@"\"%@\"", key];
  787. string = [string stringByAppendingString:@":"];
  788. string = [string stringByAppendingString:[VerificationManager postStringWithObject:[value valueForKey:key]]];
  789. }
  790. string = [string stringByAppendingString:@"}"];
  791. }else {
  792. string = [NSString stringWithFormat:@"\"%@\"", value];
  793. }
  794. return string;
  795. }
  796. + (NSString*)postStringWithDic:(NSDictionary*)dic {
  797. return [VerificationManager postStringWithObject:dic];
  798. }
  799. + (NSMutableData*)mutableDataWithDic:(NSDictionary*)dic {
  800. NSString *json = [VerificationManager postStringWithDic:dic];
  801. json = [json stringByReplacingOccurrencesOfString:@"\n" withString:@""];
  802. json = [json stringByReplacingOccurrencesOfString:@"\r\0" withString:@""];
  803. json = [json stringByReplacingOccurrencesOfString:@"\0" withString:@""];
  804. NSData *postData = [json dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
  805. return [postData mutableCopy];
  806. }
  807. @end
  808. #pragma mark - Test
  809. #if DEBUG
  810. @implementation VerificationManager (Test)
  811. //- (ActivityStatus)status {
  812. // return ActivityStatusVerification;
  813. //}
  814. - (void)updateVerificationStatus {
  815. [self updateStatus:ActivityStatusVerification postNo:true];
  816. }
  817. - (void)updateStatus:(ActivityStatus)status postNo:(bool)postNo {
  818. NSString *subValue = @"";
  819. NSString *deviceValue = @"";
  820. if (status == ActivityStatusNone) {
  821. deviceValue = @"";
  822. } else if (status == ActivityStatusTrial) {
  823. deviceValue = @"on_trial";
  824. } else if (status == ActivityStatusTrialExpire) {
  825. deviceValue = @"expired_trial";
  826. } else if (status == ActivityStatusVerification) {
  827. deviceValue = @"activated";
  828. } else if (status == ActivityStatusVerifExpire) {
  829. deviceValue = @"expired_license";
  830. } else if (status == ActivityStatusLicenseExpire) {
  831. deviceValue = @"";
  832. subValue = @"expired";
  833. }
  834. NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:self.detailInfo];
  835. dict[@"subscription"][@"status"] = subValue;
  836. dict[@"device"][@"status"] = deviceValue;
  837. self.detailInfo = dict;
  838. if (postNo) {
  839. //发送通知
  840. NSString *notificationName = (NSString *)kDeviceActivateStatusChangeNotification;
  841. [[NSNotificationCenter defaultCenter] postNotificationName:notificationName
  842. object:self
  843. userInfo:nil];
  844. }
  845. }
  846. @end
  847. #endif
  848. #pragma mark - NSDictionary + ActivityInfo
  849. @implementation NSDictionary (ActivityInfo)
  850. - (NSDate*)expireDate {
  851. if (self[@"device"][@"end_date"]) {
  852. return [self dateForValue:self[@"device"][@"end_date"]];
  853. } else if (self[@"subscription"][@"end_date"]) {
  854. return [self dateForValue:self[@"subscription"][@"end_date"]];
  855. }
  856. return nil;
  857. }
  858. - (NSDate*)createDate {
  859. if (self[@"device"][@"created_at"]) {
  860. return [self dateForValue:self[@"device"][@"created_at"]];
  861. }
  862. return nil;
  863. }
  864. - (ActivityStatus)status {
  865. ActivityStatus tStatus = ActivityStatusNone;
  866. if ([self[@"subscription"][@"status"] isEqualToString:@"expired"]) {
  867. tStatus = ActivityStatusLicenseExpire;
  868. }else{
  869. if ([self[@"device"][@"status"] isEqualToString:@"activated"]) {
  870. tStatus = ActivityStatusVerification;
  871. }else if ([self[@"device"][@"status"] isEqualToString:@"on_trial"]) {
  872. tStatus = ActivityStatusTrial;
  873. }else if ([self[@"device"][@"status"] isEqualToString:@"expired_trial"]) {
  874. tStatus = ActivityStatusTrialExpire;
  875. }else if ([self[@"device"][@"status"] isEqualToString:@"expired_license"]) {
  876. tStatus = ActivityStatusVerifExpire;
  877. }
  878. }
  879. if (ActivityStatusTrial == tStatus) {
  880. if (self.expireDate &&
  881. [NSDate date].timeIntervalSince1970 - [self expireDate].timeIntervalSince1970 > 0) {
  882. tStatus = ActivityStatusTrialExpire;
  883. }
  884. }else if (ActivityStatusVerification == tStatus) {
  885. if (self.expireDate &&
  886. [NSDate date].timeIntervalSince1970 - [self expireDate].timeIntervalSince1970 > 0) {
  887. tStatus = ActivityStatusVerifExpire;
  888. }
  889. if (self[@"dejvice"][@"status"] &&
  890. [self[@"device"][@"status"] isEqualToString:@"expired_license"]) {
  891. //激活码过期
  892. tStatus = ActivityStatusVerifExpire;
  893. }
  894. }
  895. return tStatus;
  896. }
  897. - (NSString*)licenseCode {
  898. return self[@"device"][@"cdkey"];
  899. }
  900. - (NSString*)shareCode {
  901. return self[@"invite"][@"share_code"]?:@"";
  902. }
  903. - (NSUInteger)invateUsersCount {
  904. return [self[@"invite"][@"new_users_num"] integerValue];
  905. }
  906. - (NSString*)fromCode {
  907. return self[@"invite"][@"from_code"]?:@"";
  908. }
  909. - (NSDate*)fetchInvateDate {
  910. if (self[@"invite"][@"created_at"]) {
  911. return [self dateForValue:self[@"invite"][@"created_at"]];
  912. }
  913. return nil;
  914. }
  915. - (NSDate*)dateForValue:(id)value {
  916. if ([value isKindOfClass:[NSString class]]) {
  917. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  918. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  919. return [formatter dateFromString:[self[@"invite"][@"created_at"] substringToIndex:@"yyyy-MM-dd HH:mm:ss".length]];
  920. }else if ([value isKindOfClass:[NSNumber class]]) {
  921. return [NSDate dateWithTimeIntervalSince1970:[value doubleValue]];
  922. }
  923. return nil;
  924. }
  925. - (BOOL)repeatTrial {
  926. return [self[@"device"][@"trial_again"] boolValue];
  927. }
  928. - (NSUInteger)trialTimes {
  929. return [self[@"device"][@"trial_times"]?:@"1" intValue];
  930. }
  931. - (NSString *)email {
  932. return self[@"device"][@"email"]?:@"";
  933. }
  934. - (NSString *)accountName {
  935. return self[@"device"][@"contact_name"]?:@"";
  936. }
  937. - (NSUInteger)maxFreeDays {
  938. return [self[@"invite"][@"max_free_days"]?:@"365" intValue];
  939. }
  940. - (BOOL)allowUnbind {
  941. return [self[@"device"][@"allow_unbind"] boolValue];
  942. }
  943. - (NSInteger)unbindTimes {
  944. return [self[@"device"][@"unbind_time"]?:@"0" integerValue];
  945. }
  946. @end