KMVerificationWindowController.m 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034
  1. //
  2. // KMVerificationWindowController.m
  3. // PDF Reader Pro Edition
  4. //
  5. // Created by 王帅 on 2018/5/8.
  6. //
  7. #import "KMVerificationWindowController.h"
  8. #import "KMVerificationViewController.h"
  9. #import "KMVerificationActivateViewController.h"
  10. #import "KMVerificationExpiredViewController.h"
  11. #import "KMVerificationTrialViewController.h"
  12. #import "KMVerificationAlertViewController.h"
  13. #import "KMActivityALertViewController.h"
  14. #import "KMVerificationInfoViewController.h"
  15. #import "VerificationManager.h"
  16. //#import "KMMailHelper.h"
  17. #import "GBDeviceInfo.h"
  18. #import "Reachability.h"
  19. //#import "SKInspectPublicTool.h"
  20. //#import "FMTrackEventManager.h"
  21. #import "KMRepeatTrialAlertController.h"
  22. #import "KMRepeatVerifyExpireController.h"
  23. #import <PDF_Reader_Pro-Swift.h>
  24. @interface KMVerificationWindowController ()
  25. @property (nonatomic, assign) KMVerificationType type;
  26. @property (nonatomic, assign) IBOutlet NSBox *box;
  27. @property (nonatomic, assign) IBOutlet NSProgressIndicator *progressIndicator;
  28. @property (nonatomic, retain) KMVerificationViewController *normalViewController;
  29. @property (nonatomic, retain) KMVerificationActivateViewController *activateViewController;
  30. @property (nonatomic, retain) KMVerificationExpiredViewController *expiredViewController;
  31. @property (nonatomic, retain) KMVerificationTrialViewController *trialViewController;
  32. @property (nonatomic, retain) KMVerificationAlertViewController *alertViewController;
  33. @property (nonatomic, retain) KMActivityALertViewController *activityAlertViewController;
  34. @property (nonatomic, retain) KMVerificationInfoViewController *infoViewController;
  35. @property (nonatomic, retain) KMRepeatTrialAlertController *repeatTrialAlertController;//二次试用提示弹窗
  36. @property (nonatomic, retain) KMRepeatVerifyExpireController *repeatTrialExpireController;//二次试用过期弹窗
  37. @property (nonatomic, retain) KMTrialSuccessController *trialSuccessController;
  38. @end
  39. @implementation KMVerificationWindowController
  40. + (void)launching {
  41. [VerificationManager manager];
  42. }
  43. + (BOOL)allowsShowExpired {
  44. #if VERSION_DMG
  45. if ([VerificationManager manager].status == ActivityStatusTrialExpire &&
  46. [VerificationManager manager].secondTrialEnabled == NO) {
  47. if (![[NSUserDefaults standardUserDefaults] objectForKey:@"allowTrialExpireShowKeyDMG"]) {
  48. [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"allowTrialExpireShowKeyDMG"];
  49. return YES;
  50. }
  51. }
  52. return NO;
  53. #else
  54. NSDate *lastTimeDate = [[NSUserDefaults standardUserDefaults] objectForKey:@"kVerificationExpiredShowLastTimeDateKay"];
  55. if (lastTimeDate) {
  56. NSDate *date = [NSDate date];
  57. NSTimeInterval time = [date timeIntervalSinceDate:lastTimeDate];
  58. int days = ((int)time)/(3600*24);
  59. if (days < 15) {
  60. return NO;
  61. }
  62. }
  63. #endif
  64. return YES;
  65. }
  66. + (void)showExpiredInfo {
  67. if (ActivityStatusTrialExpire == [VerificationManager manager].status) {
  68. if ([KMVerificationWindowController allowsShowExpired]) {
  69. KMVerificationWindowController *vc = [KMVerificationWindowController verificationWithType:KMVerificationTypeTrialExpired];
  70. [vc showWindow:nil];
  71. [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"kVerificationExpiredShowLastTimeDateKay"];
  72. [[NSUserDefaults standardUserDefaults] synchronize];
  73. }
  74. } else if (ActivityStatusVerifExpire == [VerificationManager manager].status) {
  75. if ([KMVerificationWindowController allowsShowExpired]) {
  76. KMVerificationWindowController *vc = [KMVerificationWindowController verificationWithType:KMVerificationTypeActivateExpired];
  77. [vc showWindow:nil];
  78. [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"kVerificationExpiredShowLastTimeDateKay"];
  79. [[NSUserDefaults standardUserDefaults] synchronize];
  80. }
  81. }
  82. }
  83. + (BOOL)allowRepeatTrialAlertShow {
  84. //是否在开启APP时弹出二次试用弹窗提示框
  85. if ([VerificationManager manager].secondTrialEnabled) {
  86. if (![[NSUserDefaults standardUserDefaults] objectForKey:@"allowRepeatTrialAlertShowKey"]) {
  87. return YES;
  88. }
  89. }
  90. return NO;
  91. }
  92. + (BOOL)allowRepeatTrialExpireShow {
  93. if ([VerificationManager manager].status == ActivityStatusTrialExpire &&
  94. [VerificationManager manager].trialTimes == 2) {
  95. if (![[NSUserDefaults standardUserDefaults] objectForKey:@"allowRepeatTrialExpireShowKey"]) {
  96. return YES;
  97. }
  98. }
  99. return NO;
  100. }
  101. static KMVerificationWindowController *_currentWindowController = nil;
  102. + (KMVerificationWindowController *)verificationWithType:(KMVerificationType)type {
  103. if (_currentWindowController) {
  104. if (type != _currentWindowController.type) {
  105. [_currentWindowController close];
  106. } else {
  107. return _currentWindowController;
  108. }
  109. }
  110. KMVerificationWindowController *vc = [[KMVerificationWindowController alloc] initWithType:type];
  111. return vc;
  112. }
  113. #pragma mark Init Methods
  114. - (instancetype)initWithType:(KMVerificationType)type {
  115. if (self = [super initWithWindowNibName:@"KMVerificationWindowController"]) {
  116. _type = type;
  117. }
  118. return self;
  119. }
  120. - (void)dealloc {
  121. [NSDistributedNotificationCenter.defaultCenter removeObserver:self];
  122. }
  123. #pragma mark - Getter Methods
  124. - (KMVerificationViewController *)normalViewController {
  125. if (!_normalViewController) {
  126. __block __typeof(self) blockSelf = self;
  127. _normalViewController = [[KMVerificationViewController alloc] init];
  128. _normalViewController.callback = ^(NSInteger index) {
  129. if (index == 0) {
  130. [blockSelf setContentView:blockSelf.activateViewController.view];
  131. } else if (index == 1) {
  132. if (KMVerificationTypeActivateExpired == self.type) {
  133. [blockSelf verificationFeedback];
  134. } else {
  135. [blockSelf close];
  136. }
  137. } else {
  138. [blockSelf verificationBuy];
  139. }
  140. };
  141. if (KMVerificationTypeTrialExpired == self.type) {
  142. _normalViewController.titleText = NSLocalizedString(@"Thank you for trying PDFTech Editor", nil);
  143. _normalViewController.messageText = NSLocalizedString(@"Your trial has expired. Buy Full version to annotate and edit PDF files.", nil);
  144. } else {
  145. _normalViewController.titleText = NSLocalizedString(@"LynxPDF Editor Activation", nil);
  146. _normalViewController.messageText = NSLocalizedString(@"Buy Full Version to annotate and edit your PDF documents.", nil);
  147. }
  148. }
  149. return _normalViewController;
  150. }
  151. - (KMVerificationActivateViewController *)activateViewController {
  152. if (!_activateViewController) {
  153. __block __typeof(self) blockSelf = self;
  154. _activateViewController = [[KMVerificationActivateViewController alloc] init];
  155. _activateViewController.callback = ^(NSInteger index, NSString *string) {
  156. if (index == 0) {
  157. if (blockSelf.callback) {
  158. blockSelf.callback();
  159. blockSelf.callback = nil;
  160. [blockSelf close];
  161. } else {
  162. if (KMVerificationTypeTrial == blockSelf.type) {
  163. [blockSelf setContentView:blockSelf.trialViewController.view];
  164. } else if (KMVerificationTypeActivateExpired == blockSelf.type) {
  165. [blockSelf setContentView:blockSelf.expiredViewController.view];
  166. } else {
  167. [blockSelf setContentView:blockSelf.normalViewController.view];
  168. }
  169. }
  170. } else {
  171. if (blockSelf.type == KMVerificationTypeActivateAIInfo) {
  172. [blockSelf verificationActivateAIInfo:string];
  173. } else {
  174. [blockSelf verificationActivate:string];
  175. }
  176. }
  177. };
  178. if (self.type == KMVerificationTypeActivateAIInfo) {
  179. _activateViewController.type = self.type;
  180. }
  181. }
  182. return _activateViewController;
  183. }
  184. - (KMVerificationExpiredViewController *)expiredViewController {
  185. if (!_expiredViewController) {
  186. __block __typeof(self) blockSelf = self;
  187. _expiredViewController = [[KMVerificationExpiredViewController alloc] init];
  188. _expiredViewController.callback = ^(NSInteger index) {
  189. if (index == 0) {
  190. [blockSelf setContentView:blockSelf.activateViewController.view];
  191. } else {
  192. [blockSelf verificationFeedback];
  193. }
  194. };
  195. }
  196. return _expiredViewController;
  197. }
  198. - (KMVerificationTrialViewController *)trialViewController {
  199. if (!_trialViewController) {
  200. __block __typeof(self) blockSelf = self;
  201. _trialViewController = [[KMVerificationTrialViewController alloc] init];
  202. _trialViewController.callback = ^(NSInteger index, NSString *email, NSString *name) {
  203. if (index == 0) {
  204. [blockSelf setContentView:blockSelf.activateViewController.view];
  205. } else {
  206. [blockSelf verificationTrialForEmail:email name:name];
  207. }
  208. };
  209. }
  210. return _trialViewController;
  211. }
  212. - (KMVerificationAlertViewController *)alertViewController {
  213. if (!_alertViewController) {
  214. __block __typeof(self) blockSelf = self;
  215. _alertViewController = [[KMVerificationAlertViewController alloc] init];
  216. _alertViewController.callback = ^{
  217. [blockSelf close];
  218. };
  219. _alertViewController.buyActionHandle = ^{
  220. #if VERSION_DMG
  221. NSURL *url = [NSURL URLWithString:@"https://www.pdfreaderpro.com/store/pdftecheditor"];
  222. [[NSWorkspace sharedWorkspace] openURL:url];
  223. #endif
  224. [[FMTrackEventManager defaultManager] trackEventWithEvent:@"PUW" withProperties:@{@"PUW_Btn":@"Btn_PUW_BuyNow-Trial"}];
  225. [blockSelf close];
  226. };
  227. }
  228. return _alertViewController;
  229. }
  230. - (KMActivityALertViewController *)activityAlertViewController {
  231. if (!_activityAlertViewController) {
  232. __block __typeof(self) blockSelf = self;
  233. _activityAlertViewController = [[KMActivityALertViewController alloc] init];
  234. _activityAlertViewController.callback = ^{
  235. [blockSelf close];
  236. };
  237. }
  238. return _activityAlertViewController;
  239. }
  240. - (KMVerificationInfoViewController *)infoViewController {
  241. if (!_infoViewController) {
  242. __block __typeof(self) blockSelf = self;
  243. _infoViewController = [[KMVerificationInfoViewController alloc] init];
  244. _infoViewController.callback = ^{
  245. [blockSelf close];
  246. };
  247. _infoViewController.unbindAction = ^{
  248. dispatch_async(dispatch_get_main_queue(), ^{
  249. [blockSelf unbindAction];
  250. });
  251. };
  252. }
  253. return _infoViewController;
  254. }
  255. - (KMRepeatTrialAlertController *)repeatTrialAlertController {
  256. if (!_repeatTrialAlertController) {
  257. __block __typeof(self) blockSelf = self;
  258. _repeatTrialAlertController = [[KMRepeatTrialAlertController alloc] init];
  259. _repeatTrialAlertController.callback = ^(NSInteger clickIndex, KMRepeatTrialAlertController * _Nonnull tRController) {
  260. if (clickIndex == 0) {
  261. //免费试用
  262. [blockSelf verificationTrialForEmail:[VerificationManager manager].email
  263. name:[VerificationManager manager].accountName] ;
  264. } else if (clickIndex == 1) {
  265. //了解更多
  266. NSURL *url = [NSURL URLWithString:@"https://www.pdfreaderpro.com/store/pdftecheditor?utm_source=app_dmg&utm_medium=dmg_puw_sec_free_trial"];
  267. [[NSWorkspace sharedWorkspace] openURL:url];
  268. [blockSelf close];
  269. } else if (clickIndex == 2) {
  270. //输入序列码
  271. KMVerificationWindowController *vc = [KMVerificationWindowController verificationWithType:KMVerificationTypeActivate];
  272. vc.callback = ^{
  273. };
  274. [vc showWindow:nil];
  275. }
  276. };
  277. }
  278. return _repeatTrialAlertController;
  279. }
  280. - (KMRepeatVerifyExpireController *)repeatTrialExpireController {
  281. if (!_repeatTrialExpireController) {
  282. __block __typeof(self) blockSelf = self;
  283. _repeatTrialExpireController = [[KMRepeatVerifyExpireController alloc] init];
  284. _repeatTrialExpireController.callback = ^(NSInteger clickIndex, KMRepeatVerifyExpireController * _Nonnull tRController) {
  285. if (clickIndex == 0) {
  286. [blockSelf setContentView:blockSelf.activateViewController.view];
  287. } else if (clickIndex == 1) {
  288. [[FMTrackEventManager defaultManager] trackEventWithEvent:@"PUW" withProperties:@{@"PUW_Btn":@"Btn_PUW_SecondTrialExpire_Later"}];
  289. [blockSelf close];
  290. } else if (clickIndex == 2) {
  291. [[FMTrackEventManager defaultManager] trackEventWithEvent:@"PUW" withProperties:@{@"PUW_Btn":@"Btn_PUW_SecondTrialExpire_Buy"}];
  292. [blockSelf verificationBuy];
  293. }
  294. };
  295. }
  296. return _repeatTrialExpireController;
  297. }
  298. - (KMTrialSuccessController *)trialSuccessController {
  299. if (!_trialSuccessController) {
  300. __block __typeof(self) blockSelf = self;
  301. _trialSuccessController = [[KMTrialSuccessController alloc] init];
  302. _trialSuccessController.clickHandle = ^(KMTrialSuccessController * _Nonnull controller) {
  303. [blockSelf close];
  304. };
  305. }
  306. return _trialSuccessController;
  307. }
  308. #pragma mark Window Methods
  309. - (void)windowDidLoad {
  310. [super windowDidLoad];
  311. // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
  312. self.window.title = @"";
  313. [[self.window standardWindowButton:NSWindowZoomButton] setHidden:YES];
  314. [[self.window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
  315. [self updateViewInfo];
  316. [self updateViewColor];
  317. [NSDistributedNotificationCenter.defaultCenter addObserver:self selector:@selector(themeChanged:) name:@"AppleInterfaceThemeChangedNotification" object: nil];
  318. }
  319. - (void)updateViewInfo {
  320. if (KMVerificationTypeNormal == self.type) {
  321. [self setContentView:self.normalViewController.view];
  322. } else if (KMVerificationTypeActivate == self.type) {
  323. [self setContentView:self.activateViewController.view];
  324. } else if (KMVerificationTypeTrial == self.type) {
  325. [self setContentView:self.trialViewController.view];
  326. } else if (KMVerificationTypeActivateExpired == self.type) {
  327. [self setContentView:self.expiredViewController.view];
  328. } else if (KMVerificationTypeTrialExpired == self.type) {
  329. [self setContentView:self.normalViewController.view];
  330. } else if (KMVerificationTypeInfo == self.type) {
  331. [self setContentView:self.infoViewController.view];
  332. } else if (KMVerificationTypeRepeatTrialGuide == self.type) {
  333. self.window.title = @"";
  334. [self setContentView:self.repeatTrialAlertController.view];
  335. [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"allowRepeatTrialAlertShowKey"];
  336. [[NSUserDefaults standardUserDefaults] synchronize];
  337. } else if (KMVerificationTypeRepeatTrialExpire == self.type) {
  338. [self setContentView:self.repeatTrialExpireController.view];
  339. [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"allowRepeatTrialExpireShowKey"];
  340. [[NSUserDefaults standardUserDefaults] synchronize];
  341. } else if (self.type == KMVerificationTypeTrialSuccess ||
  342. self.type == KMVerificationTypeRepeatTrialSuccess) {
  343. [self setContentView:self.trialSuccessController.view];
  344. } else if (KMVerificationTypeActivateAIInfo == self.type) {
  345. [self setContentView:self.activateViewController.view];
  346. self.activateViewController.type = self.type;
  347. }
  348. }
  349. - (void)updateViewColor {
  350. if (KMVerificationTypeNormal == self.type) {
  351. } else if (KMVerificationTypeActivate == self.type) {
  352. } else if (KMVerificationTypeTrial == self.type) {
  353. } else if (KMVerificationTypeActivateExpired == self.type) {
  354. } else if (KMVerificationTypeTrialExpired == self.type) {
  355. } else if (KMVerificationTypeInfo == self.type) {
  356. } else if (KMVerificationTypeRepeatTrialGuide == self.type) {
  357. [self.repeatTrialAlertController updateViewColor];
  358. } else if (KMVerificationTypeRepeatTrialExpire == self.type) {
  359. [self.repeatTrialExpireController updateViewColor];
  360. } else if (KMVerificationTypeTrialSuccess == self.type ||
  361. KMVerificationTypeRepeatTrialSuccess == self.type) {
  362. [self.trialSuccessController updateViewColor];
  363. }
  364. }
  365. - (void)showWindow:(id)sender {
  366. if (!_currentWindowController) {
  367. _currentWindowController = self;
  368. }
  369. [super showWindow:sender];
  370. }
  371. - (void)windowWillClose:(NSNotification *)notification {
  372. if (_currentWindowController) {
  373. _currentWindowController = nil;
  374. }
  375. }
  376. #pragma mark - Setter
  377. - (void)setContentView:(NSView *)view {
  378. NSRect frame = self.window.frame;
  379. frame.origin.y -= view.frame.size.height-frame.size.height;
  380. frame.origin.x -= (view.frame.size.width-frame.size.width)/2.0;
  381. frame.size.width = view.frame.size.width;
  382. frame.size.height = view.frame.size.height;
  383. [self.box setContentView:view];
  384. [self.window setFrame:frame display:YES animate:YES];
  385. }
  386. #pragma mark - Private Methods
  387. - (void)verificationTrialForEmail:(NSString *)email name:(NSString *)name {
  388. if (email.length <= 0) {
  389. return;
  390. }
  391. if (![self isConnectionAvailable]) {
  392. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Connection Error", nil)
  393. defaultButton:NSLocalizedString(@"OK", nil)
  394. alternateButton:nil
  395. otherButton:nil
  396. informativeTextWithFormat:NSLocalizedString(@"Please make sure your internet connection is available.", nil), nil];
  397. [alert runModal];
  398. return;
  399. }
  400. __block __typeof(self) blockSelf = self;
  401. self.progressIndicator.hidden = NO;
  402. [self.progressIndicator startAnimation:nil];
  403. [self.trialViewController setEnabled:NO];
  404. [[VerificationManager manager] trialForDays:7 email:email name:name complention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  405. blockSelf.progressIndicator.hidden = YES;
  406. [blockSelf.progressIndicator stopAnimation:nil];
  407. [blockSelf.trialViewController setEnabled:YES];
  408. if (error ||
  409. status != ActivityStatusTrial) {
  410. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Activation Error", nil)
  411. defaultButton:NSLocalizedString(@"Try Again", nil)
  412. alternateButton:nil
  413. otherButton:nil
  414. informativeTextWithFormat:NSLocalizedString(@"Failed to sign up for the free trial. Please make sure your internet connection is available and try again later.", nil), nil];
  415. [alert runModal];
  416. } else {
  417. blockSelf.type = KMVerificationTypeTrialSuccess;
  418. [blockSelf updateViewInfo];
  419. }
  420. }];
  421. }
  422. - (void)verificationActivateAIInfo:(NSString *)license {
  423. if (license.length <= 0) {
  424. return;
  425. }
  426. if (![self isConnectionAvailable]) {
  427. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Connection Error", nil)
  428. defaultButton:NSLocalizedString(@"OK", nil)
  429. alternateButton:nil
  430. otherButton:nil
  431. informativeTextWithFormat:@"", nil];
  432. NSButton *accessryBtn = [[NSButton alloc] initWithFrame:CGRectMake(0, 0, 180, 44)];
  433. accessryBtn.autoresizingMask = NSViewMaxXMargin | NSViewMinYMargin | NSViewMaxYMargin;
  434. accessryBtn.bezelStyle = NSBezelStyleRegularSquare;
  435. accessryBtn.bordered = NO;
  436. accessryBtn.target = self;
  437. accessryBtn.action = @selector(accessryBtnClicked:);
  438. NSMutableAttributedString *mutAttrString = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"Please make sure your internet connection is available.", nil)];
  439. [mutAttrString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0, [mutAttrString length])];
  440. [mutAttrString addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:12] range:NSMakeRange(0, [mutAttrString length])];
  441. [mutAttrString addAttribute:NSForegroundColorAttributeName value:[KMAppearance KMColor_Interactive_M0] range:NSMakeRange(0, [mutAttrString length])];
  442. accessryBtn.attributedTitle = mutAttrString;
  443. NSRect rect = [mutAttrString boundingRectWithSize:CGSizeMake(180, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading];
  444. CGRect frame = accessryBtn.frame;
  445. frame.size.height = rect.size.height;
  446. accessryBtn.frame = frame;
  447. alert.accessoryView = accessryBtn;
  448. [alert runModal];
  449. return;
  450. }
  451. __block __typeof(self) blockSelf = self;
  452. self.progressIndicator.hidden = NO;
  453. [self.progressIndicator startAnimation:nil];
  454. [self.activateViewController setEnabled:NO];
  455. NSDictionary *infoDic = @{@"cdkey":license};
  456. [[AIInfoManager defaultManager] activateAIWithInfo:infoDic complention:^(NSDictionary *info, NSError *error) {
  457. blockSelf.progressIndicator.hidden = YES;
  458. [blockSelf.progressIndicator stopAnimation:nil];
  459. [blockSelf.activateViewController setEnabled:YES];
  460. if (error) {
  461. NSString *tTitle0 = NSLocalizedString(@"The license you have entered is not correct. Please enter valid license.", nil);
  462. NSString *tTitle1 = NSLocalizedString(@"Please confirm your PDFTech Editor AI license code through the email you provided when purchasing.", nil);
  463. NSString *message = [NSString stringWithFormat:@"%@\n\n%@", tTitle0, tTitle1];
  464. if (ActivityErrorTypeCDKeyEmpty == error.code) {
  465. message = [NSString stringWithFormat:@"%@\n\n%@", NSLocalizedString(@"License number can not be empty.", nil), @""];
  466. } else if (ActivityErrorTypeCDKeyNotExist == error.code) {
  467. message = [NSString stringWithFormat:@"%@\n\n%@", NSLocalizedString(@"License number does not exist.", nil), @""];
  468. } else if (ActivityErrorTypeOutNumber == error.code) {
  469. NSString *tMsg0 = NSLocalizedString(@"The devices connected to the license number has outnumbered.", nil);
  470. NSString *tMsg1 = NSLocalizedString(@"Please deactivate license on one of them, to use PDFTech Editor on this computer", nil);
  471. message = [NSString stringWithFormat:@"%@\n\n%@", tMsg0, tMsg1];
  472. } else if (ActivityErrorTypeNetworkDisable == error.code) {
  473. message = NSLocalizedString(@"The network is unavailable.", nil);
  474. } else if (ActivityErrorTypeCDKeyExpire == error.code) {
  475. message = NSLocalizedString(@"The license number expired.", nil);
  476. } else if (ActivityErrorTypeInvalidInfo == error.code) {
  477. message = NSLocalizedString(@"Activation error. Please try to input correct license, or contact us.", nil);
  478. } else if (ActivityErrorTypeNotMatchProduct == error.code) {
  479. message = NSLocalizedString(@"The license number is wrong, please input right license which is for this app.", nil);
  480. } else if (ActivityErrorTypeFormatError == error.code) {
  481. message = NSLocalizedString(@"Error license. Please enter an AI license.", nil);
  482. }
  483. if ((ActivityErrorTypeUnknow == error.code) || (ActivityErrorTypeOutNumber == error.code) || (ActivityErrorTypeInvalidInfo == error.code)) {
  484. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Activation Error", nil)
  485. defaultButton:NSLocalizedString(@"Contact Us", nil)
  486. alternateButton:NSLocalizedString(@"Try Again", nil)
  487. otherButton:nil
  488. informativeTextWithFormat:message, nil];
  489. if ([alert runModal]) {
  490. [blockSelf verificationFeedback];
  491. }
  492. } else {
  493. if (ActivityErrorTypeNetworkDisable == error.code) {
  494. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Connection Error", nil)
  495. defaultButton:NSLocalizedString(@"OK", nil)
  496. alternateButton:nil
  497. otherButton:nil
  498. informativeTextWithFormat:@"", nil];
  499. NSButton *accessryBtn = [[NSButton alloc] initWithFrame:CGRectMake(0, 0, 180, 44)];
  500. accessryBtn.autoresizingMask = NSViewMaxXMargin | NSViewMinYMargin | NSViewMaxYMargin;
  501. accessryBtn.bezelStyle = NSBezelStyleRegularSquare;
  502. accessryBtn.bordered = NO;
  503. accessryBtn.target = self;
  504. accessryBtn.action = @selector(accessryBtnClicked:);
  505. NSMutableAttributedString *mutAttrString = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"Please make sure your internet connection is available.", nil)];
  506. [mutAttrString addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:12] range:NSMakeRange(0, [mutAttrString length])];
  507. [mutAttrString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0, [mutAttrString length])];
  508. [mutAttrString addAttribute:NSForegroundColorAttributeName value:[KMAppearance KMColor_Interactive_M0] range:NSMakeRange(0, [mutAttrString length])];
  509. accessryBtn.attributedTitle = mutAttrString;
  510. NSRect rect = [mutAttrString boundingRectWithSize:CGSizeMake(180, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading];
  511. CGRect frame = accessryBtn.frame;
  512. frame.size.height = rect.size.height;
  513. accessryBtn.frame = frame;
  514. alert.accessoryView = accessryBtn;
  515. [alert runModal];
  516. } else {
  517. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Activation Error", nil)
  518. defaultButton:NSLocalizedString(@"Try Again", nil)
  519. alternateButton:nil
  520. otherButton:nil
  521. informativeTextWithFormat:message, nil];
  522. [alert runModal];
  523. }
  524. }
  525. } else {
  526. blockSelf.activityAlertViewController.alertTitle = NSLocalizedString(@"Successful Activation!", nil);
  527. blockSelf.activityAlertViewController.alertMessage = NSLocalizedString(@"Congratulations! You can start using PDFTech Editor AI features.", nil);
  528. [blockSelf setContentView:blockSelf.activityAlertViewController.view];
  529. }
  530. }];
  531. }
  532. - (void)verificationActivate:(NSString *)license {
  533. if (license.length <= 0) {
  534. return;
  535. }
  536. if ([license hasPrefix:@"AI-"]) {
  537. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Activation Error", nil)
  538. defaultButton:NSLocalizedString(@"Try Again", nil)
  539. alternateButton:nil
  540. otherButton:nil
  541. informativeTextWithFormat:NSLocalizedString(@"To activate the AI license code, click “AI Tools” on the toolbar, then tap “My AI Credit” from the right panel.", nil), nil];
  542. [alert runModal];
  543. return;
  544. }
  545. if (![self isConnectionAvailable]) {
  546. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Connection Error", nil)
  547. defaultButton:NSLocalizedString(@"OK", nil)
  548. alternateButton:nil
  549. otherButton:nil
  550. informativeTextWithFormat:@"", nil];
  551. NSButton *accessryBtn = [[NSButton alloc] initWithFrame:CGRectMake(0, 0, 180, 44)];
  552. accessryBtn.autoresizingMask = NSViewMaxXMargin | NSViewMinYMargin | NSViewMaxYMargin;
  553. accessryBtn.bezelStyle = NSBezelStyleRegularSquare;
  554. accessryBtn.bordered = NO;
  555. accessryBtn.target = self;
  556. accessryBtn.action = @selector(accessryBtnClicked:);
  557. NSMutableAttributedString *mutAttrString = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"Please make sure your internet connection is available.", nil)];
  558. [mutAttrString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0, [mutAttrString length])];
  559. [mutAttrString addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:12] range:NSMakeRange(0, [mutAttrString length])];
  560. [mutAttrString addAttribute:NSForegroundColorAttributeName value:[KMAppearance KMColor_Interactive_M0] range:NSMakeRange(0, [mutAttrString length])];
  561. accessryBtn.attributedTitle = mutAttrString;
  562. NSRect rect = [mutAttrString boundingRectWithSize:CGSizeMake(180, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading];
  563. CGRect frame = accessryBtn.frame;
  564. frame.size.height = rect.size.height;
  565. accessryBtn.frame = frame;
  566. alert.accessoryView = accessryBtn;
  567. [alert runModal];
  568. return;
  569. }
  570. __block __typeof(self) blockSelf = self;
  571. self.progressIndicator.hidden = NO;
  572. [self.progressIndicator startAnimation:nil];
  573. [self.activateViewController setEnabled:NO];
  574. NSDictionary *infoDic = @{@"cdkey":license};
  575. [[VerificationManager manager] activateDeviceWithInfo:infoDic complention:^(ActivityStatus status, NSDictionary *info, NSError *error) {
  576. blockSelf.progressIndicator.hidden = YES;
  577. [blockSelf.progressIndicator stopAnimation:nil];
  578. [blockSelf.activateViewController setEnabled:YES];
  579. if (error) {
  580. NSString *tTitle0 = NSLocalizedString(@"The license you have entered is not correct. Please enter valid license.", nil);
  581. NSString *tTitle1 = NSLocalizedString(@"If you have already purchased LynxPDF Editor for Mac, you should find your license in an email confirmation.", nil);
  582. NSString *message = [NSString stringWithFormat:@"%@\n\n%@", tTitle0, tTitle1];
  583. if (ActivityErrorTypeCDKeyEmpty == error.code) {
  584. message = [NSString stringWithFormat:@"%@\n\n%@", NSLocalizedString(@"License number can not be empty.", nil), @""];
  585. } else if (ActivityErrorTypeCDKeyNotExist == error.code) {
  586. message = [NSString stringWithFormat:@"%@\n\n%@", NSLocalizedString(@"License number does not exist.", nil), @""];
  587. } else if (ActivityErrorTypeOutNumber == error.code) {
  588. NSString *tMsg0 = NSLocalizedString(@"The devices connected to the license number has outnumbered.", nil);
  589. NSString *tMsg1 = NSLocalizedString(@"Please deactivate license on one of them, to use PDFTech Editor on this computer", nil);
  590. message = [NSString stringWithFormat:@"%@\n\n%@", tMsg0, tMsg1];
  591. } else if (ActivityErrorTypeNetworkDisable == error.code) {
  592. message = NSLocalizedString(@"The network is unavailable.", nil);
  593. } else if (ActivityErrorTypeCDKeyExpire == error.code) {
  594. message = NSLocalizedString(@"The license number expired.", nil);
  595. } else if (ActivityErrorTypeInvalidInfo == error.code) {
  596. message = NSLocalizedString(@"Activation error. Please try to input correct license, or contact us.", nil);
  597. } else if (ActivityErrorTypeNotMatchProduct == error.code) {
  598. message = NSLocalizedString(@"The license number is wrong, please input right license which is for this app.", nil);
  599. } else if (ActivityErrorTypeFormatError == error.code) {
  600. message = NSLocalizedString(@"The license format is wrong. Please input correct license.", nil);
  601. }
  602. if ((ActivityErrorTypeUnknow == error.code) || (ActivityErrorTypeOutNumber == error.code) || (ActivityErrorTypeInvalidInfo == error.code)) {
  603. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Activation Error", nil)
  604. defaultButton:NSLocalizedString(@"Contact Us", nil)
  605. alternateButton:NSLocalizedString(@"Try Again", nil)
  606. otherButton:nil
  607. informativeTextWithFormat:message, nil];
  608. if ([alert runModal]) {
  609. [blockSelf verificationFeedback];
  610. }
  611. } else {
  612. if (ActivityErrorTypeNetworkDisable == error.code) {
  613. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Connection Error", nil)
  614. defaultButton:NSLocalizedString(@"OK", nil)
  615. alternateButton:nil
  616. otherButton:nil
  617. informativeTextWithFormat:@"", nil];
  618. NSButton *accessryBtn = [[NSButton alloc] initWithFrame:CGRectMake(0, 0, 180, 44)];
  619. accessryBtn.autoresizingMask = NSViewMaxXMargin | NSViewMinYMargin | NSViewMaxYMargin;
  620. accessryBtn.bezelStyle = NSBezelStyleRegularSquare;
  621. accessryBtn.bordered = NO;
  622. accessryBtn.target = self;
  623. accessryBtn.action = @selector(accessryBtnClicked:);
  624. NSMutableAttributedString *mutAttrString = [[NSMutableAttributedString alloc] initWithString:NSLocalizedString(@"Please make sure your internet connection is available.", nil)];
  625. [mutAttrString addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:12] range:NSMakeRange(0, [mutAttrString length])];
  626. [mutAttrString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0, [mutAttrString length])];
  627. [mutAttrString addAttribute:NSForegroundColorAttributeName value:[KMAppearance KMColor_Interactive_M0] range:NSMakeRange(0, [mutAttrString length])];
  628. accessryBtn.attributedTitle = mutAttrString;
  629. NSRect rect = [mutAttrString boundingRectWithSize:CGSizeMake(180, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading];
  630. CGRect frame = accessryBtn.frame;
  631. frame.size.height = rect.size.height;
  632. accessryBtn.frame = frame;
  633. alert.accessoryView = accessryBtn;
  634. [alert runModal];
  635. } else {
  636. NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Activation Error", nil)
  637. defaultButton:NSLocalizedString(@"Try Again", nil)
  638. alternateButton:nil
  639. otherButton:nil
  640. informativeTextWithFormat:message, nil];
  641. [alert runModal];
  642. }
  643. }
  644. } else {
  645. blockSelf.activityAlertViewController.alertTitle = NSLocalizedString(@"Successful Activation!", nil);
  646. blockSelf.activityAlertViewController.alertMessage = NSLocalizedString(@"Congrats! You are eligible to enjoy all advanced features in LynxPDF Editor.", nil);
  647. [blockSelf setContentView:blockSelf.activityAlertViewController.view];
  648. }
  649. }];
  650. }
  651. - (void)verificationBuy {
  652. #if VERSION_DMG
  653. NSURL *url = [NSURL URLWithString:@"https://www.pdfreaderpro.com/store/pdftecheditor?utm_source=MacAppDmg&utm_campaign=StoreLink&utm_medium=PdfStore"];
  654. [[NSWorkspace sharedWorkspace] openURL:url];
  655. #endif
  656. }
  657. #pragma - 验证错误时反馈信息
  658. - (void)verificationFeedback {
  659. unsigned major, minor, bugFix;
  660. [self getSystemVersionMajor:&major minor:&minor bugFix:&bugFix];
  661. NSString *versionString = [NSString stringWithFormat:@"%@ - %u.%u.%u", [GBDeviceInfo deviceInfo].rawSystemInfoString, major, minor, bugFix];
  662. //application version (use short version preferentially)
  663. NSString *tAppVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
  664. if ([tAppVersion length] < 1) {
  665. tAppVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
  666. }
  667. NSString* subjects = [[self getAppNameForSupportEmail] stringByAppendingFormat:NSLocalizedString(@" - %@;Verification Feedback;%@", nil) ,tAppVersion,versionString];
  668. [KMMailHelper newEmailWithContacts:@"support@pdfreaderpro.com" andSubjects:subjects];
  669. }
  670. - (void)unbindAction {
  671. unsigned major, minor, bugFix;
  672. [self getSystemVersionMajor:&major minor:&minor bugFix:&bugFix];
  673. NSString *versionString = [NSString stringWithFormat:@"%@ - %u.%u.%u", [GBDeviceInfo deviceInfo].rawSystemInfoString, major, minor, bugFix];
  674. //application version (use short version preferentially)
  675. NSString *tAppVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
  676. if ([tAppVersion length] < 1) {
  677. tAppVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
  678. }
  679. NSString *subjects = [[self getAppNameForEmail] stringByAppendingString:[NSString stringWithFormat:@" %@",@"Verification:"]];
  680. subjects = [subjects stringByAppendingString:[NSString stringWithFormat:@"%@;",tAppVersion]];
  681. subjects = [subjects stringByAppendingString:[NSString stringWithFormat:@" %@;",versionString]];
  682. subjects = [subjects stringByAppendingString:[NSString stringWithFormat:@" %@",NSLocalizedString(@"Unbind License Code:", nil)]];
  683. subjects = [subjects stringByAppendingString:[NSString stringWithFormat:@"%@",[VerificationManager manager].detailInfo[@"device"][@"unique_sn"]?:@""]];
  684. NSString *mailtoAddress = [NSString stringWithFormat:@"mailto:%@?Subject=%@&body=%@",@"support@pdfreaderpro.com",[self URLEncodedString:subjects],[self URLEncodedString:NSLocalizedString(@"Hi PDF Technologies Team, I need to unbind my license code, thanks!\nNotice: Please do not modify the subtitle content", nil)]];
  685. [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:mailtoAddress]];
  686. }
  687. - (void)accessryBtnClicked:(NSButton *)btn {
  688. [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.pdfreaderpro.com/mac/help/activate-license-code-mac"]];
  689. }
  690. - (NSString *)URLEncodedString:(NSString *)string {
  691. CFStringRef stringRef = CFBridgingRetain(string);
  692. #pragma clang diagnostic push
  693. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  694. CFStringRef encoded = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
  695. stringRef,
  696. NULL,
  697. CFSTR("!*'\"();:@&=+$,/?%#[]% "),
  698. kCFStringEncodingUTF8);
  699. #pragma clang diagnostic pop
  700. CFRelease(stringRef);
  701. return CFBridgingRelease(encoded);
  702. }
  703. - (void)getSystemVersionMajor:(unsigned *)major
  704. minor:(unsigned *)minor
  705. bugFix:(unsigned *)bugFix {
  706. OSErr err;
  707. SInt32 systemVersion, versionMajor, versionMinor, versionBugFix;
  708. if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
  709. NSOperatingSystemVersion osSystemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
  710. *major = (unsigned)osSystemVersion.majorVersion;
  711. *minor = (unsigned)osSystemVersion.minorVersion;
  712. *bugFix = (unsigned)osSystemVersion.patchVersion;
  713. return;
  714. } else {
  715. #pragma clang diagnostic push
  716. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  717. if ((err = Gestalt(gestaltSystemVersion, &systemVersion)) != noErr) goto fail;
  718. if (systemVersion < 0x1040)
  719. {
  720. if (major) *major = ((systemVersion & 0xF000) >> 12) * 10 +
  721. ((systemVersion & 0x0F00) >> 8);
  722. if (minor) *minor = (systemVersion & 0x00F0) >> 4;
  723. if (bugFix) *bugFix = (systemVersion & 0x000F);
  724. }
  725. else
  726. {
  727. if ((err = Gestalt(gestaltSystemVersionMajor, &versionMajor)) != noErr) goto fail;
  728. if ((err = Gestalt(gestaltSystemVersionMinor, &versionMinor)) != noErr) goto fail;
  729. if ((err = Gestalt(gestaltSystemVersionBugFix, &versionBugFix)) != noErr) goto fail;
  730. if (major) *major = versionMajor;
  731. if (minor) *minor = versionMinor;
  732. if (bugFix) *bugFix = versionBugFix;
  733. }
  734. return;
  735. #pragma clang diagnostic pop
  736. }
  737. fail:
  738. NSLog(@"Unable to obtain system version: %ld", (long)err);
  739. if (major) *major = 10;
  740. if (minor) *minor = 0;
  741. if (bugFix) *bugFix = 0;
  742. }
  743. - (NSString *)getAppNameForEmail {
  744. NSString *tAppName = @"LynxPDF Editor Mac";
  745. return tAppName;
  746. }
  747. - (NSString *)getAppNameForSupportEmail {
  748. NSString *tAppName = @"LynxPDF Editor";
  749. #if VERSION_FREE
  750. #if VERSION_DMG
  751. // 桌机版
  752. VerificationManager *tManager = [VerificationManager manager];
  753. switch ([tManager status]) {
  754. case ActivityStatusTrial:
  755. tAppName = @"LynxPDF Editor Mac Trial";
  756. break;
  757. case ActivityStatusVerification:
  758. tAppName = @"LynxPDF Editor Mac Verification";
  759. break;
  760. case ActivityStatusTrialExpire:
  761. tAppName = @"LynxPDF Editor Mac TrialExpire";
  762. break;
  763. case ActivityStatusVerifExpire:
  764. tAppName = @"LynxPDF Editor Mac VerifExpire";
  765. break;
  766. default:
  767. break;
  768. }
  769. #else
  770. // AppStore 免费版本
  771. tAppName = @"LynxPDF Editor Lite";
  772. #endif
  773. #else
  774. // AppStore 付费版
  775. tAppName = @"LynxPDF Editor Edition";
  776. #endif
  777. return tAppName;
  778. }
  779. - (BOOL)isConnectionAvailable {
  780. BOOL isExistenceNetwork = YES;
  781. Reachability *reach = [Reachability reachabilityWithHostname:@"www.apple.com"];
  782. switch ([reach currentReachabilityStatus]) {
  783. case NotReachable:
  784. isExistenceNetwork = NO;
  785. //NSLog(@"notReachable");
  786. break;
  787. case ReachableViaWiFi:
  788. isExistenceNetwork = YES;
  789. //NSLog(@"WIFI");
  790. break;
  791. case ReachableViaWWAN:
  792. isExistenceNetwork = YES;
  793. //NSLog(@"3G");
  794. break;
  795. }
  796. if (NotReachable == [[Reachability reachabilityForInternetConnection] currentReachabilityStatus]) {
  797. return NO;
  798. }
  799. return YES;
  800. }
  801. #pragma mark - NSNotification
  802. - (void)themeChanged:(NSNotification *)notification {
  803. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  804. [self updateViewColor];
  805. });
  806. }
  807. + (void)verificationFeedback {
  808. unsigned major, minor, bugFix;
  809. [self getSystemVersionMajor:&major minor:&minor bugFix:&bugFix];
  810. NSString *versionString = [NSString stringWithFormat:@"%@ - %u.%u.%u", [GBDeviceInfo deviceInfo].rawSystemInfoString, major, minor, bugFix];
  811. NSString *tAppVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
  812. if ([tAppVersion length] < 1)
  813. {
  814. tAppVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
  815. }
  816. NSString* subjects = [[self getAppNameForSupportEmail] stringByAppendingFormat:NSLocalizedString(@" - %@;Verification Feedback;%@", nil) ,tAppVersion,versionString];
  817. [KMMailHelper newEmailWithContacts:@"support@pdfreaderpro.com" andSubjects:subjects];
  818. }
  819. + (void)getSystemVersionMajor:(unsigned *)major
  820. minor:(unsigned *)minor
  821. bugFix:(unsigned *)bugFix;
  822. {
  823. OSErr err;
  824. SInt32 systemVersion, versionMajor, versionMinor, versionBugFix;
  825. if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) {
  826. NSOperatingSystemVersion osSystemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
  827. *major = (unsigned)osSystemVersion.majorVersion;
  828. *minor = (unsigned)osSystemVersion.minorVersion;
  829. *bugFix = (unsigned)osSystemVersion.patchVersion;
  830. return;
  831. } else {
  832. #pragma clang diagnostic push
  833. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  834. if ((err = Gestalt(gestaltSystemVersion, &systemVersion)) != noErr) goto fail;
  835. if (systemVersion < 0x1040)
  836. {
  837. if (major) *major = ((systemVersion & 0xF000) >> 12) * 10 +
  838. ((systemVersion & 0x0F00) >> 8);
  839. if (minor) *minor = (systemVersion & 0x00F0) >> 4;
  840. if (bugFix) *bugFix = (systemVersion & 0x000F);
  841. }
  842. else
  843. {
  844. if ((err = Gestalt(gestaltSystemVersionMajor, &versionMajor)) != noErr) goto fail;
  845. if ((err = Gestalt(gestaltSystemVersionMinor, &versionMinor)) != noErr) goto fail;
  846. if ((err = Gestalt(gestaltSystemVersionBugFix, &versionBugFix)) != noErr) goto fail;
  847. if (major) *major = versionMajor;
  848. if (minor) *minor = versionMinor;
  849. if (bugFix) *bugFix = versionBugFix;
  850. }
  851. return;
  852. #pragma clang diagnostic pop
  853. }
  854. fail:
  855. NSLog(@"Unable to obtain system version: %ld", (long)err);
  856. if (major) *major = 10;
  857. if (minor) *minor = 0;
  858. if (bugFix) *bugFix = 0;
  859. }
  860. + (NSString *)getAppNameForSupportEmail
  861. {
  862. NSString *tAppName = @"LynxPDF Editor";
  863. #if VERSION_FREE
  864. #if VERSION_DMG
  865. // 桌机版
  866. VerificationManager *tManager = [VerificationManager manager];
  867. switch ([tManager status]) {
  868. case ActivityStatusTrial:
  869. tAppName = @"LynxPDF Editor Trial";
  870. break;
  871. case ActivityStatusVerification:
  872. tAppName = @"LynxPDF Editor Verification";
  873. break;
  874. case ActivityStatusTrialExpire:
  875. tAppName = @"LynxPDF Editor TrialExpire";
  876. break;
  877. case ActivityStatusVerifExpire:
  878. tAppName = @"LynxPDF Editor VerifExpire";
  879. break;
  880. default:
  881. break;
  882. }
  883. #else
  884. // AppStore 免费版本
  885. tAppName = @"LynxPDF Editor Lite";
  886. #endif
  887. #else
  888. // AppStore 付费版
  889. tAppName = @"LynxPDF Editor Edition";
  890. #endif
  891. return tAppName;
  892. }
  893. @end