VerificationManager.m 44 KB

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