VerificationManager.m 43 KB

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