VerificationManager.m 43 KB

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