Show app update nag on launch if necessary.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-07-04 13:24:25 -04:00
parent 8e891eb357
commit 944cd7beef
7 changed files with 155 additions and 1 deletions

View File

@ -5,6 +5,7 @@ target 'Signal' do
pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git'
pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git'
#pod 'AxolotlKit', path: '../SignalProtocolKit'
pod 'ATAppUpdater'
pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git'
#pod 'SignalServiceKit', path: '../SignalServiceKit'
pod 'JSQMessagesViewController', git: 'https://github.com/WhisperSystems/JSQMessagesViewController.git', branch: 'mkirk/retain-keyboard-view'

View File

@ -15,6 +15,7 @@ PODS:
- AFNetworking/Serialization (3.1.0)
- AFNetworking/UIKit (3.1.0):
- AFNetworking/NSURLSession
- ATAppUpdater (2.0)
- AxolotlKit (0.8.1):
- 25519 (~> 2.0.1)
- CocoaLumberjack
@ -108,6 +109,7 @@ PODS:
- YapDatabase/SQLCipher/Core
DEPENDENCIES:
- ATAppUpdater
- AxolotlKit (from `https://github.com/WhisperSystems/SignalProtocolKit.git`)
- JSQMessagesViewController (from `https://github.com/WhisperSystems/JSQMessagesViewController.git`, branch `mkirk/retain-keyboard-view`)
- PureLayout
@ -143,6 +145,7 @@ CHECKOUT OPTIONS:
SPEC CHECKSUMS:
'25519': dc4bad7e2dbcbf1efa121068a705a44cd98c80fc
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
ATAppUpdater: a9f7027060959d47e58733d3b48f6b9a28cb8de1
AxolotlKit: a9530d6835baae0f204b1f6b9dd79b7901176f0d
CocoaLumberjack: aa9dcab71bdf9eaf2a63bbd9ddc87863efe45457
HKDFKit: c058305d6f64b84f28c50bd7aa89574625bcb62a
@ -161,6 +164,6 @@ SPEC CHECKSUMS:
UnionFind: c33be5adb12983981d6e827ea94fc7f9e370f52d
YapDatabase: cd911121580ff16675f65ad742a9eb0ab4d9e266
PODFILE CHECKSUM: 01734aea935bf91b25ee9aed90e20403075e5d19
PODFILE CHECKSUM: 5a4ab8a8b4bcbf3a032e42a049de98dba8a3c8d2
COCOAPODS: 1.2.1

View File

@ -73,6 +73,7 @@
34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */; };
34B3F89F1E8DF5490035BE1A /* OWSTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */; };
34B3F8A21E8EA6040035BE1A /* ViewControllerUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8A11E8EA6040035BE1A /* ViewControllerUtils.m */; };
34CCAF381F0C0599004084F4 /* AppUpdateNag.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CCAF371F0C0599004084F4 /* AppUpdateNag.m */; };
34D5CC961EA6AFAD005515DB /* OWSContactsSyncing.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CC951EA6AFAD005515DB /* OWSContactsSyncing.m */; };
34D5CCA91EAE3D30005515DB /* GroupViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCA81EAE3D30005515DB /* GroupViewHelper.m */; };
34D5CCB11EAE7E7F005515DB /* SelectRecipientViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCB01EAE7E7F005515DB /* SelectRecipientViewController.m */; };
@ -480,6 +481,8 @@
34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSTableViewController.m; sourceTree = "<group>"; };
34B3F8A01E8EA6040035BE1A /* ViewControllerUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewControllerUtils.h; sourceTree = "<group>"; };
34B3F8A11E8EA6040035BE1A /* ViewControllerUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllerUtils.m; sourceTree = "<group>"; };
34CCAF361F0C0599004084F4 /* AppUpdateNag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppUpdateNag.h; sourceTree = "<group>"; };
34CCAF371F0C0599004084F4 /* AppUpdateNag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppUpdateNag.m; sourceTree = "<group>"; };
34D5CC941EA6AFAD005515DB /* OWSContactsSyncing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactsSyncing.h; sourceTree = "<group>"; };
34D5CC951EA6AFAD005515DB /* OWSContactsSyncing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactsSyncing.m; sourceTree = "<group>"; };
34D5CC981EA6EB79005515DB /* OWSMessageCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageCollectionViewCell.h; sourceTree = "<group>"; };
@ -1318,6 +1321,8 @@
B68EF9B51C0B1E7D009C3DCD /* Animated GIFS */,
B6DA6B051B8A2F9A00CA6F98 /* AppStoreRating.h */,
B6DA6B061B8A2F9A00CA6F98 /* AppStoreRating.m */,
34CCAF361F0C0599004084F4 /* AppUpdateNag.h */,
34CCAF371F0C0599004084F4 /* AppUpdateNag.m */,
76EB04CF18170B33006006FC /* collections */,
B90418E4183E9DD40038554A /* DateUtil.h */,
B90418E5183E9DD40038554A /* DateUtil.m */,
@ -2098,6 +2103,7 @@
4542F0961EBB9E9A00C7EE92 /* Promise+retainUntilComplete.swift in Sources */,
4516E3FF1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */,
4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
34CCAF381F0C0599004084F4 /* AppUpdateNag.m in Sources */,
45387B041E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.m in Sources */,
EF764C351DB67CC5000D9A87 /* UIViewController+CameraPermissions.m in Sources */,
45CD81EF1DC030E7004C9430 /* AccountManager.swift in Sources */,

View File

@ -4,6 +4,7 @@
#import "AppDelegate.h"
#import "AppStoreRating.h"
#import "AppUpdateNag.h"
#import "CodeVerificationViewController.h"
#import "DebugLogger.h"
#import "Environment.h"
@ -53,6 +54,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
@end
#pragma mark -
@implementation AppDelegate
- (void)applicationDidEnterBackground:(UIApplication *)application {
@ -805,6 +808,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
navigationController.navigationBarHidden = YES;
self.window.rootViewController = navigationController;
}
[AppUpdateNag.sharedInstance showAppUpgradeNagIfNecessary];
}
#pragma mark - Logging

View File

@ -0,0 +1,13 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
@interface AppUpdateNag : NSObject
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)sharedInstance;
- (void)showAppUpgradeNagIfNecessary;
@end

View File

@ -0,0 +1,117 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "AppUpdateNag.h"
#import <ATAppUpdater/ATAppUpdater.h>
#import <SignalServiceKit/TSStorageManager.h>
NSString *const TSStorageManagerAppUpgradeNagCollection = @"TSStorageManagerAppUpgradeNagCollection";
NSString *const TSStorageManagerAppUpgradeNagDate = @"TSStorageManagerAppUpgradeNagDate";
@interface AppUpdateNag () <ATAppUpdaterDelegate>
@property (nonatomic, readonly) TSStorageManager *storageManager;
@end
#pragma mark -
@implementation AppUpdateNag
+ (instancetype)sharedInstance
{
static AppUpdateNag *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] initDefault];
});
return sharedInstance;
}
- (instancetype)initDefault
{
TSStorageManager *storageManager = [TSStorageManager sharedManager];
return [self initWithStorageManager:storageManager];
}
- (instancetype)initWithStorageManager:(TSStorageManager *)storageManager
{
self = [super init];
if (!self) {
return self;
}
OWSAssert(storageManager);
_storageManager = storageManager;
OWSSingletonAssert();
return self;
}
- (void)showAppUpgradeNagIfNecessary
{
NSDate *lastNagDate = [[TSStorageManager sharedManager] dateForKey:TSStorageManagerAppUpgradeNagDate
inCollection:TSStorageManagerAppUpgradeNagCollection];
const NSTimeInterval kMinute = 60.f;
const NSTimeInterval kHour = 60 * kMinute;
const NSTimeInterval kDay = 24 * kHour;
const NSTimeInterval kNagFrequency = kDay * 14;
BOOL canNag = (!lastNagDate || fabs(lastNagDate.timeIntervalSinceNow) > kNagFrequency);
if (!canNag) {
return;
}
// NOTE: The iTunes app store API exposes "short" version numbers, so
// it isn't possible to nag about hotfix releases.
ATAppUpdater *updater = [ATAppUpdater sharedUpdater];
[updater setAlertTitle:NSLocalizedString(
@"APP_UPDATE_NAG_ALERT_TITLE", @"Title for the 'new app version available' alert.")];
[updater setAlertMessage:NSLocalizedString(@"APP_UPDATE_NAG_ALERT_MESSAGE_FORMAT",
@"Message format for the 'new app version available' alert. Embeds: {{The latest app "
@"version number.}}.")];
[updater setAlertUpdateButtonTitle:NSLocalizedString(@"APP_UPDATE_NAG_ALERT_UPDATE_BUTTON",
@"Label for the 'update' button in the 'new app version available' alert.")];
[updater setAlertCancelButtonTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"")];
[updater setDelegate:self];
[updater showUpdateWithConfirmation];
}
#pragma mark - ATAppUpdaterDelegate
- (void)appUpdaterDidShowUpdateDialog
{
DDLogInfo(@"%@ %s", self.tag, __PRETTY_FUNCTION__);
[[TSStorageManager sharedManager] setDate:[NSDate new]
forKey:TSStorageManagerAppUpgradeNagDate
inCollection:TSStorageManagerAppUpgradeNagCollection];
}
- (void)appUpdaterUserDidLaunchAppStore
{
DDLogInfo(@"%@ %s", self.tag, __PRETTY_FUNCTION__);
}
- (void)appUpdaterUserDidCancel
{
DDLogInfo(@"%@ %s", self.tag, __PRETTY_FUNCTION__);
}
#pragma mark - Logging
+ (NSString *)tag
{
return [NSString stringWithFormat:@"[%@]", self.class];
}
- (NSString *)tag
{
return self.class.tag;
}
@end

View File

@ -55,6 +55,15 @@
/* No comment provided by engineer. */
"APN_MESSAGE_IN_GROUP_DETAILED" = "%@ in group %@: %@";
/* Message format for the 'new app version available' alert. Embeds: {{The latest app version number.}}. */
"APP_UPDATE_NAG_ALERT_MESSAGE_FORMAT" = "Version %@ is available in the App Store.";
/* Title for the 'new app version available' alert. */
"APP_UPDATE_NAG_ALERT_TITLE" = "New Version";
/* Label for the 'update' button in the 'new app version available' alert. */
"APP_UPDATE_NAG_ALERT_UPDATE_BUTTON" = "Update";
/* Name of application */
"APPLICATION_NAME" = "Signal";