iOS 8 Support
- Supporting iOS 8 - Updating translations - Rewriting PushManager to extensively use futures - Pick up calls directly from the lock-screen
This commit is contained in:
parent
8b42036f16
commit
cd0bda7105
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0510"
|
||||
LastUpgradeVersion = "0600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -39,6 +39,15 @@
|
|||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "A1B989631725EC1300B6E8B5"
|
||||
BuildableName = "libspandsp.a"
|
||||
BlueprintName = "spandsp"
|
||||
ReferencedContainer = "container:spandsp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0510"
|
||||
LastUpgradeVersion = "0600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -39,6 +39,15 @@
|
|||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "A1FDCBF916DBC57D00868894"
|
||||
BuildableName = "libspeex.a"
|
||||
BlueprintName = "speex"
|
||||
ReferencedContainer = "container:speex.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
|
|
4
Podfile
4
Podfile
|
@ -4,8 +4,8 @@ link_with ["Signal", "SignalTests"]
|
|||
|
||||
pod 'UICKeyChainStore', :podspec => 'Podspecs/UICKeyChainStore.podspec'
|
||||
pod 'OpenSSL', '~> 1.0.109'
|
||||
pod 'MMDrawerController', '~> 0.5.0'
|
||||
pod 'MMDrawerController', '~> 0.5.7'
|
||||
pod 'libPhoneNumber-iOS', '~> 0.7'
|
||||
pod 'PastelogKit', '~> 1.1'
|
||||
pod 'AFNetworking', '~> 2.3.1'
|
||||
pod 'AFNetworking', '~> 2.4.1'
|
||||
pod 'TwistedOakCollapsingFutures','~> 1.0'
|
||||
|
|
32
Podfile.lock
32
Podfile.lock
|
@ -1,23 +1,23 @@
|
|||
PODS:
|
||||
- AFNetworking (2.3.1):
|
||||
- AFNetworking (2.4.1):
|
||||
- AFNetworking/NSURLConnection
|
||||
- AFNetworking/NSURLSession
|
||||
- AFNetworking/Reachability
|
||||
- AFNetworking/Security
|
||||
- AFNetworking/Serialization
|
||||
- AFNetworking/UIKit
|
||||
- AFNetworking/NSURLConnection (2.3.1):
|
||||
- AFNetworking/NSURLConnection (2.4.1):
|
||||
- AFNetworking/Reachability
|
||||
- AFNetworking/Security
|
||||
- AFNetworking/Serialization
|
||||
- AFNetworking/NSURLSession (2.3.1):
|
||||
- AFNetworking/NSURLSession (2.4.1):
|
||||
- AFNetworking/Reachability
|
||||
- AFNetworking/Security
|
||||
- AFNetworking/Serialization
|
||||
- AFNetworking/Reachability (2.3.1)
|
||||
- AFNetworking/Security (2.3.1)
|
||||
- AFNetworking/Serialization (2.3.1)
|
||||
- AFNetworking/UIKit (2.3.1):
|
||||
- AFNetworking/Reachability (2.4.1)
|
||||
- AFNetworking/Security (2.4.1)
|
||||
- AFNetworking/Serialization (2.4.1)
|
||||
- AFNetworking/UIKit (2.4.1):
|
||||
- AFNetworking/NSURLConnection
|
||||
- AFNetworking/NSURLSession
|
||||
- CocoaLumberjack (1.9.2):
|
||||
|
@ -26,17 +26,17 @@ PODS:
|
|||
- CocoaLumberjack/Extensions (1.9.2):
|
||||
- CocoaLumberjack/Core
|
||||
- libPhoneNumber-iOS (0.7.3)
|
||||
- MMDrawerController (0.5.6):
|
||||
- MMDrawerController (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
- MMDrawerController/MMDrawerBarButtonItem
|
||||
- MMDrawerController/MMDrawerVisualStates
|
||||
- MMDrawerController/Subclass
|
||||
- MMDrawerController/Core (0.5.6)
|
||||
- MMDrawerController/MMDrawerBarButtonItem (0.5.6):
|
||||
- MMDrawerController/Core (0.5.7)
|
||||
- MMDrawerController/MMDrawerBarButtonItem (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
- MMDrawerController/MMDrawerVisualStates (0.5.6):
|
||||
- MMDrawerController/MMDrawerVisualStates (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
- MMDrawerController/Subclass (0.5.6):
|
||||
- MMDrawerController/Subclass (0.5.7):
|
||||
- MMDrawerController/Core
|
||||
- OpenSSL (1.0.109)
|
||||
- PastelogKit (1.1):
|
||||
|
@ -47,9 +47,9 @@ PODS:
|
|||
- UnionFind (1.0.1)
|
||||
|
||||
DEPENDENCIES:
|
||||
- AFNetworking (~> 2.3.1)
|
||||
- AFNetworking (~> 2.4.1)
|
||||
- libPhoneNumber-iOS (~> 0.7)
|
||||
- MMDrawerController (~> 0.5.0)
|
||||
- MMDrawerController (~> 0.5.7)
|
||||
- OpenSSL (~> 1.0.109)
|
||||
- PastelogKit (~> 1.1)
|
||||
- TwistedOakCollapsingFutures (~> 1.0)
|
||||
|
@ -60,10 +60,10 @@ EXTERNAL SOURCES:
|
|||
:podspec: Podspecs/UICKeyChainStore.podspec
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AFNetworking: 6d7b76aa5d04c8c37daad3eef4b7e3f2a7620da3
|
||||
AFNetworking: 0aabc6fae66d6e5d039eeb21c315843c7aae51ab
|
||||
CocoaLumberjack: 205769c032b5fef85b92472046bcc8b7e7c8a817
|
||||
libPhoneNumber-iOS: 98fc07d70c8fdb5e6a8e3442c37e97353065c20e
|
||||
MMDrawerController: 4bae84535ca7a5f4cb55a66a001e6035c3571677
|
||||
MMDrawerController: c3ab7a318ddc7e2bcd133139c3161af08c6e1197
|
||||
OpenSSL: 4810adf5c99b0e2cd20670a11a987c805e8a521c
|
||||
PastelogKit: 32836ec27e587a8876326abeaf9a1b5e2bc484ea
|
||||
TwistedOakCollapsingFutures: 07aab84fd3958dc94d55ef705b12857d9fbe61d1
|
||||
|
|
2
Pods
2
Pods
|
@ -1 +1 @@
|
|||
Subproject commit 5d4e467489501e0a8b76a3f636380e8f00296947
|
||||
Subproject commit 594aa6022c574bd1798041dd440af1aedc4d21b5
|
|
@ -396,6 +396,7 @@
|
|||
B6416FD4199A0478003C5699 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6416FAB199A0478003C5699 /* Localizable.strings */; };
|
||||
B67ADDC41989FF8700E1A773 /* CallServerRequestsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B67ADDC31989FF8700E1A773 /* CallServerRequestsManager.m */; };
|
||||
B67EBF5D19194AC60084CCFD /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B67EBF5C19194AC60084CCFD /* Settings.bundle */; };
|
||||
B684A46D19C3446200B11029 /* PushManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B684A46C19C3446200B11029 /* PushManagerTest.m */; };
|
||||
B6850E5A1995A4710068E715 /* whisperFake.cer in Resources */ = {isa = PBXBuildFile; fileRef = B6850E591995A4710068E715 /* whisperFake.cer */; };
|
||||
B69CD25119773E79005CE69A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B69CD25019773E79005CE69A /* XCTest.framework */; };
|
||||
B6B1013C196D213F007E3930 /* SGNKeychainUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B1013B196D213F007E3930 /* SGNKeychainUtil.m */; };
|
||||
|
@ -1098,6 +1099,7 @@
|
|||
B67ADDC21989FF8700E1A773 /* CallServerRequestsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallServerRequestsManager.h; sourceTree = "<group>"; };
|
||||
B67ADDC31989FF8700E1A773 /* CallServerRequestsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallServerRequestsManager.m; sourceTree = "<group>"; };
|
||||
B67EBF5C19194AC60084CCFD /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Settings.bundle; path = SettingsBundle/Settings.bundle; sourceTree = SOURCE_ROOT; };
|
||||
B684A46C19C3446200B11029 /* PushManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PushManagerTest.m; path = Signal/test/push/PushManagerTest.m; sourceTree = SOURCE_ROOT; };
|
||||
B6850E591995A4710068E715 /* whisperFake.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = whisperFake.cer; sourceTree = "<group>"; };
|
||||
B69CD25019773E79005CE69A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B6B1013A196D213F007E3930 /* SGNKeychainUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SGNKeychainUtil.h; sourceTree = "<group>"; };
|
||||
|
@ -2196,6 +2198,7 @@
|
|||
A157073917F0CD6D007C2BD6 /* Supporting Files */,
|
||||
A157073B17F0CD6D007C2BD6 /* TestUtil.h */,
|
||||
A157073C17F0CD6D007C2BD6 /* TestUtil.m */,
|
||||
B684A46C19C3446200B11029 /* PushManagerTest.m */,
|
||||
A157073D17F0CD6D007C2BD6 /* util */,
|
||||
);
|
||||
path = test;
|
||||
|
@ -3007,12 +3010,18 @@
|
|||
D221A088169C9E5E00537ABF = {
|
||||
DevelopmentTeam = U68MSDN6DR;
|
||||
SystemCapabilities = {
|
||||
com.apple.DataProtection = {
|
||||
enabled = 1;
|
||||
};
|
||||
com.apple.InAppPurchase = {
|
||||
enabled = 0;
|
||||
};
|
||||
com.apple.InterAppAudio = {
|
||||
enabled = 0;
|
||||
};
|
||||
com.apple.VPNLite = {
|
||||
enabled = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
D221A0A9169C9E5F00537ABF = {
|
||||
|
@ -3739,6 +3748,7 @@
|
|||
76EB066118170B34006006FC /* RegisterViewController.m in Sources */,
|
||||
76EB068D18170B34006006FC /* InboxFeedTableViewCell.m in Sources */,
|
||||
BFB074C119A4BCA400F2947C /* FutureUtilTest.m in Sources */,
|
||||
B684A46D19C3446200B11029 /* PushManagerTest.m in Sources */,
|
||||
76EB05A918170B33006006FC /* RtpSocket.m in Sources */,
|
||||
765052B0182AC9B5008313E1 /* DialerButtonView.m in Sources */,
|
||||
76EB062B18170B33006006FC /* BadState.m in Sources */,
|
||||
|
@ -4194,8 +4204,8 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = C71793B33D9C45079F74487E /* Pods.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
@ -4234,7 +4244,7 @@
|
|||
LLVM_LTO = NO;
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
PRODUCT_NAME = Signal;
|
||||
PROVISIONING_PROFILE = "036480DA-A21D-4CC6-BF48-98E8AE1EE981";
|
||||
PROVISIONING_PROFILE = "4aa31d4f-187c-470a-add6-8e949fc2cfd1";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TEST_AFTER_BUILD = YES;
|
||||
|
@ -4483,8 +4493,8 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = C71793B33D9C45079F74487E /* Pods.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
@ -4521,7 +4531,7 @@
|
|||
LLVM_LTO = NO;
|
||||
OTHER_LDFLAGS = "$(inherited)";
|
||||
PRODUCT_NAME = Signal;
|
||||
PROVISIONING_PROFILE = "7214A823-1F7A-4460-82D8-D89CA511CEA6";
|
||||
PROVISIONING_PROFILE = "4434E074-1111-40F0-A7B6-CEA8437ACFE1";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TEST_AFTER_BUILD = YES;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0510"
|
||||
LastUpgradeVersion = "0600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -29,13 +29,13 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.4</string>
|
||||
<string>1.0.5</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.4</string>
|
||||
<string>1.0.5</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string></string>
|
||||
<string>public.app-category.social-networking</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIAppFonts</key>
|
||||
|
@ -48,6 +48,7 @@
|
|||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
<string>fetch</string>
|
||||
<string>remote-notification</string>
|
||||
<string>voip</string>
|
||||
</array>
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
@property (nonatomic, strong) MMDrawerController *drawerController;
|
||||
@property (nonatomic, strong) NotificationTracker *notificationTracker;
|
||||
|
||||
@property (nonatomic) TOCFutureSource *callPickUpFuture;
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
@ -154,7 +156,18 @@
|
|||
|
||||
InCallViewController *callViewController = [InCallViewController inCallViewControllerWithCallState:latestCall
|
||||
andOptionallyKnownContact:latestCall.potentiallySpecifiedContact];
|
||||
|
||||
if (latestCall.initiatedLocally == false){
|
||||
[self.callPickUpFuture.future thenDo:^(NSNumber *accept) {
|
||||
if ([accept isEqualToNumber:@YES]) {
|
||||
[callViewController answerButtonTapped];
|
||||
} else if ([accept isEqualToNumber:@NO]){
|
||||
[callViewController rejectButtonTapped];
|
||||
}
|
||||
}];
|
||||
}
|
||||
[_drawerController.centerViewController presentViewController:callViewController animated:YES completion:nil];
|
||||
|
||||
} onThread:NSThread.mainThread untilCancelled:nil];
|
||||
|
||||
|
||||
|
@ -162,12 +175,15 @@
|
|||
}
|
||||
|
||||
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
|
||||
[PushManager.sharedManager registerForPushWithToken:deviceToken];
|
||||
[[PushManager sharedManager].pushNotificationFutureSource trySetResult:deviceToken];
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {
|
||||
[PushManager.sharedManager verifyPushActivated];
|
||||
DDLogError(@"Failed to register for push notifications: %@", error);
|
||||
[[PushManager sharedManager].pushNotificationFutureSource trySetFailure:error];
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
|
||||
[[PushManager sharedManager].userNotificationFutureSource trySetResult:notificationSettings];
|
||||
}
|
||||
|
||||
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
|
||||
|
@ -184,7 +200,7 @@
|
|||
DDLogError(@"Decryption of session descriptor failed");
|
||||
return;
|
||||
}
|
||||
|
||||
self.callPickUpFuture = [TOCFutureSource new];
|
||||
[Environment.phoneManager incomingCallWithSession:call];
|
||||
}
|
||||
|
||||
|
@ -207,11 +223,20 @@
|
|||
[self removeScreenProtection];
|
||||
|
||||
if (Environment.isRegistered) {
|
||||
[PushManager.sharedManager verifyPushActivated];
|
||||
[PushManager.sharedManager verifyPushPermissions];
|
||||
[AppAudioManager.sharedInstance requestRequiredPermissionsIfNeeded];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler{
|
||||
if ([identifier isEqualToString:Signal_Accept_Identifier]) {
|
||||
[self.callPickUpFuture trySetResult:@YES];
|
||||
} else if ([identifier isEqualToString:Signal_Decline_Identifier]){
|
||||
[self.callPickUpFuture trySetResult:@NO];
|
||||
}
|
||||
completionHandler();
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application{
|
||||
[self protectScreen];
|
||||
}
|
||||
|
|
|
@ -43,7 +43,11 @@
|
|||
|
||||
// Some users push IDs were not correctly registered, by precaution, we are going to re-register all of them
|
||||
|
||||
[PushManager.sharedManager askForPushRegistration];
|
||||
[PushManager.sharedManager registrationWithSuccess:^{
|
||||
|
||||
} failure:^{
|
||||
DDLogError(@"Error re-registering on migration from 1.0.2");
|
||||
}];
|
||||
|
||||
[[NSFileManager defaultManager] removeItemAtPath:path error:&error];
|
||||
|
||||
|
|
|
@ -6,19 +6,42 @@
|
|||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <TwistedOakCollapsingFutures/CollapsingFutures.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
#define Signal_Accept_Identifier @"Signal_Call_Accept"
|
||||
#define Signal_Decline_Identifier @"Signal_Call_Decline"
|
||||
|
||||
/**
|
||||
* The Push Manager is responsible for registering the device for Signal push notifications.
|
||||
*/
|
||||
|
||||
@interface PushManager : NSObject
|
||||
|
||||
+ (instancetype)sharedManager;
|
||||
|
||||
- (void)verifyPushActivated;
|
||||
/**
|
||||
* Push notification token is always registered during signup. User can however revoke notifications.
|
||||
* Therefore, we check on startup if mandatory permissions are granted.
|
||||
*/
|
||||
|
||||
- (void)askForPushRegistration;
|
||||
- (void)verifyPushPermissions;
|
||||
|
||||
- (void)askForPushRegistrationWithSuccess:(void (^)())success failure:(void (^)())failure;
|
||||
/**
|
||||
* Push notification registration method
|
||||
*
|
||||
* @param success Block to execute after succesful push notification registration
|
||||
* @param failure Block to executre if push notification registration fails
|
||||
*/
|
||||
|
||||
- (void)registerForPushWithToken:(NSData*)token;
|
||||
- (void)registrationWithSuccess:(void (^)())success failure:(void (^)())failure;
|
||||
|
||||
/**
|
||||
* The pushNotification and userNotificationFutureSource are accessed by the App Delegate after requested permissions.
|
||||
*/
|
||||
|
||||
@property TOCFutureSource *pushNotificationFutureSource;
|
||||
@property TOCFutureSource *userNotificationFutureSource;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
#import "PushManager.h"
|
||||
#import "Environment.h"
|
||||
#import "CallServerRequestsManager.h"
|
||||
#import "FutureUtil.h"
|
||||
|
||||
@interface PushManager ()
|
||||
|
||||
@property (nonatomic, copy) void (^PushRegisteringSuccessBlock)();
|
||||
@property (nonatomic, copy) void (^PushRegisteringFailureBlock)();
|
||||
@property TOCFutureSource *registerWithServerFutureSource;
|
||||
|
||||
@property int retries;
|
||||
@property UIAlertView *missingPermissionsAlertView;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -26,123 +26,209 @@
|
|||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedManager = [self new];
|
||||
sharedManager.missingPermissionsAlertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"ACTION_REQUIRED_TITLE", @"") message:NSLocalizedString(@"PUSH_SETTINGS_MESSAGE", @"") delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles:nil, nil];
|
||||
});
|
||||
return sharedManager;
|
||||
}
|
||||
|
||||
- (void)verifyPushActivated{
|
||||
UIRemoteNotificationType notificationTypes = [UIApplication.sharedApplication enabledRemoteNotificationTypes];
|
||||
- (void)verifyPushPermissions{
|
||||
|
||||
BOOL needsPushSettingChangeAlert = NO;
|
||||
|
||||
if (notificationTypes == UIRemoteNotificationTypeNone) {
|
||||
needsPushSettingChangeAlert = YES;
|
||||
} else if (notificationTypes == UIRemoteNotificationTypeBadge) {
|
||||
needsPushSettingChangeAlert = YES;
|
||||
} else if (notificationTypes == UIRemoteNotificationTypeAlert) {
|
||||
needsPushSettingChangeAlert = YES;
|
||||
} else if (notificationTypes == UIRemoteNotificationTypeSound) {
|
||||
needsPushSettingChangeAlert = YES;
|
||||
} else if (notificationTypes == (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)) {
|
||||
needsPushSettingChangeAlert = YES;
|
||||
} else if (notificationTypes == (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)) {
|
||||
needsPushSettingChangeAlert = YES;
|
||||
}
|
||||
|
||||
if (needsPushSettingChangeAlert) {
|
||||
[Environment.preferences setRevokedPushPermission:YES];
|
||||
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"ACTION_REQUIRED_TITLE", @"") message:NSLocalizedString(@"PUSH_SETTINGS_MESSAGE", @"") delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles:nil, nil];
|
||||
[alertView show];
|
||||
} else if (!needsPushSettingChangeAlert){
|
||||
if (Environment.preferences.encounteredRevokedPushPermission) {
|
||||
[self askForPushRegistration];
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
|
||||
// Displaying notifications and ringing
|
||||
|
||||
if ([self isMissingMandatoryNotificationTypes:[UIApplication.sharedApplication enabledRemoteNotificationTypes]]) {
|
||||
|
||||
[self registrationWithSuccess:^{
|
||||
DDLogInfo(@"Push notifications were succesfully re-enabled");
|
||||
} failure:^{
|
||||
[self.missingPermissionsAlertView show];
|
||||
}];
|
||||
}
|
||||
|
||||
} else{
|
||||
|
||||
// UIUserNotificationsSettings
|
||||
UIUserNotificationSettings *settings = [UIApplication.sharedApplication currentUserNotificationSettings];
|
||||
|
||||
// To use Signal, it is required to have sound notifications and alert types.
|
||||
|
||||
if ([self isMissingMandatoryNotificationTypes:settings.types]) {
|
||||
|
||||
[self registrationForUserNotificationWithSuccess:^{
|
||||
DDLogInfo(@"User notifications were succesfully re-enabled");
|
||||
} failure:^{
|
||||
[self.missingPermissionsAlertView show];
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
// Remote Notifications
|
||||
if (![UIApplication.sharedApplication isRegisteredForRemoteNotifications]) {
|
||||
|
||||
[self registrationForPushWithSuccess:^{
|
||||
DDLogInfo(@"Push notification were succesfully re-enabled");
|
||||
} failure:^{
|
||||
DDLogError(@"The phone could not be re-registered for push notifications."); // Push tokens are not changing on the same phone, just user notification changes so it's not very important.
|
||||
}];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)askForPushRegistrationWithSuccess:(void (^)())success failure:(void (^)())failure{
|
||||
self.PushRegisteringSuccessBlock = success;
|
||||
self.PushRegisteringFailureBlock = failure;
|
||||
[self askForPushRegistration];
|
||||
}
|
||||
|
||||
- (void)askForPushRegistration{
|
||||
- (void)registrationWithSuccess:(void (^)())success failure:(void (^)())failure{
|
||||
|
||||
if(SYSTEM_VERSION_LESS_THAN(_iOS_8_0)){
|
||||
[UIApplication.sharedApplication registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
|
||||
// On iOS7, we just need to register for Push Notifications (user notifications are enabled with them)
|
||||
[self registrationForPushWithSuccess:success failure:failure];
|
||||
|
||||
} else{
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1
|
||||
UIMutableUserNotificationAction *action_accept = [UIMutableUserNotificationAction new];
|
||||
action_accept.identifier = @"Signal_Call_Accept";
|
||||
action_accept.title = @"Pick up";
|
||||
action_accept.activationMode = UIUserNotificationActivationModeForeground;
|
||||
action_accept.destructive = YES;
|
||||
action_accept.authenticationRequired = NO;
|
||||
|
||||
UIMutableUserNotificationAction *action_decline = [UIMutableUserNotificationAction new];
|
||||
action_decline.identifier = @"Signal_Call_Decline";
|
||||
action_decline.title = @"Pick up";
|
||||
action_decline.activationMode = UIUserNotificationActivationModeForeground;
|
||||
action_decline.destructive = YES;
|
||||
action_decline.authenticationRequired = NO;
|
||||
// On iOS 8+, both Push Notifications and User Notfications need to be registered.
|
||||
|
||||
UIMutableUserNotificationCategory *callCategory = [UIMutableUserNotificationCategory new];
|
||||
callCategory.identifier = @"Signal_IncomingCall";
|
||||
[callCategory setActions:@[action_accept, action_decline] forContext:UIUserNotificationActionContextDefault];
|
||||
|
||||
NSSet *categories = [NSSet setWithObject:callCategory];
|
||||
|
||||
[UIApplication.sharedApplication registerForRemoteNotifications];
|
||||
[UIApplication.sharedApplication registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound) categories:categories]];
|
||||
|
||||
#endif
|
||||
|
||||
[self registrationForPushWithSuccess:^{
|
||||
[self registrationForUserNotificationWithSuccess:success failure:^{
|
||||
[self.missingPermissionsAlertView show];
|
||||
failure();
|
||||
}];
|
||||
} failure:failure];
|
||||
}
|
||||
|
||||
self.retries = 3;
|
||||
}
|
||||
|
||||
- (void)registerForPushWithToken:(NSData*)token{
|
||||
|
||||
#pragma mark Private Methods
|
||||
|
||||
#pragma mark Register Push Notification Token with server
|
||||
|
||||
-(TOCFuture*)registerForPushFutureWithToken:(NSData*)token{
|
||||
self.registerWithServerFutureSource = [TOCFutureSource new];
|
||||
|
||||
[CallServerRequestsManager.sharedInstance registerPushToken:token success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||
if ([task.response isKindOfClass: NSHTTPURLResponse.class]){
|
||||
NSInteger statusCode = [(NSHTTPURLResponse*) task.response statusCode];
|
||||
if (statusCode == 200) {
|
||||
DDLogInfo(@"Device sent push ID to server");
|
||||
[Environment.preferences setRevokedPushPermission:NO];
|
||||
if (self.PushRegisteringSuccessBlock) {
|
||||
self.PushRegisteringSuccessBlock();
|
||||
self.PushRegisteringSuccessBlock = nil;
|
||||
}
|
||||
[self.registerWithServerFutureSource trySetResult:@YES];
|
||||
} else{
|
||||
[self registerFailureWithToken:token];
|
||||
DDLogError(@"The server returned %@ instead of a 200 status code", task.response);
|
||||
[self.registerWithServerFutureSource trySetFailure:@NO];
|
||||
}
|
||||
} else{
|
||||
[self.registerWithServerFutureSource trySetFailure:@NO];
|
||||
}
|
||||
} failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
[self registerFailureWithToken:token];
|
||||
[self.registerWithServerFutureSource trySetFailure:@NO];
|
||||
}];
|
||||
|
||||
return self.registerWithServerFutureSource.future;
|
||||
}
|
||||
|
||||
#pragma mark Register device for Push Notification locally
|
||||
|
||||
-(TOCFuture*)registeriOS7PushNotificationFuture{
|
||||
self.pushNotificationFutureSource = [TOCFutureSource new];
|
||||
[UIApplication.sharedApplication registerForRemoteNotificationTypes:(UIRemoteNotificationType)[self mandatoryNotificationTypes]];
|
||||
return self.pushNotificationFutureSource.future;
|
||||
}
|
||||
|
||||
-(TOCFuture*)registerPushNotificationFuture{
|
||||
self.pushNotificationFutureSource = [TOCFutureSource new];
|
||||
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
||||
return self.pushNotificationFutureSource.future;
|
||||
}
|
||||
|
||||
-(TOCFuture*)registerForUserNotificationsFuture{
|
||||
self.userNotificationFutureSource = [TOCFutureSource new];
|
||||
[UIApplication.sharedApplication registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationType)[self allNotificationTypes] categories:[NSSet setWithObject:[self userNotificationsCallCategory]]]];
|
||||
return self.userNotificationFutureSource.future;
|
||||
}
|
||||
|
||||
- (void)registrationForPushWithSuccess:(void (^)())success failure:(void (^)())failure{
|
||||
TOCFuture *requestPushTokenFuture;
|
||||
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
requestPushTokenFuture = [self registeriOS7PushNotificationFuture];
|
||||
} else{
|
||||
requestPushTokenFuture = [self registerPushNotificationFuture];
|
||||
}
|
||||
|
||||
[requestPushTokenFuture catchDo:^(id failureObj) {
|
||||
failure();
|
||||
if (SYSTEM_VERSION_LESS_THAN(_iOS_8_0)) {
|
||||
[self.missingPermissionsAlertView show];
|
||||
} else{
|
||||
DDLogError(@"This should not happen on iOS8. No push token was provided");
|
||||
}
|
||||
}];
|
||||
|
||||
[requestPushTokenFuture thenDo:^(NSData* pushToken) {
|
||||
TOCFuture *registerPushTokenFuture = [self registerForPushFutureWithToken:pushToken];
|
||||
|
||||
[registerPushTokenFuture catchDo:^(id failureObj) {
|
||||
UIAlertView *failureToRegisterWithServerAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"REGISTRATION_ERROR", @"") message:NSLocalizedString(@"REGISTRATION_BODY", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", nil) otherButtonTitles:nil, nil];
|
||||
[failureToRegisterWithServerAlert show];
|
||||
failure();
|
||||
}];
|
||||
|
||||
[registerPushTokenFuture thenDo:^(id value) {
|
||||
success();
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)registrationForUserNotificationWithSuccess:(void (^)())success failure:(void (^)())failure{
|
||||
TOCFuture *registrerUserNotificationFuture = [self registerForUserNotificationsFuture];
|
||||
|
||||
[registrerUserNotificationFuture catchDo:^(id failureObj) {
|
||||
[self.missingPermissionsAlertView show];
|
||||
failure();
|
||||
}];
|
||||
|
||||
[registrerUserNotificationFuture thenDo:^(id types) {
|
||||
if ([self isMissingMandatoryNotificationTypes:[UIApplication.sharedApplication currentUserNotificationSettings].types]) {
|
||||
[self.missingPermissionsAlertView show];
|
||||
failure();
|
||||
} else{
|
||||
success();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Token was not sucessfully register. Try again / deal with failure
|
||||
*
|
||||
* @param token Token to register
|
||||
*/
|
||||
|
||||
- (void)registerFailureWithToken:(NSData*)token{
|
||||
if (self.retries > 0) {
|
||||
[self registerForPushWithToken:token];
|
||||
self.retries--;
|
||||
} else{
|
||||
if (self.PushRegisteringFailureBlock) {
|
||||
self.PushRegisteringFailureBlock();
|
||||
self.PushRegisteringFailureBlock = nil;
|
||||
}
|
||||
[Environment.preferences setRevokedPushPermission:YES];
|
||||
}
|
||||
-(UIUserNotificationCategory*)userNotificationsCallCategory{
|
||||
UIMutableUserNotificationAction *action_accept = [UIMutableUserNotificationAction new];
|
||||
action_accept.identifier = Signal_Accept_Identifier;
|
||||
action_accept.title = NSLocalizedString(@"ANSWER_CALL_BUTTON_TITLE", @"");
|
||||
action_accept.activationMode = UIUserNotificationActivationModeForeground;
|
||||
action_accept.destructive = NO;
|
||||
action_accept.authenticationRequired = NO;
|
||||
|
||||
UIMutableUserNotificationAction *action_decline = [UIMutableUserNotificationAction new];
|
||||
action_decline.identifier = Signal_Decline_Identifier;
|
||||
action_decline.title = NSLocalizedString(@"REJECT_CALL_BUTTON_TITLE", @"");
|
||||
action_decline.activationMode = UIUserNotificationActivationModeBackground;
|
||||
action_decline.destructive = NO;
|
||||
action_decline.authenticationRequired = NO;
|
||||
|
||||
UIMutableUserNotificationCategory *callCategory = [UIMutableUserNotificationCategory new];
|
||||
callCategory.identifier = @"Signal_IncomingCall";
|
||||
[callCategory setActions:@[action_accept, action_decline] forContext:UIUserNotificationActionContextMinimal];
|
||||
[callCategory setActions:@[action_accept, action_decline] forContext:UIUserNotificationActionContextDefault];
|
||||
|
||||
return callCategory;
|
||||
}
|
||||
|
||||
-(BOOL)isMissingMandatoryNotificationTypes:(int)notificationTypes{
|
||||
int mandatoryTypes = [self mandatoryNotificationTypes];
|
||||
return ((mandatoryTypes & notificationTypes) == mandatoryTypes)?NO:YES;
|
||||
}
|
||||
|
||||
-(int)allNotificationTypes{
|
||||
return (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
|
||||
}
|
||||
|
||||
-(int)mandatoryNotificationTypes{
|
||||
return (UIUserNotificationTypeAlert | UIUserNotificationTypeSound);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -37,4 +37,5 @@
|
|||
- (IBAction)answerButtonTapped;
|
||||
- (IBAction)rejectButtonTapped;
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
@ -199,19 +199,16 @@
|
|||
}];
|
||||
|
||||
[futureChallengeAcceptedSource.future thenDo:^(id value) {
|
||||
[PushManager.sharedManager askForPushRegistrationWithSuccess:^{
|
||||
[PushManager.sharedManager registrationWithSuccess:^{
|
||||
[Environment setRegistered:YES];
|
||||
[registered trySetResult:@YES];
|
||||
[Environment.getCurrent.phoneDirectoryManager forceUpdate];
|
||||
[self dismissView];
|
||||
} failure:^{
|
||||
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:REGISTER_ERROR_ALERT_VIEW_TITLE message:REGISTER_ERROR_ALERT_VIEW_BODY delegate:nil cancelButtonTitle:REGISTER_ERROR_ALERT_VIEW_DISMISS otherButtonTitles:nil, nil];
|
||||
[alertView show];
|
||||
_challengeButton.enabled = YES;
|
||||
[_challengeActivityIndicator stopAnimating];
|
||||
}];
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
- (void)showViewNumber:(NSInteger)viewNumber {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// PushManagerTest.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Frederic Jacobs on 12/09/14.
|
||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
@interface PushManagerTest : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation PushManagerTest
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
/**
|
||||
* This test verifies that the enum containing the notifications types doesn't change for iOS7 support.
|
||||
*/
|
||||
|
||||
- (void)testNotificationTypesForiOS7 {
|
||||
XCTAssert(UIRemoteNotificationTypeAlert == UIUserNotificationTypeAlert, @"iOS 7 <-> 8 compatibility");
|
||||
XCTAssert(UIRemoteNotificationTypeSound == UIUserNotificationTypeSound, @"iOS 7 <-> 8 compatibility");
|
||||
XCTAssert(UIRemoteNotificationTypeBadge == UIUserNotificationTypeBadge, @"iOS 7 <-> 8 compatibility");
|
||||
}
|
||||
|
||||
@end
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue