mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
commit
0d73c8dccf
17 changed files with 1108 additions and 148 deletions
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,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 = (
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
32
Riot/Categories/UNUserNotificationCenter.swift
Normal file
32
Riot/Categories/UNUserNotificationCenter.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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,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)
|
||||
{
|
||||
|
|
|
@ -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,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];
|
||||
|
|
23
Riot/Utils/Constants.swift
Normal file
23
Riot/Utils/Constants.swift
Normal 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
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>
|
90
RiotNSE/NSEMemoryStore.swift
Normal file
90
RiotNSE/NSEMemoryStore.swift
Normal 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()
|
||||
}
|
||||
|
||||
}
|
520
RiotNSE/NotificationService.swift
Normal file
520
RiotNSE/NotificationService.swift
Normal 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
|
||||
}
|
||||
|
||||
}
|
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>
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue