UserReminder.m 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // _____ _
  2. // |_ _| |_ _ _ ___ ___ _ __ __ _
  3. // | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. // |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. //
  6. // Threema iOS Client
  7. // Copyright (c) 2013-2020 Threema GmbH
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU Affero General Public License, version 3,
  11. // as published by the Free Software Foundation.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU Affero General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Affero General Public License
  19. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. #import "UserReminder.h"
  21. #import "UIDefines.h"
  22. #import "MyIdentityViewController.h"
  23. #import "MyIdentityStore.h"
  24. #import "AppDelegate.h"
  25. #import "AppGroup.h"
  26. #import <UserNotifications/UserNotifications.h>
  27. #ifdef DEBUG
  28. static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
  29. #else
  30. static const DDLogLevel ddLogLevel = DDLogLevelWarning;
  31. #endif
  32. #define kLinkReminderTime 2*86400
  33. #define kPublicNicknameReminderTime 3*86400
  34. #define kPushReminderTime 900
  35. #define kPushReminderInterval 1*86400
  36. @implementation UserReminder {
  37. }
  38. + (UserReminder*)sharedUserReminder {
  39. static UserReminder *instance;
  40. @synchronized (self) {
  41. if (!instance)
  42. instance = [[UserReminder alloc] init];
  43. }
  44. return instance;
  45. }
  46. - (void)checkReminders:(void(^)(BOOL check))onCompletion {
  47. if (![[MyIdentityStore sharedMyIdentityStore] isProvisioned]) {
  48. DDLogVerbose(@"Not provisioned - no reminders to show");
  49. onCompletion(false);
  50. }
  51. /* Push reminder: check that push registration was successful */
  52. [self checkPushReminder:^(BOOL check) {
  53. if (check == true) {
  54. onCompletion(true);
  55. return;
  56. }
  57. onCompletion(false);
  58. return;
  59. }];
  60. }
  61. - (void)isPushEnabled:(void(^)(BOOL isEnabled))onCompletion {
  62. UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  63. [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
  64. //1. Query the authorization status of the UNNotificationSettings object
  65. switch (settings.authorizationStatus) {
  66. case UNAuthorizationStatusAuthorized:
  67. onCompletion(true);
  68. break;
  69. case UNAuthorizationStatusDenied:
  70. onCompletion(false);
  71. break;
  72. case UNAuthorizationStatusNotDetermined:
  73. onCompletion(false);
  74. break;
  75. default:
  76. onCompletion(false);
  77. break;
  78. }
  79. }];
  80. }
  81. - (void)checkPushReminder:(void(^)(BOOL check))onCompletion {
  82. [self isPushEnabled:^(BOOL isEnabled) {
  83. /* push enabled? */
  84. if (isEnabled) {
  85. DDLogVerbose(@"Push notifications are enabled");
  86. onCompletion(false);
  87. return;
  88. }
  89. /* less than 15 minutes after identity creation? Give user a chance to accept pushes first */
  90. NSDate *targetDate = [[self idCreationDate] dateByAddingTimeInterval:kPushReminderTime];
  91. if ([targetDate compare:[NSDate date]] == NSOrderedDescending) {
  92. DDLogVerbose(@"Push reminder: not time to show yet");
  93. onCompletion(false);
  94. return;
  95. }
  96. /* already shown? */
  97. NSDate *lastShow = [[AppGroup userDefaults] objectForKey:@"PushReminderShowDate"];
  98. BOOL doNotShowAgain = [[AppGroup userDefaults] boolForKey:@"PushReminderDoNotShowAgain"];
  99. if ((lastShow != nil && -[lastShow timeIntervalSinceNow] < kPushReminderInterval) || doNotShowAgain == true) {
  100. DDLogVerbose(@"Push reminder already shown");
  101. onCompletion(false);
  102. return;
  103. }
  104. /* time to show the reminder */
  105. UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"push_reminder_title", nil) message:NSLocalizedString(@"push_reminder_message", nil) preferredStyle:UIAlertControllerStyleAlert];
  106. [alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"ok", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
  107. }]];
  108. [alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"safe_intro_cancel", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
  109. [[AppGroup userDefaults] setBool:true forKey:@"PushReminderDoNotShowAgain"];
  110. }]];
  111. dispatch_async(dispatch_get_main_queue(), ^{
  112. [[[AppDelegate sharedAppDelegate] currentTopViewController] presentViewController:alert animated:YES completion:nil];
  113. });
  114. [[AppGroup userDefaults] setObject:[NSDate date] forKey:@"PushReminderShowDate"];
  115. onCompletion(true);
  116. return;
  117. }];
  118. }
  119. - (void)markIdentityDeleted {
  120. [[AppGroup userDefaults] removeObjectForKey:@"LinkReminderShown"];
  121. [[AppGroup userDefaults] removeObjectForKey:@"PublicNicknameReminderShown"];
  122. [[AppGroup userDefaults] removeObjectForKey:@"IdentityCreationDate"];
  123. [[AppGroup userDefaults] removeObjectForKey:@"PushReminderDoNotShowAgain"];
  124. }
  125. - (NSDate*)idCreationDate {
  126. NSDate *idCreateDate = [[AppGroup userDefaults] objectForKey:@"IdentityCreationDate"];
  127. if (idCreateDate == nil) {
  128. /* not available - put in current date */
  129. DDLogVerbose(@"Init with current date");
  130. idCreateDate = [NSDate date];
  131. [[AppGroup userDefaults] setObject:idCreateDate forKey:@"IdentityCreationDate"];
  132. }
  133. return idCreateDate;
  134. }
  135. @end