mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-16 06:28:27 +02:00
Create notification service extension
Signed-off-by: ismailgulek <gulekismail@gmail.com>
This commit is contained in:
4
Podfile
4
Podfile
@@ -93,6 +93,10 @@ abstract_target 'RiotPods' do
|
||||
import_MatrixKitAppExtension
|
||||
end
|
||||
|
||||
target "RiotNSE" do
|
||||
import_MatrixKitAppExtension
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -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,9 @@
|
||||
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 */; };
|
||||
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 +755,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 +780,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 +791,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 +925,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 +1687,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 +1715,10 @@
|
||||
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>"; };
|
||||
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 +1782,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 +2138,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 +2152,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 +4277,16 @@
|
||||
path = PushNotification;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EC85D7442477E5F7002C44C9 /* RiotNSE */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EC85D74E2477E614002C44C9 /* RiotNSE.entitlements */,
|
||||
EC85D7452477E5F7002C44C9 /* NotificationService.swift */,
|
||||
EC85D7472477E5F7002C44C9 /* Info.plist */,
|
||||
);
|
||||
path = RiotNSE;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F083BB021E7005FD00A9B29C /* RiotTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -4407,6 +4447,7 @@
|
||||
F083BB021E7005FD00A9B29C /* RiotTests */,
|
||||
24CBEC4F1F0EAD310093EABB /* RiotShareExtension */,
|
||||
92726A441F58737A004AD26F /* SiriIntents */,
|
||||
EC85D7442477E5F7002C44C9 /* RiotNSE */,
|
||||
F094A9A31B78D8F000B1FBBF /* Products */,
|
||||
5FC42FA41F5186AFFB6A2404 /* Frameworks */,
|
||||
3232AAFE22564D9100AD6A5C /* Tools */,
|
||||
@@ -4422,6 +4463,7 @@
|
||||
F094A9BE1B78D8F000B1FBBF /* RiotTests.xctest */,
|
||||
24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */,
|
||||
92726A431F58737A004AD26F /* SiriIntents.appex */,
|
||||
EC85D7432477E5F7002C44C9 /* RiotNSE.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -4465,6 +4507,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 +4543,7 @@
|
||||
dependencies = (
|
||||
242661F61F12B1BA00D3FC08 /* PBXTargetDependency */,
|
||||
92726A4A1F58737A004AD26F /* PBXTargetDependency */,
|
||||
EC85D7492477E5F7002C44C9 /* PBXTargetDependency */,
|
||||
);
|
||||
name = Riot;
|
||||
productName = Vector;
|
||||
@@ -4514,6 +4575,8 @@
|
||||
F094A99A1B78D8F000B1FBBF /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
DefaultBuildSystemTypeForWorkspace = Original;
|
||||
LastSwiftUpdateCheck = 1130;
|
||||
LastUpgradeCheck = 0940;
|
||||
ORGANIZATIONNAME = matrix.org;
|
||||
TargetAttributes = {
|
||||
@@ -4538,6 +4601,9 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
EC85D7422477E5F7002C44C9 = {
|
||||
CreatedOnToolsVersion = 11.3.1;
|
||||
};
|
||||
F094A9A11B78D8F000B1FBBF = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
DevelopmentTeam = 7J4U792NQT;
|
||||
@@ -4599,6 +4665,7 @@
|
||||
F094A9BD1B78D8F000B1FBBF /* RiotTests */,
|
||||
24CBEC4D1F0EAD310093EABB /* RiotShareExtension */,
|
||||
92726A421F58737A004AD26F /* SiriIntents */,
|
||||
EC85D7422477E5F7002C44C9 /* RiotNSE */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -4625,6 +4692,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
EC85D7412477E5F7002C44C9 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F094A9A01B78D8F000B1FBBF /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -4934,6 +5008,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 +5093,15 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
EC85D73F2477E5F7002C44C9 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EC85D74F2477E8EB002C44C9 /* RiotSettings.swift in Sources */,
|
||||
EC85D7462477E5F7002C44C9 /* NotificationService.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F094A99E1B78D8F000B1FBBF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -5540,6 +5645,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 +5901,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 +6228,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 = (
|
||||
|
||||
@@ -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];
|
||||
@@ -4541,6 +4566,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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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,83 @@
|
||||
|
||||
- (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);
|
||||
//
|
||||
// // Display local notifications only when the app is running in background.
|
||||
// if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
|
||||
// {
|
||||
// NSLog(@"[PushNotificationService][Push] didReceiveRemoteNotification while app is in background");
|
||||
//
|
||||
// // Check whether an event id is provided.
|
||||
// NSString *eventId = userInfo[@"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] = userInfo;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// NSLog(@"[PushNotificationService][Push] didReceiveRemoteNotification - Unexpected payload %@", userInfo);
|
||||
// }
|
||||
//
|
||||
// // Trigger a background sync to handle notifications.
|
||||
// [self launchBackgroundSync];
|
||||
// }
|
||||
//
|
||||
completionHandler(UIBackgroundFetchResultNewData);
|
||||
}
|
||||
|
||||
- (void)deregisterRemoteNotifications
|
||||
{
|
||||
self.pushRegistry = nil;
|
||||
_isPushRegistered = NO;
|
||||
}
|
||||
|
||||
@@ -259,64 +326,64 @@
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - PKPushRegistryDelegate
|
||||
//#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 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];
|
||||
}
|
||||
}
|
||||
//- (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
|
||||
|
||||
@@ -374,12 +441,13 @@
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
//- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
|
||||
//{
|
||||
// NSLog(@"[PushNotificationService][Push] willPresentNotification: applicationState: %@", @([UIApplication sharedApplication].applicationState));
|
||||
//
|
||||
//// completionHandler(UNNotificationPresentationOptionNone);
|
||||
// completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
|
||||
//}
|
||||
|
||||
#pragma mark - Other Methods
|
||||
|
||||
@@ -607,7 +675,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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,9 +87,9 @@ enum
|
||||
|
||||
enum
|
||||
{
|
||||
CALLS_ENABLE_CALLKIT_INDEX = 0,
|
||||
CALLS_CALLKIT_DESCRIPTION_INDEX,
|
||||
CALLS_ENABLE_STUN_SERVER_FALLBACK_INDEX,
|
||||
//CALLS_ENABLE_CALLKIT_INDEX = 0,
|
||||
//CALLS_CALLKIT_DESCRIPTION_INDEX,
|
||||
CALLS_ENABLE_STUN_SERVER_FALLBACK_INDEX=0,
|
||||
CALLS_STUN_SERVER_FALLBACK_DESCRIPTION_INDEX,
|
||||
CALLS_COUNT
|
||||
};
|
||||
@@ -1731,39 +1731,40 @@ 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_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)
|
||||
{
|
||||
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_calls_stun_server_fallback_button", @"Vector", nil);
|
||||
@@ -2848,10 +2849,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];
|
||||
@@ -2868,7 +2869,7 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
||||
}
|
||||
else
|
||||
{
|
||||
[account enablePushKitNotifications:YES success:^{
|
||||
[account enablePushNotifications:YES success:^{
|
||||
[self stopActivityIndicator];
|
||||
} failure:^(NSError *error) {
|
||||
[self stopActivityIndicator];
|
||||
|
||||
31
RiotNSE/Info.plist
Normal file
31
RiotNSE/Info.plist
Normal 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>
|
||||
482
RiotNSE/NotificationService.swift
Normal file
482
RiotNSE/NotificationService.swift
Normal file
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
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 requestIdentifier: String?
|
||||
var contentHandler: ((UNNotificationContent) -> Void)?
|
||||
var originalContent: UNMutableNotificationContent?
|
||||
|
||||
var userAccount: MXKAccount?
|
||||
var store: MXFileStore?
|
||||
var showDecryptedContentInNotifications: Bool {
|
||||
return RiotSettings.shared.showDecryptedContentInNotifications
|
||||
}
|
||||
|
||||
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||
self.contentHandler = contentHandler
|
||||
requestIdentifier = request.identifier
|
||||
// save this content as fallback content
|
||||
originalContent = request.content.mutableCopy() as? UNMutableNotificationContent
|
||||
|
||||
// check if this is a Matrix notification
|
||||
if let content = originalContent {
|
||||
let userInfo = content.userInfo
|
||||
NSLog("[NotificationService] Payload came: \(userInfo) with identifier: \(requestIdentifier!)")
|
||||
let roomId = userInfo["room_id"] as? String
|
||||
let eventId = userInfo["event_id"] as? String
|
||||
|
||||
guard roomId != nil, eventId != nil else {
|
||||
// it's not a Matrix notification, do not change the content
|
||||
NSLog("[NotificationService] Fallback case 7")
|
||||
contentHandler(content)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// setup user account
|
||||
setup()
|
||||
|
||||
// fetch the event first
|
||||
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] Fallback case 5")
|
||||
fallbackToOriginalContent()
|
||||
}
|
||||
|
||||
func setup() {
|
||||
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)
|
||||
}
|
||||
|
||||
userAccount = MXKAccountManager.shared()?.activeAccounts.first
|
||||
|
||||
if let theUserAccount = userAccount {
|
||||
store = MXFileStore(credentials: theUserAccount.mxCredentials)
|
||||
|
||||
if theUserAccount.mxSession == nil {
|
||||
theUserAccount.openSession(with: store!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fetchEvent() {
|
||||
if let content = originalContent, let theUserAccount = self.userAccount {
|
||||
let userInfo = content.userInfo
|
||||
let roomId = userInfo["room_id"] as? String
|
||||
let eventId = userInfo["event_id"] as? String
|
||||
|
||||
guard let theRoomId = roomId, let theEventId = eventId else {
|
||||
// it's not a Matrix notification, do not change the content
|
||||
NSLog("[NotificationService] Fallback case 1")
|
||||
contentHandler?(content)
|
||||
return
|
||||
}
|
||||
|
||||
theUserAccount.mxSession.event(withEventId: theEventId, inRoom: theRoomId, success: { [weak self] (event) in
|
||||
guard let strongSelf = self else {
|
||||
NSLog("[NotificationService] Fallback case 9")
|
||||
return
|
||||
}
|
||||
|
||||
guard let theEvent = event else {
|
||||
return
|
||||
}
|
||||
|
||||
if theEvent.isEncrypted {
|
||||
// encrypted
|
||||
if strongSelf.showDecryptedContentInNotifications {
|
||||
// should show decrypted content in notification
|
||||
if theEvent.clear == nil {
|
||||
// should decrypt it first
|
||||
if theUserAccount.mxSession.decryptEvent(theEvent, inTimeline: nil) {
|
||||
// decryption succeeded
|
||||
strongSelf.processEvent(theEvent)
|
||||
} else {
|
||||
// decryption failed
|
||||
NSLog("[NotificationService] Event needs to be decrpyted, but we don't have the keys to decrypt it. Launching a background sync.")
|
||||
strongSelf.launchBackgroundSync()
|
||||
}
|
||||
} else {
|
||||
// already decrypted
|
||||
strongSelf.processEvent(theEvent)
|
||||
}
|
||||
} else {
|
||||
// do not show decrypted content in notification
|
||||
strongSelf.fallbackToOriginalContent()
|
||||
}
|
||||
} else {
|
||||
// not encrypted, go on
|
||||
strongSelf.processEvent(theEvent)
|
||||
}
|
||||
}) { [weak self] (error) in
|
||||
guard let strongSelf = self else {
|
||||
NSLog("[NotificationService] Fallback case 10")
|
||||
return
|
||||
}
|
||||
NSLog("[NotificationService] Fallback case 3")
|
||||
strongSelf.fallbackToOriginalContent()
|
||||
}
|
||||
} else {
|
||||
// there is something wrong, do not change the content
|
||||
NSLog("[NotificationService] Fallback case 4")
|
||||
fallbackToOriginalContent()
|
||||
}
|
||||
}
|
||||
|
||||
func launchBackgroundSync() {
|
||||
guard let theUserAccount = userAccount else { return }
|
||||
guard let theFileStore = store else { return }
|
||||
if theUserAccount.mxSession == nil {
|
||||
theUserAccount.openSession(with: theFileStore)
|
||||
}
|
||||
let sessionState = theUserAccount.mxSession.state
|
||||
if sessionState == MXSessionStateInitialised || sessionState == MXSessionStatePaused {
|
||||
theUserAccount.initialBackgroundSync(20000, success: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
NSLog("[NotificationService] Fallback case 12")
|
||||
return
|
||||
}
|
||||
strongSelf.fetchEvent()
|
||||
}) { [weak self] (error) in
|
||||
guard let strongSelf = self else {
|
||||
NSLog("[NotificationService] Fallback case 11")
|
||||
return
|
||||
}
|
||||
NSLog("[NotificationService] Fallback case 6")
|
||||
strongSelf.fallbackToOriginalContent()
|
||||
}
|
||||
} else {
|
||||
NSLog("[NotificationService] Fallback case 8")
|
||||
fallbackToOriginalContent()
|
||||
}
|
||||
}
|
||||
|
||||
func processEvent(_ event: MXEvent) {
|
||||
if let content = originalContent, let theUserAccount = userAccount {
|
||||
|
||||
self.notificationContent(forEvent: event, inAccount: theUserAccount) { (notificationContent) in
|
||||
self.store?.close()
|
||||
|
||||
// Modify the notification content here...
|
||||
guard let newContent = notificationContent else {
|
||||
// remove
|
||||
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [self.requestIdentifier!])
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
self.contentHandler?(content)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fallbackToOriginalContent() {
|
||||
store?.close()
|
||||
if let content = originalContent {
|
||||
contentHandler?(content)
|
||||
} else {
|
||||
NSLog("[NotificationService] Fallback case 13")
|
||||
}
|
||||
}
|
||||
|
||||
func notificationContent(forEvent event: MXEvent, inAccount account: MXKAccount, onComplete: @escaping (UNNotificationContent?) -> Void) {
|
||||
if event.content == nil || event.content!.count == 0 {
|
||||
NSLog("[NotificationService][Push] notificationContentForEvent: empty event content")
|
||||
onComplete(nil)
|
||||
return
|
||||
}
|
||||
|
||||
guard let room = account.mxSession.room(withRoomId: event.roomId) else {
|
||||
NSLog("[NotificationService][Push] notificationBodyForEvent: Unknown room")
|
||||
onComplete(nil)
|
||||
return
|
||||
}
|
||||
let pushRule = room.getRoomPushRule()
|
||||
|
||||
room.state({ (roomState:MXRoomState!) in
|
||||
|
||||
var notificationTitle: String?
|
||||
var notificationBody: String?
|
||||
|
||||
var threadIdentifier = room.roomId
|
||||
let eventSenderName = roomState.members.memberName(event.sender)
|
||||
let currentUserId = account.mxCredentials.userId
|
||||
|
||||
if event.eventType == .roomMessage || event.eventType == .roomEncrypted {
|
||||
if room.isMentionsOnly {
|
||||
// A local notification will be displayed only for highlighted notification.
|
||||
var isHighlighted:Bool = false
|
||||
|
||||
// Check whether is there an highlight tweak on it
|
||||
for ruleAction in pushRule?.actions ?? [] {
|
||||
guard let action = ruleAction as? MXPushRuleAction else { continue }
|
||||
if action.actionType == MXPushRuleActionTypeSetTweak {
|
||||
if action.parameters["set_tweak"] as? String == "highlight" {
|
||||
// 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:String! = account.mxSession.myUser.userId
|
||||
let isIncomingEvent:Bool = !(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 == "m.text") {
|
||||
notificationBody = messageContent
|
||||
} else if (msgType == "m.emote") {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "ACTION_FROM_USER", arguments:[eventSenderName as Any, messageContent as Any])
|
||||
} else if (msgType == "m.image") {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "IMAGE_FROM_USER", arguments:[eventSenderName as Any, messageContent as Any])
|
||||
} else if room.isDirect && isIncomingEvent && (msgType == kMXMessageTypeKeyVerificationRequest) {
|
||||
account.mxSession.crypto.keyVerificationManager.keyVerification(fromKeyVerificationEvent: event,
|
||||
success:{ (keyVerification) in
|
||||
if keyVerification.request != nil && keyVerification.request!.state == MXKeyVerificationRequestStatePending {
|
||||
// TODO: Add accept and decline actions to notification
|
||||
let body:String! = NSString.localizedUserNotificationString(forKey: "KEY_VERIFICATION_REQUEST_FROM_USER", arguments:[eventSenderName as Any])
|
||||
|
||||
let notificationContent:UNNotificationContent! = self.notificationContent(withTitle: notificationTitle,
|
||||
body: body,
|
||||
threadIdentifier: threadIdentifier,
|
||||
userId: currentUserId,
|
||||
event: event,
|
||||
pushRule: pushRule)
|
||||
|
||||
onComplete(notificationContent)
|
||||
} else {
|
||||
onComplete(nil)
|
||||
}
|
||||
}, 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
|
||||
|
||||
if (msgType == "m.text") {
|
||||
notificationBody = messageContent
|
||||
} else if (msgType == "m.emote") {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "ACTION_FROM_USER", arguments:[eventSenderName as Any, messageContent as Any])
|
||||
} else if (msgType == "m.image") {
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "IMAGE_FROM_USER", arguments:[eventSenderName as Any, messageContent as Any])
|
||||
} else {
|
||||
// Encrypted messages falls here
|
||||
notificationBody = NSString.localizedUserNotificationString(forKey: "MSG_FROM_USER", arguments:[eventSenderName as Any])
|
||||
}
|
||||
}
|
||||
} else if event.eventType == .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
|
||||
} else if event.eventType == .roomMember {
|
||||
let roomDisplayName:String! = 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])
|
||||
}
|
||||
} else if event.eventType == .sticker {
|
||||
let roomDisplayName:String! = 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])
|
||||
}
|
||||
|
||||
if (notificationBody != nil) {
|
||||
let notificationContent = self.notificationContent(withTitle: notificationTitle,
|
||||
body: notificationBody,
|
||||
threadIdentifier: threadIdentifier,
|
||||
userId: currentUserId,
|
||||
event: event,
|
||||
pushRule: pushRule)
|
||||
|
||||
onComplete(notificationContent)
|
||||
} else {
|
||||
onComplete(nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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 }
|
||||
|
||||
if action.actionType == MXPushRuleActionTypeSetTweak {
|
||||
if (action.parameters["set_tweak"] as? String == "sound") {
|
||||
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
|
||||
|
||||
var categoryIdentifier: String?
|
||||
|
||||
if (event.eventType == .roomMessage || event.eventType == .roomEncrypted) && isNotificationContentShown {
|
||||
categoryIdentifier = "QUICK_REPLY"
|
||||
}
|
||||
|
||||
return categoryIdentifier
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension MXRoom {
|
||||
|
||||
func getRoomPushRule() -> MXPushRule? {
|
||||
if let rules = self.mxSession.notificationCenter.rules.global.room {
|
||||
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
|
||||
if let rule = self.getRoomPushRule() {
|
||||
for ruleAction in rule.actions {
|
||||
guard let action = ruleAction as? MXPushRuleAction else { continue }
|
||||
if action.actionType == MXPushRuleActionTypeDontNotify {
|
||||
return rule.enabled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
10
RiotNSE/RiotNSE.entitlements
Normal file
10
RiotNSE/RiotNSE.entitlements
Normal 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>
|
||||
Reference in New Issue
Block a user