Merge pull request #3268 from vector-im/remove_pushkit

Remove PushKit
This commit is contained in:
ismailgulek 2020-05-29 12:34:20 +03:00 committed by GitHub
commit 0d73c8dccf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 1108 additions and 148 deletions

View file

@ -93,6 +93,10 @@ abstract_target 'RiotPods' do
import_MatrixKitAppExtension
end
target "RiotNSE" do
import_MatrixKitAppExtension
end
end

View file

@ -684,6 +684,7 @@
B1E5368D21FB7245001F3AFF /* KeyBackupRecoverFromPassphraseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E5368C21FB7245001F3AFF /* KeyBackupRecoverFromPassphraseViewController.swift */; };
B1E5368F21FB7258001F3AFF /* KeyBackupRecoverFromPassphraseViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B1E5368E21FB7258001F3AFF /* KeyBackupRecoverFromPassphraseViewController.storyboard */; };
B1FDF56021F5FE5500BA3834 /* KeyBackupSetupPassphraseViewAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FDF55F21F5FE5500BA3834 /* KeyBackupSetupPassphraseViewAction.swift */; };
DB1392A2332C3CAF6C9962EF /* Pods_RiotPods_RiotNSE.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4D418D054E4032F2CFA8B51 /* Pods_RiotPods_RiotNSE.framework */; };
EC85D6AE2477DC89002C44C9 /* RoundedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D6AD2477DC89002C44C9 /* RoundedButton.swift */; };
EC85D7142477DCD7002C44C9 /* KeyVerificationScanConfirmationViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D70C2477DCD7002C44C9 /* KeyVerificationScanConfirmationViewState.swift */; };
EC85D7152477DCD7002C44C9 /* KeyVerificationScanConfirmationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D70D2477DCD7002C44C9 /* KeyVerificationScanConfirmationViewController.swift */; };
@ -706,6 +707,14 @@
EC85D7372477DD97002C44C9 /* LocalContactsSectionHeaderContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = EC85D7352477DD97002C44C9 /* LocalContactsSectionHeaderContainerView.m */; };
EC85D73A2477DDB8002C44C9 /* DirectorySectionHeaderContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = EC85D7392477DDB8002C44C9 /* DirectorySectionHeaderContainerView.m */; };
EC85D73E2477DDD0002C44C9 /* PushNotificationService.m in Sources */ = {isa = PBXBuildFile; fileRef = EC85D73D2477DDD0002C44C9 /* PushNotificationService.m */; };
EC85D7462477E5F7002C44C9 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D7452477E5F7002C44C9 /* NotificationService.swift */; };
EC85D74A2477E5F7002C44C9 /* RiotNSE.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = EC85D7432477E5F7002C44C9 /* RiotNSE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
EC85D74F2477E8EB002C44C9 /* RiotSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B5597F20EFC3DF00210D55 /* RiotSettings.swift */; };
EC85D751247C0E8F002C44C9 /* UNUserNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D750247C0E8F002C44C9 /* UNUserNotificationCenter.swift */; };
EC85D752247C0F52002C44C9 /* UNUserNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D750247C0E8F002C44C9 /* UNUserNotificationCenter.swift */; };
EC85D754247C0F5B002C44C9 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D753247C0F5B002C44C9 /* Constants.swift */; };
EC85D755247C0F84002C44C9 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D753247C0F5B002C44C9 /* Constants.swift */; };
EC85D757247E700F002C44C9 /* NSEMemoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC85D756247E700F002C44C9 /* NSEMemoryStore.swift */; };
ECB101302477CFDB00CF8C11 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB1012C2477CFDB00CF8C11 /* UITableView.swift */; };
ECB101312477CFDB00CF8C11 /* UILabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB1012D2477CFDB00CF8C11 /* UILabel.swift */; };
ECB101322477CFDB00CF8C11 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB1012E2477CFDB00CF8C11 /* UIDevice.swift */; };
@ -751,6 +760,13 @@
remoteGlobalIDString = 92726A421F58737A004AD26F;
remoteInfo = SiriIntents;
};
EC85D7482477E5F7002C44C9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F094A99A1B78D8F000B1FBBF /* Project object */;
proxyType = 1;
remoteGlobalIDString = EC85D7422477E5F7002C44C9;
remoteInfo = RiotNSE;
};
F094A9BF1B78D8F000B1FBBF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F094A99A1B78D8F000B1FBBF /* Project object */;
@ -769,6 +785,7 @@
files = (
24CBEC591F0EAD310093EABB /* RiotShareExtension.appex in Embed App Extensions */,
92726A4B1F58737A004AD26F /* SiriIntents.appex in Embed App Extensions */,
EC85D74A2477E5F7002C44C9 /* RiotNSE.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
@ -779,6 +796,7 @@
129EB7E27E7E4AC3F5F098F5 /* Pods_RiotTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RiotTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1ACF09217ADF1D7E7A35BC02 /* Pods_RiotPods_Riot.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RiotPods_Riot.framework; sourceTree = BUILT_PRODUCTS_DIR; };
24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = RiotShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
2B582BE9B2A98BCF5F740873 /* Pods-RiotPods-RiotNSE.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-RiotNSE.debug.xcconfig"; path = "Target Support Files/Pods-RiotPods-RiotNSE/Pods-RiotPods-RiotNSE.debug.xcconfig"; sourceTree = "<group>"; };
3209451121F1C1430088CAA2 /* BlackTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlackTheme.swift; sourceTree = "<group>"; };
32242F0821E8B05F00725742 /* UIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = "<group>"; };
32242F0C21E8FBA900725742 /* ThemeService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThemeService.m; sourceTree = "<group>"; };
@ -912,6 +930,7 @@
43C2962BE367F59220F517FA /* Pods-RiotPods-Riot.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-Riot.debug.xcconfig"; path = "Target Support Files/Pods-RiotPods-Riot/Pods-RiotPods-Riot.debug.xcconfig"; sourceTree = "<group>"; };
4FC6A5D63FAD1B27C2F57AFA /* Pods-RiotPods-RiotShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-RiotShareExtension.release.xcconfig"; path = "Target Support Files/Pods-RiotPods-RiotShareExtension/Pods-RiotPods-RiotShareExtension.release.xcconfig"; sourceTree = "<group>"; };
51187E952D5CECF6D6F5A28E /* Pods_RiotPods_SiriIntents.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RiotPods_SiriIntents.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8A61E94F88EA96AFE1CFD9D3 /* Pods-RiotPods-RiotNSE.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-RiotNSE.release.xcconfig"; path = "Target Support Files/Pods-RiotPods-RiotNSE/Pods-RiotPods-RiotNSE.release.xcconfig"; sourceTree = "<group>"; };
926FA53D1F4C132000F826C2 /* MXSession+Riot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MXSession+Riot.h"; sourceTree = "<group>"; };
926FA53E1F4C132000F826C2 /* MXSession+Riot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MXSession+Riot.m"; sourceTree = "<group>"; };
92726A431F58737A004AD26F /* SiriIntents.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SiriIntents.appex; sourceTree = BUILT_PRODUCTS_DIR; };
@ -1673,6 +1692,7 @@
B43DC75D1590BB8A4243BD4D /* Pods-RiotPods-Riot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-Riot.release.xcconfig"; path = "Target Support Files/Pods-RiotPods-Riot/Pods-RiotPods-Riot.release.xcconfig"; sourceTree = "<group>"; };
BABB6681FBD79219B1213D6C /* Pods-RiotTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotTests.debug.xcconfig"; path = "Target Support Files/Pods-RiotTests/Pods-RiotTests.debug.xcconfig"; sourceTree = "<group>"; };
E2599D0ECB8DD206624E450B /* Pods-RiotPods-SiriIntents.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-SiriIntents.release.xcconfig"; path = "Target Support Files/Pods-RiotPods-SiriIntents/Pods-RiotPods-SiriIntents.release.xcconfig"; sourceTree = "<group>"; };
E4D418D054E4032F2CFA8B51 /* Pods_RiotPods_RiotNSE.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RiotPods_RiotNSE.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EC85D6AD2477DC89002C44C9 /* RoundedButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedButton.swift; sourceTree = "<group>"; };
EC85D70C2477DCD7002C44C9 /* KeyVerificationScanConfirmationViewState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationScanConfirmationViewState.swift; sourceTree = "<group>"; };
EC85D70D2477DCD7002C44C9 /* KeyVerificationScanConfirmationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationScanConfirmationViewController.swift; sourceTree = "<group>"; };
@ -1700,6 +1720,13 @@
EC85D7392477DDB8002C44C9 /* DirectorySectionHeaderContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DirectorySectionHeaderContainerView.m; sourceTree = "<group>"; };
EC85D73C2477DDD0002C44C9 /* PushNotificationService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PushNotificationService.h; sourceTree = "<group>"; };
EC85D73D2477DDD0002C44C9 /* PushNotificationService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PushNotificationService.m; sourceTree = "<group>"; };
EC85D7432477E5F7002C44C9 /* RiotNSE.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = RiotNSE.appex; sourceTree = BUILT_PRODUCTS_DIR; };
EC85D7452477E5F7002C44C9 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
EC85D7472477E5F7002C44C9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
EC85D74E2477E614002C44C9 /* RiotNSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RiotNSE.entitlements; sourceTree = "<group>"; };
EC85D750247C0E8F002C44C9 /* UNUserNotificationCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNUserNotificationCenter.swift; sourceTree = "<group>"; };
EC85D753247C0F5B002C44C9 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
EC85D756247E700F002C44C9 /* NSEMemoryStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSEMemoryStore.swift; sourceTree = "<group>"; };
ECB1012C2477CFDB00CF8C11 /* UITableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableView.swift; sourceTree = "<group>"; };
ECB1012D2477CFDB00CF8C11 /* UILabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabel.swift; sourceTree = "<group>"; };
ECB1012E2477CFDB00CF8C11 /* UIDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIDevice.swift; sourceTree = "<group>"; };
@ -1763,6 +1790,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
EC85D7402477E5F7002C44C9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DB1392A2332C3CAF6C9962EF /* Pods_RiotPods_RiotNSE.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F094A99F1B78D8F000B1FBBF /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -2111,6 +2146,8 @@
E2599D0ECB8DD206624E450B /* Pods-RiotPods-SiriIntents.release.xcconfig */,
BABB6681FBD79219B1213D6C /* Pods-RiotTests.debug.xcconfig */,
AC34BF67FD21A9D01C16AE5D /* Pods-RiotTests.release.xcconfig */,
2B582BE9B2A98BCF5F740873 /* Pods-RiotPods-RiotNSE.debug.xcconfig */,
8A61E94F88EA96AFE1CFD9D3 /* Pods-RiotPods-RiotNSE.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@ -2123,6 +2160,7 @@
97151D7F0F892081250D50A3 /* Pods_RiotPods_RiotShareExtension.framework */,
51187E952D5CECF6D6F5A28E /* Pods_RiotPods_SiriIntents.framework */,
129EB7E27E7E4AC3F5F098F5 /* Pods_RiotTests.framework */,
E4D418D054E4032F2CFA8B51 /* Pods_RiotPods_RiotNSE.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -4247,6 +4285,17 @@
path = PushNotification;
sourceTree = "<group>";
};
EC85D7442477E5F7002C44C9 /* RiotNSE */ = {
isa = PBXGroup;
children = (
EC85D74E2477E614002C44C9 /* RiotNSE.entitlements */,
EC85D7452477E5F7002C44C9 /* NotificationService.swift */,
EC85D756247E700F002C44C9 /* NSEMemoryStore.swift */,
EC85D7472477E5F7002C44C9 /* Info.plist */,
);
path = RiotNSE;
sourceTree = "<group>";
};
F083BB021E7005FD00A9B29C /* RiotTests */ = {
isa = PBXGroup;
children = (
@ -4338,6 +4387,7 @@
926FA53D1F4C132000F826C2 /* MXSession+Riot.h */,
926FA53E1F4C132000F826C2 /* MXSession+Riot.m */,
32242F0821E8B05F00725742 /* UIColor.swift */,
EC85D750247C0E8F002C44C9 /* UNUserNotificationCenter.swift */,
B1CA3A2621EF6913000D1D89 /* UIViewController.swift */,
B1CA3A2821EF692B000D1D89 /* UIView.swift */,
B140B4A121F87F7100E3F5FE /* OperationQueue.swift */,
@ -4380,6 +4430,7 @@
F083BC0F1E7009EC00A9B29C /* Utils */ = {
isa = PBXGroup;
children = (
EC85D753247C0F5B002C44C9 /* Constants.swift */,
ECB101342477D00700CF8C11 /* UniversalLink.h */,
ECB101352477D00700CF8C11 /* UniversalLink.m */,
F083BC101E7009EC00A9B29C /* AvatarGenerator.h */,
@ -4407,6 +4458,7 @@
F083BB021E7005FD00A9B29C /* RiotTests */,
24CBEC4F1F0EAD310093EABB /* RiotShareExtension */,
92726A441F58737A004AD26F /* SiriIntents */,
EC85D7442477E5F7002C44C9 /* RiotNSE */,
F094A9A31B78D8F000B1FBBF /* Products */,
5FC42FA41F5186AFFB6A2404 /* Frameworks */,
3232AAFE22564D9100AD6A5C /* Tools */,
@ -4422,6 +4474,7 @@
F094A9BE1B78D8F000B1FBBF /* RiotTests.xctest */,
24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */,
92726A431F58737A004AD26F /* SiriIntents.appex */,
EC85D7432477E5F7002C44C9 /* RiotNSE.appex */,
);
name = Products;
sourceTree = "<group>";
@ -4465,6 +4518,24 @@
productReference = 92726A431F58737A004AD26F /* SiriIntents.appex */;
productType = "com.apple.product-type.app-extension";
};
EC85D7422477E5F7002C44C9 /* RiotNSE */ = {
isa = PBXNativeTarget;
buildConfigurationList = EC85D74D2477E5F7002C44C9 /* Build configuration list for PBXNativeTarget "RiotNSE" */;
buildPhases = (
E96A5016582B740FB3EABBB3 /* [CP] Check Pods Manifest.lock */,
EC85D73F2477E5F7002C44C9 /* Sources */,
EC85D7402477E5F7002C44C9 /* Frameworks */,
EC85D7412477E5F7002C44C9 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = RiotNSE;
productName = RiotNSE;
productReference = EC85D7432477E5F7002C44C9 /* RiotNSE.appex */;
productType = "com.apple.product-type.app-extension";
};
F094A9A11B78D8F000B1FBBF /* Riot */ = {
isa = PBXNativeTarget;
buildConfigurationList = F094A9C81B78D8F000B1FBBF /* Build configuration list for PBXNativeTarget "Riot" */;
@ -4483,6 +4554,7 @@
dependencies = (
242661F61F12B1BA00D3FC08 /* PBXTargetDependency */,
92726A4A1F58737A004AD26F /* PBXTargetDependency */,
EC85D7492477E5F7002C44C9 /* PBXTargetDependency */,
);
name = Riot;
productName = Vector;
@ -4514,6 +4586,8 @@
F094A99A1B78D8F000B1FBBF /* Project object */ = {
isa = PBXProject;
attributes = {
DefaultBuildSystemTypeForWorkspace = Original;
LastSwiftUpdateCheck = 1130;
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = matrix.org;
TargetAttributes = {
@ -4538,6 +4612,9 @@
};
};
};
EC85D7422477E5F7002C44C9 = {
CreatedOnToolsVersion = 11.3.1;
};
F094A9A11B78D8F000B1FBBF = {
CreatedOnToolsVersion = 6.2;
DevelopmentTeam = 7J4U792NQT;
@ -4599,6 +4676,7 @@
F094A9BD1B78D8F000B1FBBF /* RiotTests */,
24CBEC4D1F0EAD310093EABB /* RiotShareExtension */,
92726A421F58737A004AD26F /* SiriIntents */,
EC85D7422477E5F7002C44C9 /* RiotNSE */,
);
};
/* End PBXProject section */
@ -4625,6 +4703,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
EC85D7412477E5F7002C44C9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
F094A9A01B78D8F000B1FBBF /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -4934,6 +5019,28 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
E96A5016582B740FB3EABBB3 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RiotPods-RiotNSE-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
FF06981FDA0DB688B8C52A41 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -4997,6 +5104,18 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
EC85D73F2477E5F7002C44C9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
EC85D74F2477E8EB002C44C9 /* RiotSettings.swift in Sources */,
EC85D757247E700F002C44C9 /* NSEMemoryStore.swift in Sources */,
EC85D7462477E5F7002C44C9 /* NotificationService.swift in Sources */,
EC85D752247C0F52002C44C9 /* UNUserNotificationCenter.swift in Sources */,
EC85D755247C0F84002C44C9 /* Constants.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F094A99E1B78D8F000B1FBBF /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -5292,6 +5411,7 @@
32A6001D22C661100042C1D9 /* EditHistoryCoordinatorType.swift in Sources */,
F083BDFA1E7009ED00A9B29C /* RoomPreviewData.m in Sources */,
B1B557B420EF5AEF00210D55 /* EventDetailsView.m in Sources */,
EC85D751247C0E8F002C44C9 /* UNUserNotificationCenter.swift in Sources */,
B1BEE73823DF44A60003A4CB /* UserVerificationSessionsStatusViewAction.swift in Sources */,
B1B5577E20EE84BF00210D55 /* IncomingCallView.m in Sources */,
B1CE83E22422817200D07506 /* KeyVerificationVerifyBySASViewState.swift in Sources */,
@ -5395,6 +5515,7 @@
B1B558C820EF768F00210D55 /* RoomIncomingEncryptedAttachmentBubbleCell.m in Sources */,
B1B557C620EF5CD400210D55 /* DirectoryServerDetailTableViewCell.m in Sources */,
EC85D71A2477DCD7002C44C9 /* KeyVerificationScanConfirmationCoordinator.swift in Sources */,
EC85D754247C0F5B002C44C9 /* Constants.swift in Sources */,
B1B336C4242B933700F95EC4 /* KeyVerificationSelfVerifyStartViewAction.swift in Sources */,
B1B5590920EF768F00210D55 /* RoomEmptyBubbleCell.m in Sources */,
324A2054225FC571004FE8B0 /* DeviceVerificationIncomingCoordinatorType.swift in Sources */,
@ -5540,6 +5661,11 @@
target = 92726A421F58737A004AD26F /* SiriIntents */;
targetProxy = 92726A491F58737A004AD26F /* PBXContainerItemProxy */;
};
EC85D7492477E5F7002C44C9 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = EC85D7422477E5F7002C44C9 /* RiotNSE */;
targetProxy = EC85D7482477E5F7002C44C9 /* PBXContainerItemProxy */;
};
F094A9C01B78D8F000B1FBBF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = F094A9A11B78D8F000B1FBBF /* Riot */;
@ -5791,6 +5917,83 @@
};
name = Release;
};
EC85D74B2477E5F7002C44C9 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2B582BE9B2A98BCF5F740873 /* Pods-RiotPods-RiotNSE.debug.xcconfig */;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = RiotNSE/RiotNSE.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 0.11.5;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 7J4U792NQT;
ENABLE_BITCODE = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = RiotNSE/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 0.11.5;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.nse;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
EC85D74C2477E5F7002C44C9 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8A61E94F88EA96AFE1CFD9D3 /* Pods-RiotPods-RiotNSE.release.xcconfig */;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = RiotNSE/RiotNSE.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 0.11.5;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 7J4U792NQT;
ENABLE_BITCODE = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = RiotNSE/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 0.11.5;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.nse;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
F094A9C61B78D8F000B1FBBF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -6041,6 +6244,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
EC85D74D2477E5F7002C44C9 /* Build configuration list for PBXNativeTarget "RiotNSE" */ = {
isa = XCConfigurationList;
buildConfigurations = (
EC85D74B2477E5F7002C44C9 /* Debug */,
EC85D74C2477E5F7002C44C9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F094A99D1B78D8F000B1FBBF /* Build configuration list for PBXProject "Riot" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View file

@ -273,6 +273,28 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
[self.pushNotificationService registerForRemoteNotificationsWithCompletion:completion];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[self.pushNotificationService didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
NSString * deviceTokenString = [[[[deviceToken description]
stringByReplacingOccurrencesOfString: @"<" withString: @""]
stringByReplacingOccurrencesOfString: @">" withString: @""]
stringByReplacingOccurrencesOfString: @" " withString: @""];
NSLog(@"The generated device token string is : %@",deviceTokenString);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[self.pushNotificationService didFailToRegisterForRemoteNotificationsWithError:error];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
[self.pushNotificationService didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
#pragma mark -
- (NSString*)appVersion
@ -484,6 +506,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
[MXSDKOptions sharedInstance].analyticsDelegate = [Analytics sharedInstance];
[DecryptionFailureTracker sharedInstance].delegate = [Analytics sharedInstance];
[[Analytics sharedInstance] start];
// Disable CallKit
[MXKAppSettings standardAppSettings].enableCallKit = NO;
self.pushNotificationService = [PushNotificationService new];
self.pushNotificationService.delegate = self;
@ -1953,7 +1978,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
if (isPushRegistered)
{
// Enable push notifications by default on new added account
[account enablePushKitNotifications:YES success:nil failure:nil];
[account enablePushNotifications:YES success:nil failure:nil];
}
else
{
@ -2034,13 +2059,13 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
accountManager.storeClass = [MXFileStore class];
// Disable APNS use.
if (accountManager.apnsDeviceToken)
{
// We use now Pushkit, unregister for all remote notifications received via Apple Push Notification service.
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
[accountManager setApnsDeviceToken:nil];
}
// if (accountManager.apnsDeviceToken)
// {
// // We use now Pushkit, unregister for all remote notifications received via Apple Push Notification service.
// [[UIApplication sharedApplication] unregisterForRemoteNotifications];
// [accountManager setApnsDeviceToken:nil];
// }
// Observers have been defined, we can start a matrix session for each enabled accounts.
NSLog(@"[AppDelegate] initMatrixSessions: prepareSessionForActiveAccounts (app state: %tu)", [[UIApplication sharedApplication] applicationState]);
[accountManager prepareSessionForActiveAccounts];
@ -4569,6 +4594,11 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
NSDictionary *defaults = [NSDictionary dictionaryWithContentsOfFile:defaultsPathFromApp];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
if (!RiotSettings.shared.isUserDefaultsMigrated)
{
[RiotSettings.shared migrate];
}
// Now use RiotSettings and NSUserDefaults to store `showDecryptedContentInNotifications` setting option
// Migrate this information from main MXKAccount to RiotSettings, if value is not in UserDefaults

View file

@ -12,6 +12,10 @@
<string>im.vector.app.ios.voip.prod</string>
<key>pushKitAppIdDev</key>
<string>im.vector.app.ios.voip.dev</string>
<key>pusherAppIdDev</key>
<string>im.vector.app.ios.dev</string>
<key>pusherAppIdProd</key>
<string>im.vector.app.ios.prod</string>
<key>identityserverurl</key>
<string>https://vector.im</string>
<key>homeserverurl</key>

View file

@ -0,0 +1,32 @@
/*
Copyright 2020 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import Foundation
import UserNotifications
@objc extension UNUserNotificationCenter {
func removeUnwantedNotifications() {
UNUserNotificationCenter.current().getDeliveredNotifications { (notifications) in
// get identifiers of notifications whose category identifiers are "TO_BE_REMOVED"
let identifiersToBeRemoved = notifications.compactMap({ $0.request.content.categoryIdentifier == Constants.toBeRemovedNotificationCategoryIdentifier ? $0.request.identifier : nil })
// remove the notifications with these id's
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: identifiersToBeRemoved)
}
}
}

View file

@ -34,6 +34,8 @@ internal enum RiotDefaults {
internal static let pushGatewayURL: String = _document["pushGatewayURL"]
internal static let pushKitAppIdDev: String = _document["pushKitAppIdDev"]
internal static let pushKitAppIdProd: String = _document["pushKitAppIdProd"]
internal static let pusherAppIdDev: String = _document["pusherAppIdDev"]
internal static let pusherAppIdProd: String = _document["pusherAppIdProd"]
internal static let roomDirectoryServers: [String: Any] = _document["roomDirectoryServers"]
internal static let showAllEventsInRoomHistory: Bool = _document["showAllEventsInRoomHistory"]
internal static let showLeftMembersInRoomMemberList: Bool = _document["showLeftMembersInRoomMemberList"]

View file

@ -15,16 +15,19 @@
limitations under the License.
*/
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <PushKit/PushKit.h>
#import <UserNotifications/UserNotifications.h>
@class MXSession;
@class MXEvent;
@class MXPushRule;
@class MXKAccount;
@protocol PushNotificationServiceDelegate;
NS_ASSUME_NONNULL_BEGIN
@interface PushNotificationService : NSObject <PKPushRegistryDelegate, UNUserNotificationCenterDelegate>
@interface PushNotificationService : NSObject <UNUserNotificationCenterDelegate>
/**
Is push really registered.
@ -48,6 +51,13 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)registerForRemoteNotificationsWithCompletion:(nullable void (^)(NSError *))completion;
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
- (void)didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;
/**
Perform deregistration for remote notifications.
*/

View file

@ -46,7 +46,7 @@
NSMutableDictionary <NSNumber *, MXOnNotification> *notificationListenerBlocks;
}
@property (nonatomic, strong) PKPushRegistry *pushRegistry;
//@property (nonatomic, strong) PKPushRegistry *pushRegistry;
@property (nonatomic) NSMutableDictionary <NSNumber *, NSMutableArray <NSString *> *> *incomingPushEventIds;
@ -110,16 +110,56 @@
- (void)registerForRemoteNotificationsWithCompletion:(nullable void (^)(NSError *))completion
{
self.pushRegistry = [[PKPushRegistry alloc] initWithQueue:nil];
self.pushRegistry.delegate = self;
self.pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
self.registrationForRemoteNotificationsCompletion = completion;
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
}
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
MXKAccountManager* accountManager = [MXKAccountManager sharedManager];
[accountManager setApnsDeviceToken:deviceToken];
// remove PushKit pusher if exists
if (accountManager.pushDeviceToken)
{
[accountManager setPushDeviceToken:nil withPushOptions:nil];
}
// Sanity check: Make sure the Pushkit push token is deleted
NSParameterAssert(!accountManager.isPushAvailable);
NSParameterAssert(!accountManager.pushDeviceToken);
_isPushRegistered = YES;
if (self.registrationForRemoteNotificationsCompletion)
{
self.registrationForRemoteNotificationsCompletion(nil);
self.registrationForRemoteNotificationsCompletion = nil;
}
}
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[self clearPushNotificationToken];
if (self.registrationForRemoteNotificationsCompletion)
{
self.registrationForRemoteNotificationsCompletion(error);
self.registrationForRemoteNotificationsCompletion = nil;
}
}
- (void)didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSLog(@"[PushNotificationService][Push] didReceiveRemoteNotification: applicationState: %tu - payload: %@", [UIApplication sharedApplication].applicationState, userInfo);
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)deregisterRemoteNotifications
{
self.pushRegistry = nil;
_isPushRegistered = NO;
}
@ -131,6 +171,8 @@
[array removeAllObjects];
}
[incomingPushPayloads removeAllObjects];
[[UNUserNotificationCenter currentNotificationCenter] removeUnwantedNotifications];
}
- (void)addMatrixSession:(MXSession *)mxSession
@ -259,65 +301,6 @@
}
}
#pragma mark - PKPushRegistryDelegate
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type
{
NSData *token = credentials.token;
NSLog(@"[PushNotificationService][Push] didUpdatePushCredentials: Got Push token: %@. Type: %@", [MXKTools logForPushToken:token], type);
MXKAccountManager* accountManager = [MXKAccountManager sharedManager];
[accountManager setPushDeviceToken:token withPushOptions:@{@"format": @"event_id_only"}];
_isPushRegistered = YES;
if (self.registrationForRemoteNotificationsCompletion)
{
self.registrationForRemoteNotificationsCompletion(nil);
self.registrationForRemoteNotificationsCompletion = nil;
}
}
- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type
{
NSLog(@"[PushNotificationService][Push] didInvalidatePushTokenForType: Type: %@", type);
[self clearPushNotificationToken];
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type
{
NSLog(@"[PushNotificationService][Push] didReceiveIncomingPushWithPayload: applicationState: %tu - type: %@ - payload: %@", [UIApplication sharedApplication].applicationState, payload.type, payload.dictionaryPayload);
// Display local notifications only when the app is running in background.
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
{
NSLog(@"[PushNotificationService][Push] didReceiveIncomingPushWithPayload while app is in background");
// Check whether an event id is provided.
NSString *eventId = payload.dictionaryPayload[@"event_id"];
if (eventId)
{
// Add this event identifier in the pending push array for each session.
for (NSMutableArray *array in self.incomingPushEventIds.allValues)
{
[array addObject:eventId];
}
// Cache payload for further usage
incomingPushPayloads[eventId] = payload.dictionaryPayload;
}
else
{
NSLog(@"[PushNotificationService][Push] didReceiveIncomingPushWithPayload - Unexpected payload %@", payload.dictionaryPayload);
}
// Trigger a background sync to handle notifications.
[self launchBackgroundSync];
}
}
#pragma mark - UNUserNotificationCenterDelegate
// iOS 10+, see application:handleActionWithIdentifier:forLocalNotification:withResponseInfo:completionHandler:
@ -373,14 +356,6 @@
}
}
// iOS 10+, this is called when a notification is about to display in foreground.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSLog(@"[PushNotificationService][Push] willPresentNotification: applicationState: %@", @([UIApplication sharedApplication].applicationState));
completionHandler(UNNotificationPresentationOptionNone);
}
#pragma mark - Other Methods
- (void)launchBackgroundSync
@ -607,7 +582,7 @@
}
// iOS 10+, does the same thing as notificationBodyForEvent:pushRule:inAccount:onComplete:, except with more features
- (void)notificationContentForEvent:(MXEvent *)event pushRule:(MXPushRule *)rule inAccount:(MXKAccount *)account onComplete:(void (^)(UNNotificationContent * _Nullable notificationContent))onComplete;
- (void)notificationContentForEvent:(MXEvent *)event pushRule:(MXPushRule *)rule inAccount:(MXKAccount *)account onComplete:(void (^)(UNNotificationContent * _Nullable notificationContent))onComplete
{
if (!event.content || !event.content.count)
{

View file

@ -38,39 +38,61 @@ final class RiotSettings: NSObject {
static let shared = RiotSettings()
/// UserDefaults to be used on reads and writes.
private lazy var defaults: UserDefaults = {
return UserDefaults(suiteName: "group.im.vector")!
}()
// MARK: - Public
// MARK: Notifications
/// Indicate if `showDecryptedContentInNotifications` settings has been set once.
var isShowDecryptedContentInNotificationsHasBeenSetOnce: Bool {
return UserDefaults.standard.object(forKey: UserDefaultsKeys.notificationsShowDecryptedContent) != nil
return defaults.object(forKey: UserDefaultsKeys.notificationsShowDecryptedContent) != nil
}
/// Indicate if UserDefaults suite has been migrated once.
var isUserDefaultsMigrated: Bool {
return defaults.object(forKey: UserDefaultsKeys.notificationsShowDecryptedContent) != nil
}
func migrate() {
// read all values from standard
let dictionary = UserDefaults.standard.dictionaryRepresentation()
// write values to suite
// remove redundant values from standard
for (key, value) in dictionary {
defaults.set(value, forKey: key)
UserDefaults.standard.removeObject(forKey: key)
}
}
/// Indicate if encrypted messages content should be displayed in notifications.
var showDecryptedContentInNotifications: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.notificationsShowDecryptedContent)
return defaults.bool(forKey: UserDefaultsKeys.notificationsShowDecryptedContent)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.notificationsShowDecryptedContent)
defaults.set(newValue, forKey: UserDefaultsKeys.notificationsShowDecryptedContent)
}
}
/// Indicate if rooms with missed notifications should be displayed first on home screen.
var pinRoomsWithMissedNotificationsOnHome: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.pinRoomsWithMissedNotifications)
return defaults.bool(forKey: UserDefaultsKeys.pinRoomsWithMissedNotifications)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.pinRoomsWithMissedNotifications)
defaults.set(newValue, forKey: UserDefaultsKeys.pinRoomsWithMissedNotifications)
}
}
/// Indicate if rooms with unread messages should be displayed first on home screen.
var pinRoomsWithUnreadMessagesOnHome: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.pinRoomsWithUnreadMessages)
return defaults.bool(forKey: UserDefaultsKeys.pinRoomsWithUnreadMessages)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.pinRoomsWithUnreadMessages)
defaults.set(newValue, forKey: UserDefaultsKeys.pinRoomsWithUnreadMessages)
}
}
@ -78,9 +100,9 @@ final class RiotSettings: NSObject {
var userInterfaceTheme: String? {
get {
return UserDefaults.standard.string(forKey: UserDefaultsKeys.userInterfaceTheme)
return defaults.string(forKey: UserDefaultsKeys.userInterfaceTheme)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.userInterfaceTheme)
defaults.set(newValue, forKey: UserDefaultsKeys.userInterfaceTheme)
}
}
@ -88,22 +110,22 @@ final class RiotSettings: NSObject {
/// Indicate if `enableCrashReport` settings has been set once.
var isEnableCrashReportHasBeenSetOnce: Bool {
return UserDefaults.standard.object(forKey: UserDefaultsKeys.enableCrashReport) != nil
return defaults.object(forKey: UserDefaultsKeys.enableCrashReport) != nil
}
var enableCrashReport: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.enableCrashReport)
return defaults.bool(forKey: UserDefaultsKeys.enableCrashReport)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.enableCrashReport)
defaults.set(newValue, forKey: UserDefaultsKeys.enableCrashReport)
}
}
var enableRageShake: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.enableRageShake)
return defaults.bool(forKey: UserDefaultsKeys.enableRageShake)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.enableRageShake)
defaults.set(newValue, forKey: UserDefaultsKeys.enableRageShake)
}
}
@ -111,9 +133,9 @@ final class RiotSettings: NSObject {
var createConferenceCallsWithJitsi: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.createConferenceCallsWithJitsi)
return defaults.bool(forKey: UserDefaultsKeys.createConferenceCallsWithJitsi)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.createConferenceCallsWithJitsi)
defaults.set(newValue, forKey: UserDefaultsKeys.createConferenceCallsWithJitsi)
}
}
@ -121,36 +143,36 @@ final class RiotSettings: NSObject {
/// Indicate if `allowStunServerFallback` settings has been set once.
var isAllowStunServerFallbackHasBeenSetOnce: Bool {
return UserDefaults.standard.object(forKey: UserDefaultsKeys.allowStunServerFallback) != nil
return defaults.object(forKey: UserDefaultsKeys.allowStunServerFallback) != nil
}
var allowStunServerFallback: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.allowStunServerFallback)
return defaults.bool(forKey: UserDefaultsKeys.allowStunServerFallback)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.allowStunServerFallback)
defaults.set(newValue, forKey: UserDefaultsKeys.allowStunServerFallback)
}
}
var stunServerFallback: String? {
return UserDefaults.standard.string(forKey: UserDefaultsKeys.stunServerFallback)
return defaults.string(forKey: UserDefaultsKeys.stunServerFallback)
}
// MARK: Key verification
var hideVerifyThisSessionAlert: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
return defaults.bool(forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
defaults.set(newValue, forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
}
}
var hideReviewSessionsAlert: Bool {
get {
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.hideReviewSessionsAlert)
return defaults.bool(forKey: UserDefaultsKeys.hideReviewSessionsAlert)
} set {
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.hideReviewSessionsAlert)
defaults.set(newValue, forKey: UserDefaultsKeys.hideReviewSessionsAlert)
}
}
}

View file

@ -87,9 +87,7 @@ enum
enum
{
CALLS_ENABLE_CALLKIT_INDEX = 0,
CALLS_CALLKIT_DESCRIPTION_INDEX,
CALLS_ENABLE_STUN_SERVER_FALLBACK_INDEX,
CALLS_ENABLE_STUN_SERVER_FALLBACK_INDEX=0,
CALLS_STUN_SERVER_FALLBACK_DESCRIPTION_INDEX,
CALLS_COUNT
};
@ -1732,39 +1730,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
}
else if (section == SETTINGS_SECTION_CALLS_INDEX)
{
if (row == CALLS_ENABLE_CALLKIT_INDEX)
{
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_enable_callkit", @"Vector", nil);
labelAndSwitchCell.mxkSwitch.on = [MXKAppSettings standardAppSettings].isCallKitEnabled;
labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor;
labelAndSwitchCell.mxkSwitch.enabled = YES;
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleCallKit:) forControlEvents:UIControlEventTouchUpInside];
if (![MXCallKitAdapter callKitAvailable])
{
labelAndSwitchCell.mxkSwitch.on = NO;
labelAndSwitchCell.mxkSwitch.enabled = NO;
labelAndSwitchCell.mxkLabel.enabled = NO;
}
cell = labelAndSwitchCell;
}
else if (row == CALLS_CALLKIT_DESCRIPTION_INDEX)
{
MXKTableViewCell *globalInfoCell = [self getDefaultTableViewCell:tableView];
globalInfoCell.textLabel.text = NSLocalizedStringFromTable(@"settings_callkit_info", @"Vector", nil);
globalInfoCell.textLabel.numberOfLines = 0;
globalInfoCell.selectionStyle = UITableViewCellSelectionStyleNone;
if (![MXCallKitAdapter callKitAvailable])
{
globalInfoCell.textLabel.enabled = NO;
}
cell = globalInfoCell;
}
else if (row == CALLS_ENABLE_STUN_SERVER_FALLBACK_INDEX)
if (row == CALLS_ENABLE_STUN_SERVER_FALLBACK_INDEX)
{
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_calls_stun_server_fallback_button", @"Vector", nil);
@ -2849,10 +2815,10 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
MXKAccountManager *accountManager = [MXKAccountManager sharedManager];
MXKAccount* account = accountManager.activeAccounts.firstObject;
if (accountManager.pushDeviceToken)
if (accountManager.apnsDeviceToken)
{
[account enablePushKitNotifications:!account.isPushKitNotificationActive success:^{
[account enablePushNotifications:!account.pushNotificationServiceIsActive success:^{
[self stopActivityIndicator];
} failure:^(NSError *error) {
[self stopActivityIndicator];
@ -2869,7 +2835,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
}
else
{
[account enablePushKitNotifications:YES success:^{
[account enablePushNotifications:YES success:^{
[self stopActivityIndicator];
} failure:^(NSError *error) {
[self stopActivityIndicator];

View file

@ -0,0 +1,23 @@
/*
Copyright 2020 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import Foundation
enum Constants {
static let toBeRemovedNotificationCategoryIdentifier = "TO_BE_REMOVED"
}

31
RiotNSE/Info.plist Normal file
View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>RiotNSE</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.usernotifications.service</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
</dict>
</dict>
</plist>

View file

@ -0,0 +1,90 @@
/*
Copyright 2020 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import Foundation
import MatrixSDK
/// Fake memory store implementation. Uses some real values from an MXFileStore instance.
class NSEMemoryStore: MXMemoryStore {
private var credentials: MXCredentials
// real store
private var fileStore: MXFileStore
init(withCredentials credentials: MXCredentials) {
self.credentials = credentials
fileStore = MXFileStore(credentials: credentials)
// load real eventStreamToken
fileStore.loadMetaData()
}
// Return real eventStreamToken, to be able to launch a meaningful background sync
override var eventStreamToken: String? {
get {
return fileStore.eventStreamToken
} set {
// no-op
}
}
// Return real userAccountData, to be able to use push rules
override var userAccountData: [AnyHashable : Any]? {
get {
return fileStore.userAccountData
} set {
// no-op
}
}
// This store should act like as a permanent one
override var isPermanent: Bool {
return true
}
// Some mandatory methods to implement to be permanent
override func storeState(forRoom roomId: String, stateEvents: [MXEvent]) {
// no-op
}
// Fetch real room state
override func state(ofRoom roomId: String, success: @escaping ([MXEvent]) -> Void, failure: ((Error) -> Void)? = nil) {
fileStore.state(ofRoom: roomId, success: success, failure: failure)
}
// Fetch real soom summary
override func summary(ofRoom roomId: String) -> MXRoomSummary? {
return fileStore.summary(ofRoom: roomId)
}
// Fetch real room account data
override func accountData(ofRoom roomId: String) -> MXRoomAccountData? {
return fileStore.accountData(ofRoom: roomId)
}
// Override and return a user to be stored on session.myUser
override func user(withUserId userId: String) -> MXUser? {
if userId == credentials.userId {
return MXMyUser(userId: userId)
}
return MXUser(userId: userId)
}
override func close() {
// close real store
fileStore.close()
}
}

View file

@ -0,0 +1,520 @@
/*
Copyright 2020 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import UserNotifications
import MatrixKit
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var originalContent: UNMutableNotificationContent?
var mxSession: MXSession?
var store: NSEMemoryStore!
var showDecryptedContentInNotifications: Bool {
return RiotSettings.shared.showDecryptedContentInNotifications
}
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
// save this content as fallback content
originalContent = request.content.mutableCopy() as? UNMutableNotificationContent
UNUserNotificationCenter.current().removeUnwantedNotifications()
// check if this is a Matrix notification
guard let content = originalContent else {
return
}
let userInfo = content.userInfo
NSLog("[NotificationService] Payload came: \(userInfo)")
guard let roomId = userInfo["room_id"] as? String, let _ = userInfo["event_id"] as? String else {
// it's not a Matrix notification, do not change the content
NSLog("[NotificationService] didReceiveRequest: This is not a Matrix notification.")
contentHandler(content)
return
}
// setup user account
setup(withRoomId: roomId) {
// fetch the event first
self.fetchEvent()
}
}
override func serviceExtensionTimeWillExpire() {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
NSLog("[NotificationService] serviceExtensionTimeWillExpire")
fallbackToOriginalContent()
}
func setup(withRoomId roomId: String, completion: @escaping () -> Void) {
let sdkOptions = MXSDKOptions.sharedInstance()
sdkOptions.applicationGroupIdentifier = "group.im.vector"
sdkOptions.disableIdenticonUseForUserAvatar = true
sdkOptions.enableCryptoWhenStartingMXSession = true
sdkOptions.backgroundModeHandler = MXUIKitBackgroundModeHandler()
Bundle.mxk_customizeLocalizedStringTableName("Vector")
if isatty(STDERR_FILENO) == 0 {
MXLogger.setSubLogName("nse")
MXLogger.redirectNSLog(toFiles: true)
}
if let userAccount = MXKAccountManager.shared()?.activeAccounts.first {
store = NSEMemoryStore(withCredentials: userAccount.mxCredentials)
// Fake roomStores in memory store. This is for both -[MXMemoryStore rooms] and -[MXSession rooms] to return some rooms.
// Also roomsSummaries will be filled with the room summary for this roomId.
// They all will be used afterwards.
store.getOrCreateRoomStore(roomId)
mxSession = MXSession(matrixRestClient: MXRestClient(credentials: userAccount.mxCredentials, unrecognizedCertificateHandler: nil))
mxSession?.setStore(store, completion: { (response) in
switch response {
case .success:
completion()
break
case .failure(let error):
NSLog("[NotificationService] setup: MXSession.setStore method returned error: \(String(describing: error))")
self.fallbackToOriginalContent()
break
}
})
}
}
func fetchEvent() {
guard let content = originalContent, let mxSession = mxSession else {
// there is something wrong, do not change the content
NSLog("[NotificationService] fetchEvent: Either originalContent or mxSession is missing.")
fallbackToOriginalContent()
return
}
let userInfo = content.userInfo
guard let roomId = userInfo["room_id"] as? String, let eventId = userInfo["event_id"] as? String else {
// it's not a Matrix notification, do not change the content
NSLog("[NotificationService] fetchEvent: This is not a Matrix notification.")
contentHandler?(content)
return
}
mxSession.event(withEventId: eventId, inRoom: roomId, success: { [weak self] (event) in
guard let self = self else {
NSLog("[NotificationService] fetchEvent: MXSession.event method returned too late successfully.")
return
}
guard let event = event else {
self.fallbackToOriginalContent()
return
}
if !event.isEncrypted {
// not encrypted, go on processing
self.processEvent(event)
return
}
// encrypted
if !self.showDecryptedContentInNotifications {
// do not show decrypted content in notification
self.fallbackToOriginalContent()
return
}
// should show decrypted content in notification
if event.clear != nil {
// already decrypted
self.processEvent(event)
return
}
// should decrypt it first
if mxSession.decryptEvent(event, inTimeline: nil) {
// decryption succeeded
self.processEvent(event)
} else {
// decryption failed
NSLog("[NotificationService] fetchEvent: Event needs to be decrpyted, but we don't have the keys to decrypt it. Launching a background sync.")
self.launchBackgroundSync()
}
}) { [weak self] (error) in
guard let self = self else {
NSLog("[NotificationService] fetchEvent: MXSession.event method returned too late with error: \(String(describing: error))")
return
}
NSLog("[NotificationService] fetchEvent: MXSession.event method returned error: \(String(describing: error))")
self.fallbackToOriginalContent()
}
}
func launchBackgroundSync() {
guard let mxSession = mxSession else {
NSLog("[NotificationService] launchBackgroundSync: mxSession is missing.")
self.fallbackToOriginalContent()
return
}
// launch an initial background sync
mxSession.backgroundSync(withTimeout: 20, ignoreSessionState: true) { [weak self] (response) in
switch response {
case .success:
guard let self = self else {
NSLog("[NotificationService] launchBackgroundSync: MXSession.initialBackgroundSync returned too late successfully")
return
}
self.fetchEvent()
break
case .failure(let error):
guard let self = self else {
NSLog("[NotificationService] launchBackgroundSync: MXSession.initialBackgroundSync returned too late with error: \(String(describing: error))")
return
}
NSLog("[NotificationService] launchBackgroundSync: MXSession.initialBackgroundSync returned with error: \(String(describing: error))")
self.fallbackToOriginalContent()
break
}
}
}
func processEvent(_ event: MXEvent) {
guard let content = originalContent, let mxSession = mxSession else {
self.fallbackToOriginalContent()
return
}
self.notificationContent(forEvent: event, inSession: mxSession) { (notificationContent) in
// close store
self.store.close()
// Modify the notification content here...
if let newContent = notificationContent {
content.title = newContent.title
content.subtitle = newContent.subtitle
content.body = newContent.body
content.threadIdentifier = newContent.threadIdentifier
content.categoryIdentifier = newContent.categoryIdentifier
content.userInfo = newContent.userInfo
content.sound = newContent.sound
} else {
// this is an unwanted notification, mark as to be deleted when app is foregrounded again OR a new push came
content.categoryIdentifier = Constants.toBeRemovedNotificationCategoryIdentifier
}
self.contentHandler?(content)
}
}
func fallbackToOriginalContent() {
store.close()
guard let content = originalContent else {
NSLog("[NotificationService] fallbackToOriginalContent: Original content is missing.")
return
}
// call contentHandler
contentHandler?(content)
}
func notificationContent(forEvent event: MXEvent, inSession session: MXSession, onComplete: @escaping (UNNotificationContent?) -> Void) {
guard let content = event.content, content.count > 0 else {
NSLog("[NotificationService][Push] notificationContentForEvent: empty event content")
onComplete(nil)
return
}
guard let room = session.room(withRoomId: event.roomId) else {
NSLog("[NotificationService][Push] notificationBodyForEvent: Unknown room")
onComplete(nil)
return
}
let pushRule = room.getRoomPushRule()
room.state { (roomState) in
guard let roomState = roomState else {
NSLog("[NotificationService] notificationContentForEvent: Could not load the room state")
onComplete(nil)
return
}
var notificationTitle: String?
var notificationBody: String?
var threadIdentifier = room.roomId
let eventSenderName = roomState.members.memberName(event.sender)
let currentUserId = session.credentials.userId
switch event.eventType {
case .roomMessage, .roomEncrypted:
if room.isMentionsOnly {
// A local notification will be displayed only for highlighted notification.
var isHighlighted = false
// Check whether is there an highlight tweak on it
for ruleAction in pushRule?.actions ?? [] {
guard let action = ruleAction as? MXPushRuleAction else { continue }
guard action.actionType == MXPushRuleActionTypeSetTweak else { continue }
guard action.parameters["set_tweak"] as? String == "highlight" else { continue }
// Check the highlight tweak "value"
// If not present, highlight. Else check its value before highlighting
if nil == action.parameters["value"] || true == (action.parameters["value"] as? Bool) {
isHighlighted = true
break
}
}
if !isHighlighted {
// Ignore this notif.
NSLog("[NotificationService][Push] notificationBodyForEvent: Ignore non highlighted notif in mentions only room")
onComplete(nil)
return
}
}
var msgType = event.content["msgtype"] as? String
let messageContent = event.content["body"] as? String
if event.isEncrypted && !self.showDecryptedContentInNotifications {
// Hide the content
msgType = nil
}
let roomDisplayName = room.summary.displayname
let myUserId = session.myUser.userId
let isIncomingEvent = event.sender != myUserId
// Display the room name only if it is different than the sender name
if roomDisplayName != nil && roomDisplayName != eventSenderName {
notificationTitle = NSString.localizedUserNotificationString(forKey: "MSG_FROM_USER_IN_ROOM_TITLE", arguments: [eventSenderName as Any, roomDisplayName as Any])
if msgType == kMXMessageTypeText {
notificationBody = messageContent
} else if msgType == kMXMessageTypeEmote {
notificationBody = NSString.localizedUserNotificationString(forKey: "ACTION_FROM_USER", arguments: [eventSenderName as Any, messageContent as Any])
} else if msgType == kMXMessageTypeImage {
notificationBody = NSString.localizedUserNotificationString(forKey: "IMAGE_FROM_USER", arguments: [eventSenderName as Any, messageContent as Any])
} else if room.isDirect && isIncomingEvent && msgType == kMXMessageTypeKeyVerificationRequest {
session.crypto.keyVerificationManager.keyVerification(fromKeyVerificationEvent: event,
success:{ (keyVerification) in
guard let request = keyVerification.request, request.state == MXKeyVerificationRequestStatePending else {
onComplete(nil)
return
}
// TODO: Add accept and decline actions to notification
let body = NSString.localizedUserNotificationString(forKey: "KEY_VERIFICATION_REQUEST_FROM_USER", arguments: [eventSenderName as Any])
let notificationContent = self.notificationContent(withTitle: notificationTitle,
body: body,
threadIdentifier: threadIdentifier,
userId: currentUserId,
event: event,
pushRule: pushRule)
onComplete(notificationContent)
}, failure:{ (error) in
NSLog("[NotificationService][Push] notificationContentForEvent: failed to fetch key verification with error: \(error)")
onComplete(nil)
})
} else {
// Encrypted messages falls here
notificationBody = NSString.localizedUserNotificationString(forKey: "MSG_FROM_USER", arguments: [eventSenderName as Any])
}
} else {
notificationTitle = eventSenderName
switch msgType {
case kMXMessageTypeText:
notificationBody = messageContent
break
case kMXMessageTypeEmote:
notificationBody = NSString.localizedUserNotificationString(forKey: "ACTION_FROM_USER", arguments: [eventSenderName as Any, messageContent as Any])
break
case kMXMessageTypeImage:
notificationBody = NSString.localizedUserNotificationString(forKey: "IMAGE_FROM_USER", arguments: [eventSenderName as Any, messageContent as Any])
break
default:
// Encrypted messages falls here
notificationBody = NSString.localizedUserNotificationString(forKey: "MSG_FROM_USER", arguments: [eventSenderName as Any])
break
}
}
break
case .callInvite:
let offer = event.content["offer"] as? [AnyHashable: Any]
let sdp = offer?["sdp"] as? String
let isVideoCall = sdp?.contains("m=video") ?? false
if isVideoCall {
notificationBody = NSString.localizedUserNotificationString(forKey: "VIDEO_CALL_FROM_USER", arguments: [eventSenderName as Any])
} else {
notificationBody = NSString.localizedUserNotificationString(forKey: "VOICE_CALL_FROM_USER", arguments: [eventSenderName as Any])
}
// call notifications should stand out from normal messages, so we don't stack them
threadIdentifier = nil
case .roomMember:
let roomDisplayName = room.summary.displayname
if roomDisplayName != nil && roomDisplayName != eventSenderName {
notificationBody = NSString.localizedUserNotificationString(forKey: "USER_INVITE_TO_NAMED_ROOM", arguments: [eventSenderName as Any, roomDisplayName as Any])
} else {
notificationBody = NSString.localizedUserNotificationString(forKey: "USER_INVITE_TO_CHAT", arguments: [eventSenderName as Any])
}
case .sticker:
let roomDisplayName = room.summary.displayname
if roomDisplayName != nil && roomDisplayName != eventSenderName {
notificationTitle = NSString.localizedUserNotificationString(forKey: "MSG_FROM_USER_IN_ROOM_TITLE", arguments: [eventSenderName as Any, roomDisplayName as Any])
} else {
notificationTitle = eventSenderName
}
notificationBody = NSString.localizedUserNotificationString(forKey: "STICKER_FROM_USER", arguments: [eventSenderName as Any])
default:
break
}
guard (notificationBody != nil) else {
onComplete(nil)
return
}
let notificationContent = self.notificationContent(withTitle: notificationTitle,
body: notificationBody,
threadIdentifier: threadIdentifier,
userId: currentUserId,
event: event,
pushRule: pushRule)
onComplete(notificationContent)
}
}
func notificationContent(withTitle title: String?,
body: String?,
threadIdentifier: String?,
userId: String?,
event: MXEvent,
pushRule: MXPushRule?) -> UNNotificationContent {
let notificationContent = UNMutableNotificationContent()
if let title = title {
notificationContent.title = title
}
if let body = body {
notificationContent.body = body
}
if let threadIdentifier = threadIdentifier {
notificationContent.threadIdentifier = threadIdentifier
}
if let categoryIdentifier = self.notificationCategoryIdentifier(forEvent: event) {
notificationContent.categoryIdentifier = categoryIdentifier
}
if let soundName = notificationSoundName(fromPushRule: pushRule) {
notificationContent.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: soundName))
} else {
notificationContent.sound = UNNotificationSound.default
}
notificationContent.userInfo = notificationUserInfo(forEvent: event, andUserId: userId)
return notificationContent
}
func notificationUserInfo(forEvent event: MXEvent, andUserId userId: String?) -> [AnyHashable: Any] {
var notificationUserInfo: [AnyHashable: Any] = [
"type": "full",
"room_id": event.roomId as Any,
"event_id": event.eventId as Any
]
if let userId = userId {
notificationUserInfo["user_id"] = userId
}
return notificationUserInfo
}
func notificationSoundName(fromPushRule pushRule: MXPushRule?) -> String? {
var soundName: String?
// Set sound name based on the value provided in action of MXPushRule
for ruleAction in pushRule?.actions ?? [] {
guard let action = ruleAction as? MXPushRuleAction else { continue }
guard action.actionType == MXPushRuleActionTypeSetTweak else { continue }
guard action.parameters["set_tweak"] as? String == "sound" else { continue }
soundName = action.parameters["value"] as? String
if soundName == "default" {
soundName = "message.caf"
}
}
return soundName
}
func notificationCategoryIdentifier(forEvent event: MXEvent) -> String? {
let isNotificationContentShown = !event.isEncrypted || self.showDecryptedContentInNotifications
guard isNotificationContentShown else {
return nil
}
guard event.eventType == .roomMessage || event.eventType == .roomEncrypted else {
return nil
}
return "QUICK_REPLY"
}
}
extension MXRoom {
func getRoomPushRule() -> MXPushRule? {
guard let rules = self.mxSession.notificationCenter.rules.global.room else {
return nil
}
for rule in rules {
guard let pushRule = rule as? MXPushRule else { continue }
// the rule id is the room Id
// it is the server trick to avoid duplicated rule on the same room.
if pushRule.ruleId == self.roomId {
return pushRule
}
}
return nil
}
var isMentionsOnly: Bool {
// Check push rules at room level
guard let rule = self.getRoomPushRule() else {
return false
}
for ruleAction in rule.actions {
guard let action = ruleAction as? MXPushRuleAction else { continue }
if action.actionType == MXPushRuleActionTypeDontNotify {
return rule.enabled
}
}
return false
}
}

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.im.vector</string>
</array>
</dict>
</plist>

View file

@ -6,10 +6,12 @@ SCHEME=Riot
MAIN_TARGET=Riot
SHARE_EXTENSION_TARGET=RiotShareExtension
SIRI_INTENTS_EXTENSION_TARGET=SiriIntents
NSE_TARGET=RiotNSE
MAIN_BUNDLE_ID=im.vector.app
SHARE_EXTENSION_BUNDLE_ID=im.vector.app.shareExtension
SIRI_INTENTS_EXTENSION_BUNDLE_ID=im.vector.app.SiriIntents
NSE_BUNDLE_ID=im.vector.app.nse
## Build configuration
@ -26,6 +28,7 @@ PROVISIONING_PROFILES_PATH=./provisioning_profiles/
MAIN_PROVISIONING_PROFILE_FILENAME=main.mobileprovision
SHARE_EXTENSION_PROVISIONING_PROFILE_FILENAME=share_extension.mobileprovision
SIRI_INTENTS_EXTENSION_PROVISIONING_PROFILE_FILENAME=siri_intents.mobileprovision
NSE_PROVISIONING_PROFILE_FILENAME=nse.mobileprovision
## App Store code signing
@ -35,12 +38,14 @@ APPSTORE_SIGNING_CERTIFICATE="iPhone Distribution: Vector Creations Limited (7J4
APPSTORE_MAIN_PROVISIONING_PROFILE_SPECIFIER="Vector App Store"
APPSTORE_SHARE_EXTENSION_PROVISIONING_PROFILE_SPECIFIER="Vector Share Extension: App Store"
APPSTORE_SIRI_INTENTS_EXTENSION_PROVISIONING_PROFILE_SPECIFIER="Vector Siri Intents: App Store"
APPSTORE_NSE_PROVISIONING_PROFILE_SPECIFIER="Vector NSE: App Store"
## Ad-Hoc code signing
ADHOC_MAIN_PROVISIONING_PROFILE_SPECIFIER="Vector Ad Hoc"
ADHOC_SHARE_EXTENSION_PROVISIONING_PROFILE_SPECIFIER="Vector Share Extension: Ad Hoc
ADHOC_SIRI_INTENTS_EXTENSION_PROVISIONING_PROFILE_SPECIFIER="Vector Siri Intents: Ad Hoc"
ADHOC_NSE_PROVISIONING_PROFILE_SPECIFIER="Vector NSE: Ad Hoc"
## Account information

View file

@ -101,11 +101,13 @@ platform :ios do
main_provisioning_profile = ENV["ADHOC_MAIN_PROVISIONING_PROFILE_SPECIFIER"]
share_extension_provisioning_profile = ENV["ADHOC_SHARE_EXTENSION_PROVISIONING_PROFILE_SPECIFIER"]
siri_intents_provisioning_profile = ENV["ADHOC_SIRI_INTENTS_EXTENSION_PROVISIONING_PROFILE_SPECIFIER"]
nse_provisioning_profile = ENV["ADHOC_NSE_PROVISIONING_PROFILE_SPECIFIER"]
else
export_method = "app-store"
main_provisioning_profile = ENV["APPSTORE_MAIN_PROVISIONING_PROFILE_SPECIFIER"]
share_extension_provisioning_profile = ENV["APPSTORE_SHARE_EXTENSION_PROVISIONING_PROFILE_SPECIFIER"]
siri_intents_provisioning_profile = ENV["APPSTORE_SIRI_INTENTS_EXTENSION_PROVISIONING_PROFILE_SPECIFIER"]
nse_provisioning_profile = ENV["APPSTORE_NSE_PROVISIONING_PROFILE_SPECIFIER"]
end
# Build app and create ipa
@ -130,6 +132,7 @@ platform :ios do
ENV["MAIN_BUNDLE_ID"] => main_provisioning_profile,
ENV["SHARE_EXTENSION_BUNDLE_ID"] => share_extension_provisioning_profile,
ENV["SIRI_INTENTS_EXTENSION_BUNDLE_ID"] => siri_intents_provisioning_profile
ENV["NSE_BUNDLE_ID"] => nse_provisioning_profile
},
iCloudContainerEnvironment: 'Production'
}
@ -172,6 +175,15 @@ platform :ios do
filename: ENV["SIRI_INTENTS_EXTENSION_PROVISIONING_PROFILE_FILENAME"],
readonly: true
)
# NSE
get_provisioning_profile(
app_identifier: ENV["NSE_BUNDLE_ID"],
adhoc: adhoc,
skip_certificate_verification: skip_certificate_verification,
output_path: output_path,
filename: ENV["NSE_PROVISIONING_PROFILE_FILENAME"],
readonly: true
)
end
desc "Update provisioning profiles for each target"
@ -201,6 +213,13 @@ platform :ios do
target_filter: ENV["SIRI_INTENTS_EXTENSION_TARGET"],
build_configuration: build_configuration
)
# NSE
update_project_provisioning(
xcodeproj: xcodeproj,
profile: "#{provisioning_profiles_path}#{ENV["NSE_PROVISIONING_PROFILE_FILENAME"]}",
target_filter: ENV["NSE_TARGET"],
build_configuration: build_configuration
)
end
desc "Update application build number for all targets"
@ -222,6 +241,11 @@ platform :ios do
build_number: build_number,
target: ENV["SIRI_INTENTS_EXTENSION_TARGET"]
)
# NSE
increment_build_number_in_plist(
build_number: build_number,
target: ENV["NSE_TARGET"]
)
end
desc "Returns version identifiers hash to inject in GCC_PREPROCESSOR_DEFINITIONS for release builds"