mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-04-22 23:48:36 +00:00
Merge remote-tracking branch 'refs/remotes/origin/master'
Conflicts: Linphone/Core/CoreContext.swift Linphone/Localizable.xcstrings Linphone/UI/Assistant/Viewmodel/AccountLoginViewModel.swift
This commit is contained in:
commit
bf4e4042d3
19 changed files with 756 additions and 85 deletions
|
|
@ -7,14 +7,22 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
660AAF7F2B839272004C0FA6 /* msgNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 660AAF7B2B839271004C0FA6 /* msgNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
660D8A712B517D260092694D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 660D8A702B517D260092694D /* GoogleService-Info.plist */; };
|
660D8A712B517D260092694D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 660D8A702B517D260092694D /* GoogleService-Info.plist */; };
|
||||||
662B69D92B25DE18007118BF /* TelecomManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69D82B25DE18007118BF /* TelecomManager.swift */; };
|
662B69D92B25DE18007118BF /* TelecomManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69D82B25DE18007118BF /* TelecomManager.swift */; };
|
||||||
662B69DB2B25DE25007118BF /* ProviderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69DA2B25DE25007118BF /* ProviderDelegate.swift */; };
|
662B69DB2B25DE25007118BF /* ProviderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662B69DA2B25DE25007118BF /* ProviderDelegate.swift */; };
|
||||||
|
667E5D7F2B8E430C00EBCFC4 /* linphonerc-factory in Resources */ = {isa = PBXBuildFile; fileRef = D732A90B2B0376F500DB42BA /* linphonerc-factory */; };
|
||||||
|
667E5D812B8E444E00EBCFC4 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 667E5D802B8E444D00EBCFC4 /* GoogleService-Info.plist */; };
|
||||||
|
6691CA7E2B839C2D00B2A7B8 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6691CA7D2B839C2D00B2A7B8 /* NotificationService.swift */; };
|
||||||
66C491F92B24D25B00CEA16D /* ConfigExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491F82B24D25A00CEA16D /* ConfigExtension.swift */; };
|
66C491F92B24D25B00CEA16D /* ConfigExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491F82B24D25A00CEA16D /* ConfigExtension.swift */; };
|
||||||
66C491FB2B24D32600CEA16D /* CoreExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FA2B24D32600CEA16D /* CoreExtension.swift */; };
|
66C491FB2B24D32600CEA16D /* CoreExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FA2B24D32600CEA16D /* CoreExtension.swift */; };
|
||||||
66C491FD2B24D36500CEA16D /* AudioRouteUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FC2B24D36500CEA16D /* AudioRouteUtils.swift */; };
|
66C491FD2B24D36500CEA16D /* AudioRouteUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FC2B24D36500CEA16D /* AudioRouteUtils.swift */; };
|
||||||
66C491FF2B24D4AC00CEA16D /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FE2B24D4AC00CEA16D /* FileUtils.swift */; };
|
66C491FF2B24D4AC00CEA16D /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FE2B24D4AC00CEA16D /* FileUtils.swift */; };
|
||||||
66C492012B24DB6900CEA16D /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C492002B24DB6900CEA16D /* Log.swift */; };
|
66C492012B24DB6900CEA16D /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C492002B24DB6900CEA16D /* Log.swift */; };
|
||||||
|
66FBFC482B83B8CC00BC6AB1 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C492002B24DB6900CEA16D /* Log.swift */; };
|
||||||
|
66FBFC492B83BD2400BC6AB1 /* ConfigExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491F82B24D25A00CEA16D /* ConfigExtension.swift */; };
|
||||||
|
66FBFC4A2B83BD3300BC6AB1 /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FE2B24D4AC00CEA16D /* FileUtils.swift */; };
|
||||||
|
66FBFC4B2B83BD7B00BC6AB1 /* CoreExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66C491FA2B24D32600CEA16D /* CoreExtension.swift */; };
|
||||||
D706BA822ADD72D100278F45 /* DeviceRotationViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D706BA812ADD72D100278F45 /* DeviceRotationViewModifier.swift */; };
|
D706BA822ADD72D100278F45 /* DeviceRotationViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D706BA812ADD72D100278F45 /* DeviceRotationViewModifier.swift */; };
|
||||||
D70959F12B8DF3EC0014AC0B /* ConversationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70959F02B8DF3EC0014AC0B /* ConversationModel.swift */; };
|
D70959F12B8DF3EC0014AC0B /* ConversationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70959F02B8DF3EC0014AC0B /* ConversationModel.swift */; };
|
||||||
D70A26EE2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A26ED2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift */; };
|
D70A26EE2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A26ED2B7CF60B006CC8FC /* ConversationsListBottomSheet.swift */; };
|
||||||
|
|
@ -112,10 +120,38 @@
|
||||||
D7FB55112AD447FD00A5AB15 /* RegisterFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7FB55102AD447FD00A5AB15 /* RegisterFragment.swift */; };
|
D7FB55112AD447FD00A5AB15 /* RegisterFragment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7FB55102AD447FD00A5AB15 /* RegisterFragment.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
660AAF7D2B839272004C0FA6 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = D719ABAB2ABC67BF00B41C10 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 660AAF7A2B839271004C0FA6;
|
||||||
|
remoteInfo = msgNotificationService;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
660AAF802B839272004C0FA6 /* Embed Foundation Extensions */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 13;
|
||||||
|
files = (
|
||||||
|
660AAF7F2B839272004C0FA6 /* msgNotificationService.appex in Embed Foundation Extensions */,
|
||||||
|
);
|
||||||
|
name = "Embed Foundation Extensions";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
660AAF7B2B839271004C0FA6 /* msgNotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = msgNotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
660AAF842B8392E0004C0FA6 /* msgNotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = msgNotificationService.entitlements; sourceTree = "<group>"; };
|
||||||
660D8A702B517D260092694D /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
660D8A702B517D260092694D /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
662B69D82B25DE18007118BF /* TelecomManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelecomManager.swift; sourceTree = "<group>"; };
|
662B69D82B25DE18007118BF /* TelecomManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelecomManager.swift; sourceTree = "<group>"; };
|
||||||
662B69DA2B25DE25007118BF /* ProviderDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderDelegate.swift; sourceTree = "<group>"; };
|
662B69DA2B25DE25007118BF /* ProviderDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
667E5D802B8E444D00EBCFC4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
|
6691CA7D2B839C2D00B2A7B8 /* NotificationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
|
||||||
66C491F82B24D25A00CEA16D /* ConfigExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigExtension.swift; sourceTree = "<group>"; };
|
66C491F82B24D25A00CEA16D /* ConfigExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigExtension.swift; sourceTree = "<group>"; };
|
||||||
66C491FA2B24D32600CEA16D /* CoreExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreExtension.swift; sourceTree = "<group>"; };
|
66C491FA2B24D32600CEA16D /* CoreExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreExtension.swift; sourceTree = "<group>"; };
|
||||||
66C491FC2B24D36500CEA16D /* AudioRouteUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRouteUtils.swift; sourceTree = "<group>"; };
|
66C491FC2B24D36500CEA16D /* AudioRouteUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRouteUtils.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -222,6 +258,13 @@
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
660AAF782B839271004C0FA6 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
D719ABB02ABC67BF00B41C10 /* Frameworks */ = {
|
D719ABB02ABC67BF00B41C10 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
|
@ -232,6 +275,16 @@
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
660AAF7C2B839272004C0FA6 /* msgNotificationService */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
667E5D802B8E444D00EBCFC4 /* GoogleService-Info.plist */,
|
||||||
|
6691CA7D2B839C2D00B2A7B8 /* NotificationService.swift */,
|
||||||
|
660AAF842B8392E0004C0FA6 /* msgNotificationService.entitlements */,
|
||||||
|
);
|
||||||
|
path = msgNotificationService;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
662B69D72B25DDF6007118BF /* TelecomManager */ = {
|
662B69D72B25DDF6007118BF /* TelecomManager */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
|
@ -294,6 +347,7 @@
|
||||||
children = (
|
children = (
|
||||||
660D8A702B517D260092694D /* GoogleService-Info.plist */,
|
660D8A702B517D260092694D /* GoogleService-Info.plist */,
|
||||||
D719ABB52ABC67BF00B41C10 /* Linphone */,
|
D719ABB52ABC67BF00B41C10 /* Linphone */,
|
||||||
|
660AAF7C2B839272004C0FA6 /* msgNotificationService */,
|
||||||
D719ABB42ABC67BF00B41C10 /* Products */,
|
D719ABB42ABC67BF00B41C10 /* Products */,
|
||||||
A31AF2AB8C6A3D7B7EA3B424 /* Pods */,
|
A31AF2AB8C6A3D7B7EA3B424 /* Pods */,
|
||||||
);
|
);
|
||||||
|
|
@ -303,6 +357,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D719ABB32ABC67BF00B41C10 /* Linphone.app */,
|
D719ABB32ABC67BF00B41C10 /* Linphone.app */,
|
||||||
|
660AAF7B2B839271004C0FA6 /* msgNotificationService.appex */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -619,12 +674,30 @@
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
660AAF7A2B839271004C0FA6 /* msgNotificationService */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 660AAF832B839272004C0FA6 /* Build configuration list for PBXNativeTarget "msgNotificationService" */;
|
||||||
|
buildPhases = (
|
||||||
|
660AAF772B839271004C0FA6 /* Sources */,
|
||||||
|
660AAF782B839271004C0FA6 /* Frameworks */,
|
||||||
|
660AAF792B839271004C0FA6 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = msgNotificationService;
|
||||||
|
productName = msgNotificationService;
|
||||||
|
productReference = 660AAF7B2B839271004C0FA6 /* msgNotificationService.appex */;
|
||||||
|
productType = "com.apple.product-type.app-extension";
|
||||||
|
};
|
||||||
D719ABB22ABC67BF00B41C10 /* Linphone */ = {
|
D719ABB22ABC67BF00B41C10 /* Linphone */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = D719ABC22ABC67BF00B41C10 /* Build configuration list for PBXNativeTarget "Linphone" */;
|
buildConfigurationList = D719ABC22ABC67BF00B41C10 /* Build configuration list for PBXNativeTarget "Linphone" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
D719ABAF2ABC67BF00B41C10 /* Sources */,
|
D719ABAF2ABC67BF00B41C10 /* Sources */,
|
||||||
D719ABB02ABC67BF00B41C10 /* Frameworks */,
|
D719ABB02ABC67BF00B41C10 /* Frameworks */,
|
||||||
|
660AAF802B839272004C0FA6 /* Embed Foundation Extensions */,
|
||||||
D719ABB12ABC67BF00B41C10 /* Resources */,
|
D719ABB12ABC67BF00B41C10 /* Resources */,
|
||||||
D7FB55122AD53FE200A5AB15 /* Run Script */,
|
D7FB55122AD53FE200A5AB15 /* Run Script */,
|
||||||
66BF2D4B2B558A3100A5F2E3 /* Crashlytics */,
|
66BF2D4B2B558A3100A5F2E3 /* Crashlytics */,
|
||||||
|
|
@ -632,6 +705,7 @@
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
|
660AAF7E2B839272004C0FA6 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = Linphone;
|
name = Linphone;
|
||||||
productName = Linphone;
|
productName = Linphone;
|
||||||
|
|
@ -648,6 +722,10 @@
|
||||||
LastSwiftUpdateCheck = 1430;
|
LastSwiftUpdateCheck = 1430;
|
||||||
LastUpgradeCheck = 1430;
|
LastUpgradeCheck = 1430;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
|
660AAF7A2B839271004C0FA6 = {
|
||||||
|
CreatedOnToolsVersion = 15.0.1;
|
||||||
|
LastSwiftMigration = 1500;
|
||||||
|
};
|
||||||
D719ABB22ABC67BF00B41C10 = {
|
D719ABB22ABC67BF00B41C10 = {
|
||||||
CreatedOnToolsVersion = 14.3.1;
|
CreatedOnToolsVersion = 14.3.1;
|
||||||
};
|
};
|
||||||
|
|
@ -667,11 +745,21 @@
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
D719ABB22ABC67BF00B41C10 /* Linphone */,
|
D719ABB22ABC67BF00B41C10 /* Linphone */,
|
||||||
|
660AAF7A2B839271004C0FA6 /* msgNotificationService */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
660AAF792B839271004C0FA6 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
667E5D7F2B8E430C00EBCFC4 /* linphonerc-factory in Resources */,
|
||||||
|
667E5D812B8E444E00EBCFC4 /* GoogleService-Info.plist in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
D719ABB12ABC67BF00B41C10 /* Resources */ = {
|
D719ABB12ABC67BF00B41C10 /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
|
@ -741,6 +829,18 @@
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
660AAF772B839271004C0FA6 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
66FBFC482B83B8CC00BC6AB1 /* Log.swift in Sources */,
|
||||||
|
6691CA7E2B839C2D00B2A7B8 /* NotificationService.swift in Sources */,
|
||||||
|
66FBFC492B83BD2400BC6AB1 /* ConfigExtension.swift in Sources */,
|
||||||
|
66FBFC4A2B83BD3300BC6AB1 /* FileUtils.swift in Sources */,
|
||||||
|
66FBFC4B2B83BD7B00BC6AB1 /* CoreExtension.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
D719ABAF2ABC67BF00B41C10 /* Sources */ = {
|
D719ABAF2ABC67BF00B41C10 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
|
@ -839,7 +939,95 @@
|
||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
660AAF7E2B839272004C0FA6 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 660AAF7A2B839271004C0FA6 /* msgNotificationService */;
|
||||||
|
targetProxy = 660AAF7D2B839272004C0FA6 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
|
660AAF812B839272004C0FA6 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = msgNotificationService/msgNotificationService.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = Z2V957B3D6;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"DEBUG=1",
|
||||||
|
);
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = msgNotificationService/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = msgNotificationService;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
OTHER_SWIFT_FLAGS = "$(inherited)";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.msgNotificationService;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
660AAF822B839272004C0FA6 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = msgNotificationService/msgNotificationService.entitlements;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = Z2V957B3D6;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = msgNotificationService/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = msgNotificationService;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
OTHER_SWIFT_FLAGS = "$(inherited)";
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.phone.msgNotificationService;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
D719ABC02ABC67BF00B41C10 /* Debug */ = {
|
D719ABC02ABC67BF00B41C10 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
|
@ -958,6 +1146,7 @@
|
||||||
D719ABC32ABC67BF00B41C10 /* Debug */ = {
|
D719ABC32ABC67BF00B41C10 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
|
@ -1013,6 +1202,7 @@
|
||||||
D719ABC42ABC67BF00B41C10 /* Release */ = {
|
D719ABC42ABC67BF00B41C10 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||||
|
|
@ -1064,6 +1254,15 @@
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
|
660AAF832B839272004C0FA6 /* Build configuration list for PBXNativeTarget "msgNotificationService" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
660AAF812B839272004C0FA6 /* Debug */,
|
||||||
|
660AAF822B839272004C0FA6 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
D719ABAE2ABC67BF00B41C10 /* Build configuration list for PBXProject "Linphone" */ = {
|
D719ABAE2ABC67BF00B41C10 /* Build configuration list for PBXProject "Linphone" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ import Combine
|
||||||
import UniformTypeIdentifiers
|
import UniformTypeIdentifiers
|
||||||
import Network
|
import Network
|
||||||
|
|
||||||
|
#if USE_CRASHLYTICS
|
||||||
|
import Firebase
|
||||||
|
#endif
|
||||||
|
|
||||||
final class CoreContext: ObservableObject {
|
final class CoreContext: ObservableObject {
|
||||||
|
|
||||||
static let shared = CoreContext()
|
static let shared = CoreContext()
|
||||||
|
|
@ -66,36 +70,35 @@ final class CoreContext: ObservableObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initialiseCore() throws {
|
func initialiseCore() throws {
|
||||||
|
#if USE_CRASHLYTICS
|
||||||
|
FirebaseApp.configure()
|
||||||
|
#endif
|
||||||
coreQueue.async {
|
coreQueue.async {
|
||||||
|
|
||||||
LoggingService.Instance.logLevel = LogLevel.Debug
|
LoggingService.Instance.logLevel = LogLevel.Debug
|
||||||
let configDir = Factory.Instance.getConfigDir(context: nil)
|
Factory.Instance.logCollectionPath = Factory.Instance.getConfigDir(context: nil)
|
||||||
|
|
||||||
Factory.Instance.logCollectionPath = configDir
|
|
||||||
Factory.Instance.enableLogCollection(state: LogCollectionState.Enabled)
|
Factory.Instance.enableLogCollection(state: LogCollectionState.Enabled)
|
||||||
|
|
||||||
|
Log.info("Checking if linphonerc file exists already. If not, creating one as a copy of linphonerc-default")
|
||||||
|
if let rcDir = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Config.appGroupName)?
|
||||||
|
.appendingPathComponent("Library/Preferences/linphone") {
|
||||||
|
let rcFileUrl = rcDir.appendingPathComponent("linphonerc")
|
||||||
|
if !FileManager.default.fileExists(atPath: rcFileUrl.path) {
|
||||||
|
do {
|
||||||
|
try FileManager.default.createDirectory(at: rcDir, withIntermediateDirectories: true)
|
||||||
|
if let pathToDefaultConfig = Bundle.main.path(forResource: "linphonerc-default", ofType: nil) {
|
||||||
|
try FileManager.default.copyItem(at: URL(fileURLWithPath: pathToDefaultConfig), to: rcFileUrl)
|
||||||
|
Log.info("Successfully copied linphonerc-default configuration")
|
||||||
|
}
|
||||||
|
} catch let error {
|
||||||
|
Log.error("Failed to copy default linphonerc file: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.info("Found existing linphonerc file, skip copying of linphonerc-default configuration")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.info("Initialising core")
|
Log.info("Initialising core")
|
||||||
let url = NSURL(fileURLWithPath: configDir)
|
self.mCore = try? Factory.Instance.createSharedCoreWithConfig(config: Config.get(), systemContext: nil, appGroupId: Config.appGroupName, mainCore: true)
|
||||||
if let pathComponent = url.appendingPathComponent("linphonerc") {
|
|
||||||
let filePath = pathComponent.path
|
|
||||||
let fileManager = FileManager.default
|
|
||||||
if !fileManager.fileExists(atPath: filePath) {
|
|
||||||
let path = Bundle.main.path(forResource: "linphonerc-default", ofType: nil)
|
|
||||||
if path != nil {
|
|
||||||
try? FileManager.default.copyItem(at: NSURL(fileURLWithPath: path!) as URL, to: pathComponent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let config = try? Factory.Instance.createConfigWithFactory(
|
|
||||||
path: "\(configDir)/linphonerc",
|
|
||||||
factoryPath: Bundle.main.path(forResource: "linphonerc-factory", ofType: nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
if config != nil {
|
|
||||||
self.mCore = try? Factory.Instance.createCoreWithConfig(config: config!, systemContext: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
linphone_core_set_push_registry_dispatch_queue(self.mCore.getCobject, Unmanaged.passUnretained(coreQueue).toOpaque())
|
linphone_core_set_push_registry_dispatch_queue(self.mCore.getCobject, Unmanaged.passUnretained(coreQueue).toOpaque())
|
||||||
self.mCore.autoIterateEnabled = false
|
self.mCore.autoIterateEnabled = false
|
||||||
|
|
@ -169,9 +172,6 @@ final class CoreContext: ObservableObject {
|
||||||
if cbVal.state == .Ok {
|
if cbVal.state == .Ok {
|
||||||
self.loggingInProgress = false
|
self.loggingInProgress = false
|
||||||
self.loggedIn = true
|
self.loggedIn = true
|
||||||
if self.mCore.consolidatedPresence != ConsolidatedPresence.Online {
|
|
||||||
self.onForeground()
|
|
||||||
}
|
|
||||||
} else if cbVal.state == .Progress {
|
} else if cbVal.state == .Progress {
|
||||||
self.loggingInProgress = true
|
self.loggingInProgress = true
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -198,8 +198,11 @@ final class CoreContext: ObservableObject {
|
||||||
})
|
})
|
||||||
|
|
||||||
self.mCoreSuscriptions.insert(self.mCore.publisher?.onAccountRegistrationStateChanged?.postOnCoreQueue { (cbVal: (core: Core, account: Account, state: RegistrationState, message: String)) in
|
self.mCoreSuscriptions.insert(self.mCore.publisher?.onAccountRegistrationStateChanged?.postOnCoreQueue { (cbVal: (core: Core, account: Account, state: RegistrationState, message: String)) in
|
||||||
// If registration failed, remove account from core
|
if cbVal.state == .Ok {
|
||||||
if cbVal.state != .Ok && cbVal.state != .Progress {
|
if self.mCore.consolidatedPresence != ConsolidatedPresence.Online {
|
||||||
|
self.updatePresence(core: self.mCore, presence: ConsolidatedPresence.Online)
|
||||||
|
}
|
||||||
|
} else if cbVal.state != .Ok && cbVal.state != .Progress { // If registration failed, remove account from core
|
||||||
let params = cbVal.account.params
|
let params = cbVal.account.params
|
||||||
let clonedParams = params?.clone()
|
let clonedParams = params?.clone()
|
||||||
clonedParams?.registerEnabled = false
|
clonedParams?.registerEnabled = false
|
||||||
|
|
@ -266,27 +269,35 @@ final class CoreContext: ObservableObject {
|
||||||
try? self.mCore.start()
|
try? self.mCore.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func onForeground() {
|
|
||||||
coreQueue.async {
|
func updatePresence(core : Core, presence : ConsolidatedPresence) {
|
||||||
// We can't rely on defaultAccount?.params?.isPublishEnabled
|
if core.config!.getBool(section: "app", key: "publish_presence", defaultValue: true) {
|
||||||
// as it will be modified by the SDK when changing the presence status
|
core.consolidatedPresence = presence
|
||||||
if self.mCore.config!.getBool(section: "app", key: "publish_presence", defaultValue: true) {
|
|
||||||
Log.info("App is in foreground, PUBLISHING presence as Online")
|
|
||||||
self.mCore.consolidatedPresence = ConsolidatedPresence.Online
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func onBackground() {
|
func onEnterForeground() {
|
||||||
|
coreQueue.async {
|
||||||
|
// We can't rely on defaultAccount?.params?.isPublishEnabled
|
||||||
|
// as it will be modified by the SDK when changing the presence status
|
||||||
|
|
||||||
|
Log.info("App is in foreground, PUBLISHING presence as Online")
|
||||||
|
self.updatePresence(core: self.mCore, presence: ConsolidatedPresence.Online)
|
||||||
|
try? self.mCore.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func onEnterBackground() {
|
||||||
coreQueue.async {
|
coreQueue.async {
|
||||||
// We can't rely on defaultAccount?.params?.isPublishEnabled
|
// We can't rely on defaultAccount?.params?.isPublishEnabled
|
||||||
// as it will be modified by the SDK when changing the presence status
|
// as it will be modified by the SDK when changing the presence status
|
||||||
if self.mCore.config!.getBool(section: "app", key: "publish_presence", defaultValue: true) {
|
|
||||||
Log.info("App is in background, un-PUBLISHING presence info")
|
Log.info("App is in background, un-PUBLISHING presence info")
|
||||||
|
|
||||||
// We don't use ConsolidatedPresence.Busy but Offline to do an unsubscribe,
|
// We don't use ConsolidatedPresence.Busy but Offline to do an unsubscribe,
|
||||||
// Flexisip will handle the Busy status depending on other devices
|
// Flexisip will handle the Busy status depending on other devices
|
||||||
self.mCore.consolidatedPresence = ConsolidatedPresence.Offline
|
self.updatePresence(core: self.mCore, presence: ConsolidatedPresence.Offline)
|
||||||
}
|
// self.mCore.iterate()
|
||||||
|
self.mCore.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
<true/>
|
<true/>
|
||||||
<key>ITSEncryptionExportComplianceCode</key>
|
<key>ITSEncryptionExportComplianceCode</key>
|
||||||
<string>b5cb085f-772a-4a4f-8c77-5d1332b1f93f</string>
|
<string>b5cb085f-772a-4a4f-8c77-5d1332b1f93f</string>
|
||||||
|
<key>NSSupportsSuddenTermination</key>
|
||||||
|
<false/>
|
||||||
<key>UIAppFonts</key>
|
<key>UIAppFonts</key>
|
||||||
<array>
|
<array>
|
||||||
<string>NotoSans-Light.ttf</string>
|
<string>NotoSans-Light.ttf</string>
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,12 @@
|
||||||
<string>group.belledonne-communications.linphone</string>
|
<string>group.belledonne-communications.linphone</string>
|
||||||
<string>group.org.linphone.phone.linphoneExtension</string>
|
<string>group.org.linphone.phone.linphoneExtension</string>
|
||||||
<string>group.org.linphone.phone.msgNotification</string>
|
<string>group.org.linphone.phone.msgNotification</string>
|
||||||
<string>group.org.linphone.phone.logs</string>
|
|
||||||
</array>
|
</array>
|
||||||
<key>com.apple.security.files.user-selected.read-only</key>
|
<key>com.apple.security.files.user-selected.read-only</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>keychain-access-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>$(AppIdentifierPrefix)org.linphone.phone</string>
|
||||||
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
||||||
|
|
@ -18,23 +18,54 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
#if USE_CRASHLYTICS
|
import linphonesw
|
||||||
import Firebase
|
|
||||||
#endif
|
let accountTokenNotification = Notification.Name("AccountCreationTokenReceived")
|
||||||
|
|
||||||
class AppDelegate: NSObject, UIApplicationDelegate {
|
class AppDelegate: NSObject, UIApplicationDelegate {
|
||||||
func application(_ application: UIApplication,
|
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
||||||
#if USE_CRASHLYTICS
|
let tokenStr = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
|
||||||
FirebaseApp.configure()
|
Log.info("Received remote push token : \(tokenStr)")
|
||||||
#endif
|
CoreContext.shared.doOnCoreQueue { core in
|
||||||
return true
|
Log.info("Forwarding remote push token to core")
|
||||||
|
core.didRegisterForRemotePushWithStringifiedToken(deviceTokenStr: tokenStr + ":remote")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
|
||||||
|
Log.error("Failed to register for push notifications : \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
|
||||||
|
Log.info("Received background push notification, payload = \(userInfo.description)")
|
||||||
|
/*
|
||||||
|
let creationToken = (userInfo["customPayload"] as? NSDictionary)?["token"] as? String
|
||||||
|
if let creationToken = creationToken {
|
||||||
|
NotificationCenter.default.post(name: accountTokenNotification, object: nil, userInfo: ["token": creationToken])
|
||||||
|
}
|
||||||
|
completionHandler(UIBackgroundFetchResult.newData)*/
|
||||||
|
}
|
||||||
|
|
||||||
|
func applicationWillTerminate(_ application: UIApplication) {
|
||||||
|
Log.info("IOS applicationWillTerminate")
|
||||||
|
CoreContext.shared.doOnCoreQueue(synchronous: true) { core in
|
||||||
|
Log.info("applicationWillTerminate - Stopping linphone core")
|
||||||
|
MagicSearchSingleton.shared.destroyMagicSearch()
|
||||||
|
if core.globalState != GlobalState.Off {
|
||||||
|
core.stop()
|
||||||
|
} else {
|
||||||
|
Log.info("applicationWillTerminate - Core already stopped")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct LinphoneApp: App {
|
struct LinphoneApp: App {
|
||||||
|
|
||||||
|
@Environment(\.scenePhase) var scenePhase
|
||||||
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
|
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
|
||||||
@ObservedObject private var coreContext = CoreContext.shared
|
@ObservedObject private var coreContext = CoreContext.shared
|
||||||
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
|
@ObservedObject private var sharedMainViewModel = SharedMainViewModel.shared
|
||||||
|
|
@ -96,6 +127,15 @@ struct LinphoneApp: App {
|
||||||
conversationViewModel = ConversationViewModel()
|
conversationViewModel = ConversationViewModel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.onChange(of: scenePhase) { newPhase in
|
||||||
|
if newPhase == .active {
|
||||||
|
Log.info("Entering foreground")
|
||||||
|
coreContext.onEnterForeground()
|
||||||
|
} else if newPhase == .inactive {
|
||||||
|
} else if newPhase == .background {
|
||||||
|
Log.info("Entering background")
|
||||||
|
coreContext.onEnterBackground()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,23 @@
|
||||||
},
|
},
|
||||||
"First name*" : {
|
"First name*" : {
|
||||||
|
|
||||||
|
},
|
||||||
|
"GC_MSG" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "You have been added to a chat room"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Vous avez été ajouté à une conversation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Hang up call" : {
|
"Hang up call" : {
|
||||||
|
|
||||||
|
|
@ -355,6 +372,23 @@
|
||||||
},
|
},
|
||||||
"I understand" : {
|
"I understand" : {
|
||||||
|
|
||||||
|
},
|
||||||
|
"IM_MSG" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "You have received a message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fr" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Vous avez reçu un message"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Incoming call" : {
|
"Incoming call" : {
|
||||||
|
|
||||||
|
|
@ -379,6 +413,9 @@
|
||||||
},
|
},
|
||||||
"Job title" : {
|
"Job title" : {
|
||||||
|
|
||||||
|
},
|
||||||
|
"Key" : {
|
||||||
|
"extractionState" : "manual"
|
||||||
},
|
},
|
||||||
"Last name" : {
|
"Last name" : {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
<entry name="conference_factory_uri" overwrite="true">sip:conference-factory@sip.linphone.org</entry>
|
<entry name="conference_factory_uri" overwrite="true">sip:conference-factory@sip.linphone.org</entry>
|
||||||
<entry name="audio_video_conference_factory_uri" overwrite="true">sip:videoconference-factory@sip.linphone.org</entry>
|
<entry name="audio_video_conference_factory_uri" overwrite="true">sip:videoconference-factory@sip.linphone.org</entry>
|
||||||
<entry name="push_notification_allowed" overwrite="true">1</entry>
|
<entry name="push_notification_allowed" overwrite="true">1</entry>
|
||||||
|
<entry name="remote_push_notification_allowed" overwrite="true">1</entry>
|
||||||
<entry name="cpim_in_basic_chat_rooms_enabled" overwrite="true">1</entry>
|
<entry name="cpim_in_basic_chat_rooms_enabled" overwrite="true">1</entry>
|
||||||
<entry name="rtp_bundle" overwrite="true">1</entry>
|
<entry name="rtp_bundle" overwrite="true">1</entry>
|
||||||
<entry name="lime_server_url" overwrite="true">https://lime.linphone.org/lime-server/lime-server.php</entry>
|
<entry name="lime_server_url" overwrite="true">https://lime.linphone.org/lime-server/lime-server.php</entry>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ size=vga
|
||||||
tunnel=disabled
|
tunnel=disabled
|
||||||
auto_start=1
|
auto_start=1
|
||||||
record_aware=1
|
record_aware=1
|
||||||
|
disable_chat_feature=0
|
||||||
|
|
||||||
[tunnel]
|
[tunnel]
|
||||||
host=
|
host=
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ store_friends=0
|
||||||
activation_code_length=4
|
activation_code_length=4
|
||||||
prefer_basic_chat_room=1
|
prefer_basic_chat_room=1
|
||||||
record_aware=1
|
record_aware=1
|
||||||
|
disable_chat_feature=0
|
||||||
|
|
||||||
[account_creator]
|
[account_creator]
|
||||||
backend=1
|
backend=1
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ class AccountLoginViewModel: ObservableObject {
|
||||||
// And we ensure the account will start the registration process
|
// And we ensure the account will start the registration process
|
||||||
accountParams.registerEnabled = true
|
accountParams.registerEnabled = true
|
||||||
accountParams.pushNotificationAllowed = true
|
accountParams.pushNotificationAllowed = true
|
||||||
accountParams.remotePushNotificationAllowed = false
|
accountParams.remotePushNotificationAllowed = true
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
let pushEnvironment = ".dev"
|
let pushEnvironment = ".dev"
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -894,25 +894,6 @@ struct ContentView: View {
|
||||||
}
|
}
|
||||||
orientation = newOrientation
|
orientation = newOrientation
|
||||||
}
|
}
|
||||||
.onChange(of: scenePhase) { newPhase in
|
|
||||||
if newPhase == .active {
|
|
||||||
coreContext.onForeground()
|
|
||||||
/*
|
|
||||||
if !isShowStartCallFragment {
|
|
||||||
contactsManager.fetchContacts()
|
|
||||||
DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
|
|
||||||
historyListViewModel.computeCallLogsList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
print("Active")
|
|
||||||
} else if newPhase == .inactive {
|
|
||||||
print("Inactive")
|
|
||||||
} else if newPhase == .background {
|
|
||||||
coreContext.onBackground()
|
|
||||||
print("Background")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func openMenu() {
|
func openMenu() {
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ extension Config {
|
||||||
|
|
||||||
public static func get() -> Config {
|
public static func get() -> Config {
|
||||||
if _instance == nil {
|
if _instance == nil {
|
||||||
let factoryPath = FileUtil.bundleFilePath(Core.runsInsideExtension() ? "linphonerc-factory-appex" : "linphonerc-factory-app")!
|
let factoryPath = FileUtil.bundleFilePath("linphonerc-factory")!
|
||||||
|
let configDir = Factory.Instance.getConfigDir(context: nil)
|
||||||
_instance = Config.newForSharedCore(appGroupId: Config.appGroupName, configFilename: "linphonerc", factoryConfigFilename: factoryPath)!
|
_instance = Config.newForSharedCore(appGroupId: Config.appGroupName, configFilename: "linphonerc", factoryConfigFilename: factoryPath)!
|
||||||
}
|
}
|
||||||
return _instance!
|
return _instance!
|
||||||
|
|
@ -46,7 +47,7 @@ extension Config {
|
||||||
return hasEntry(section: section, key: key) == 1 ? getString(section: section, key: key, defaultString: "") : nil
|
return hasEntry(section: section, key: key) == 1 ? getString(section: section, key: key, defaultString: "") : nil
|
||||||
}
|
}
|
||||||
|
|
||||||
static let appGroupName = "group.org.linphone.phone.logs"
|
static let appGroupName = "group.org.linphone.phone.msgNotification"
|
||||||
// Needs to be the same name in App Group (capabilities in ALL targets - app & extensions - content + service), can't be stored in the Config itself the Config needs this value to get created
|
// Needs to be the same name in App Group (capabilities in ALL targets - app & extensions - content + service), can't be stored in the Config itself the Config needs this value to get created
|
||||||
static let teamID = Config.get().getString(section: "app", key: "team_id", defaultString: "")
|
static let teamID = Config.get().getString(section: "app", key: "team_id", defaultString: "")
|
||||||
static let earlymediaContentExtCatIdentifier = Config.get().getString(section: "app", key: "extension_category", defaultString: "")
|
static let earlymediaContentExtCatIdentifier = Config.get().getString(section: "app", key: "extension_category", defaultString: "")
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ final class MagicSearchSingleton: ObservableObject {
|
||||||
|
|
||||||
var searchSubscription: AnyCancellable?
|
var searchSubscription: AnyCancellable?
|
||||||
|
|
||||||
|
func destroyMagicSearch() {
|
||||||
|
magicSearch = nil
|
||||||
|
}
|
||||||
|
|
||||||
private init() {
|
private init() {
|
||||||
coreContext.doOnCoreQueue { core in
|
coreContext.doOnCoreQueue { core in
|
||||||
self.domainDefaultAccount = core.defaultAccount?.params?.domain ?? ""
|
self.domainDefaultAccount = core.defaultAccount?.params?.domain ?? ""
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,14 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
import Photos
|
import Photos
|
||||||
import Contacts
|
import Contacts
|
||||||
|
import UserNotifications
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
class PermissionManager: ObservableObject {
|
class PermissionManager: ObservableObject {
|
||||||
|
|
||||||
static let shared = PermissionManager()
|
static let shared = PermissionManager()
|
||||||
|
|
||||||
|
@Published var pushPermissionGranted = false
|
||||||
@Published var photoLibraryPermissionGranted = false
|
@Published var photoLibraryPermissionGranted = false
|
||||||
@Published var cameraPermissionGranted = false
|
@Published var cameraPermissionGranted = false
|
||||||
@Published var contactsPermissionGranted = false
|
@Published var contactsPermissionGranted = false
|
||||||
|
|
@ -33,12 +36,25 @@ class PermissionManager: ObservableObject {
|
||||||
private init() {}
|
private init() {}
|
||||||
|
|
||||||
func getPermissions() {
|
func getPermissions() {
|
||||||
|
pushNotificationRequestPermission()
|
||||||
microphoneRequestPermission()
|
microphoneRequestPermission()
|
||||||
photoLibraryRequestPermission()
|
photoLibraryRequestPermission()
|
||||||
cameraRequestPermission()
|
cameraRequestPermission()
|
||||||
contactsRequestPermission()
|
contactsRequestPermission()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func pushNotificationRequestPermission() {
|
||||||
|
let options: UNAuthorizationOptions = [.alert, .sound, .badge]
|
||||||
|
UNUserNotificationCenter.current().requestAuthorization(options: options) { (granted, error) in
|
||||||
|
if let error = error {
|
||||||
|
Log.error("Unexpected error when asking for Push permission : \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.pushPermissionGranted = granted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func microphoneRequestPermission() {
|
func microphoneRequestPermission() {
|
||||||
AVAudioSession.sharedInstance().requestRecordPermission({ granted in
|
AVAudioSession.sharedInstance().requestRecordPermission({ granted in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
|
|
||||||
9
Podfile
9
Podfile
|
|
@ -30,6 +30,15 @@ target 'Linphone' do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
target 'msgNotificationService' do
|
||||||
|
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
|
||||||
|
use_frameworks!
|
||||||
|
|
||||||
|
# Pods for messagesNotification
|
||||||
|
basic_pods
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
app_project = Xcodeproj::Project.open(Dir.glob("*.xcodeproj")[0])
|
app_project = Xcodeproj::Project.open(Dir.glob("*.xcodeproj")[0])
|
||||||
app_project.native_targets.each do |target|
|
app_project.native_targets.each do |target|
|
||||||
|
|
|
||||||
36
msgNotificationService/GoogleService-Info.plist
Normal file
36
msgNotificationService/GoogleService-Info.plist
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?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>CLIENT_ID</key>
|
||||||
|
<string>221368768663-b8e48em01it3pt04vp1k0ddrgrcrju65.apps.googleusercontent.com</string>
|
||||||
|
<key>REVERSED_CLIENT_ID</key>
|
||||||
|
<string>com.googleusercontent.apps.221368768663-b8e48em01it3pt04vp1k0ddrgrcrju65</string>
|
||||||
|
<key>API_KEY</key>
|
||||||
|
<string>AIzaSyDJTtlRCM7IqdVUU2dSIYq2YIsTz6bqnkI</string>
|
||||||
|
<key>GCM_SENDER_ID</key>
|
||||||
|
<string>221368768663</string>
|
||||||
|
<key>PLIST_VERSION</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>BUNDLE_ID</key>
|
||||||
|
<string>org.linphone.phone.msgNotificationService</string>
|
||||||
|
<key>PROJECT_ID</key>
|
||||||
|
<string>linphone-iphone</string>
|
||||||
|
<key>STORAGE_BUCKET</key>
|
||||||
|
<string>linphone-iphone.appspot.com</string>
|
||||||
|
<key>IS_ADS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_ANALYTICS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_APPINVITE_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_GCM_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_SIGNIN_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>GOOGLE_APP_ID</key>
|
||||||
|
<string>1:221368768663:ios:ccf2c32eadcd3a0f9431d2</string>
|
||||||
|
<key>DATABASE_URL</key>
|
||||||
|
<string>https://linphone-iphone.firebaseio.com</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
31
msgNotificationService/Info.plist
Normal file
31
msgNotificationService/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>msgNotificationService</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>
|
||||||
284
msgNotificationService/NotificationService.swift
Normal file
284
msgNotificationService/NotificationService.swift
Normal file
|
|
@ -0,0 +1,284 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2020 Belledonne Communications SARL.
|
||||||
|
*
|
||||||
|
* This file is part of linphone-iphone
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// swiftlint:disable identifier_name
|
||||||
|
|
||||||
|
import UserNotifications
|
||||||
|
import linphonesw
|
||||||
|
#if USE_CRASHLYTICS
|
||||||
|
import Firebase
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var LINPHONE_DUMMY_SUBJECT = "dummy subject"
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
func getDisplayNameFromSipAddress(lc: Core) -> String? {
|
||||||
|
Log.info("looking for display name for \(self)")
|
||||||
|
|
||||||
|
let defaults = UserDefaults.init(suiteName: Config.appGroupName)
|
||||||
|
let addressBook = defaults?.dictionary(forKey: "addressBook")
|
||||||
|
|
||||||
|
if addressBook == nil {
|
||||||
|
Log.info("address book not found in userDefaults")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var usePrefix = true
|
||||||
|
if let account = lc.defaultAccount, let params = account.params {
|
||||||
|
usePrefix = params.useInternationalPrefixForCallsAndChats
|
||||||
|
}
|
||||||
|
|
||||||
|
if let simpleAddr = lc.interpretUrl(url: self, applyInternationalPrefix: usePrefix) {
|
||||||
|
simpleAddr.clean()
|
||||||
|
let nomalSipaddr = simpleAddr.asString()
|
||||||
|
if let displayName = addressBook?[nomalSipaddr] as? String {
|
||||||
|
Log.info("display name for \(self): \(displayName)")
|
||||||
|
return displayName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info("display name for \(self) not found in userDefaults")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MsgData: Codable {
|
||||||
|
var from: String?
|
||||||
|
var body: String?
|
||||||
|
var subtitle: String?
|
||||||
|
var callId: String?
|
||||||
|
var localAddr: String?
|
||||||
|
var peerAddr: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotificationService: UNNotificationServiceExtension {
|
||||||
|
|
||||||
|
var contentHandler: ((UNNotificationContent) -> Void)?
|
||||||
|
var bestAttemptContent: UNMutableNotificationContent?
|
||||||
|
|
||||||
|
var lc: Core?
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
super.init()
|
||||||
|
#if USE_CRASHLYTICS
|
||||||
|
FirebaseApp.configure()
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||||
|
|
||||||
|
self.contentHandler = contentHandler
|
||||||
|
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
||||||
|
|
||||||
|
LoggingService.Instance.logLevel = LogLevel.Debug
|
||||||
|
Factory.Instance.logCollectionPath = Factory.Instance.getConfigDir(context: nil)
|
||||||
|
Factory.Instance.enableLogCollection(state: LogCollectionState.Enabled)
|
||||||
|
Log.info("[msgNotificationService] start msgNotificationService extension")
|
||||||
|
/*
|
||||||
|
if (VFSUtil.vfsEnabled(groupName: Config.appGroupName) && !VFSUtil.activateVFS()) {
|
||||||
|
VFSUtil.log("[VFS] Error unable to activate.", .error)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if let bestAttemptContent = bestAttemptContent {
|
||||||
|
createCore()
|
||||||
|
|
||||||
|
if !lc!.config!.getBool(section: "app", key: "disable_chat_feature", defaultValue: true) {
|
||||||
|
Log.info("received push payload : \(bestAttemptContent.userInfo.debugDescription)")
|
||||||
|
|
||||||
|
/*
|
||||||
|
let defaults = UserDefaults.init(suiteName: Config.appGroupName)
|
||||||
|
if let chatroomsPushStatus = defaults?.dictionary(forKey: "chatroomsPushStatus") {
|
||||||
|
let aps = bestAttemptContent.userInfo["aps"] as? NSDictionary
|
||||||
|
let alert = aps?["alert"] as? NSDictionary
|
||||||
|
let fromAddresses = alert?["loc-args"] as? [String]
|
||||||
|
|
||||||
|
if let from = fromAddresses?.first {
|
||||||
|
if ((chatroomsPushStatus[from] as? String) == "disabled") {
|
||||||
|
NotificationService.log.message(message: "message comes from a muted chatroom, ignore it")
|
||||||
|
contentHandler(UNNotificationContent())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if let chatRoomInviteAddr = bestAttemptContent.userInfo["chat-room-addr"] as? String, !chatRoomInviteAddr.isEmpty {
|
||||||
|
Log.info("fetch chat room for invite, addr: \(chatRoomInviteAddr)")
|
||||||
|
let chatRoom = lc!.getNewChatRoomFromConfAddr(chatRoomAddr: chatRoomInviteAddr)
|
||||||
|
|
||||||
|
if let chatRoom = chatRoom {
|
||||||
|
stopCore()
|
||||||
|
Log.info("chat room invite received")
|
||||||
|
bestAttemptContent.title = NSLocalizedString("GC_MSG", comment: "")
|
||||||
|
if chatRoom.hasCapability(mask: ChatRoom.Capabilities.OneToOne.rawValue) {
|
||||||
|
if chatRoom.peerAddress?.displayName?.isEmpty != true {
|
||||||
|
bestAttemptContent.body = chatRoom.peerAddress!.displayName!
|
||||||
|
} else {
|
||||||
|
bestAttemptContent.body = chatRoom.peerAddress!.username!
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bestAttemptContent.body = chatRoom.subject!
|
||||||
|
}
|
||||||
|
contentHandler(bestAttemptContent)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if let callId = bestAttemptContent.userInfo["call-id"] as? String {
|
||||||
|
Log.info("fetch msg for callid ["+callId+"]")
|
||||||
|
let message = lc!.getNewMessageFromCallid(callId: callId)
|
||||||
|
|
||||||
|
if let message = message {
|
||||||
|
let msgData = parseMessage(message: message)
|
||||||
|
|
||||||
|
// Extension only upates app's badge when main shared core is Off = extension's core is On.
|
||||||
|
// Otherwise, the app will update the badge.
|
||||||
|
if lc?.globalState == GlobalState.On, let badge = updateBadge() as NSNumber? {
|
||||||
|
bestAttemptContent.badge = badge
|
||||||
|
}
|
||||||
|
|
||||||
|
stopCore()
|
||||||
|
|
||||||
|
bestAttemptContent.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "msg.caf"))
|
||||||
|
bestAttemptContent.title = NSLocalizedString("Message received", comment: "")
|
||||||
|
if let subtitle = msgData?.subtitle {
|
||||||
|
bestAttemptContent.subtitle = subtitle
|
||||||
|
}
|
||||||
|
if let body = msgData?.body {
|
||||||
|
bestAttemptContent.body = body
|
||||||
|
}
|
||||||
|
|
||||||
|
bestAttemptContent.categoryIdentifier = "msg_cat"
|
||||||
|
|
||||||
|
bestAttemptContent.userInfo.updateValue(msgData?.callId as Any, forKey: "CallId")
|
||||||
|
bestAttemptContent.userInfo.updateValue(msgData?.from as Any, forKey: "from")
|
||||||
|
bestAttemptContent.userInfo.updateValue(msgData?.peerAddr as Any, forKey: "peer_addr")
|
||||||
|
bestAttemptContent.userInfo.updateValue(msgData?.localAddr as Any, forKey: "local_addr")
|
||||||
|
|
||||||
|
if message.reactionContent != " " {
|
||||||
|
contentHandler(bestAttemptContent)
|
||||||
|
} else {
|
||||||
|
contentHandler(UNNotificationContent())
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
Log.info("Message not found for callid ["+callId+"]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serviceExtensionTimeWillExpire()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
Log.warn("serviceExtensionTimeWillExpire")
|
||||||
|
stopCore()
|
||||||
|
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
|
||||||
|
NSLog("[msgNotificationService] serviceExtensionTimeWillExpire")
|
||||||
|
bestAttemptContent.categoryIdentifier = "app_active"
|
||||||
|
|
||||||
|
if let chatRoomInviteAddr = bestAttemptContent.userInfo["chat-room-addr"] as? String, !chatRoomInviteAddr.isEmpty {
|
||||||
|
bestAttemptContent.title = NSLocalizedString("GC_MSG", comment: "")
|
||||||
|
bestAttemptContent.body = ""
|
||||||
|
bestAttemptContent.sound = UNNotificationSound(named: UNNotificationSoundName("msg.caf")) // TODO : temporary fix, to be removed after flexisip release
|
||||||
|
} else {
|
||||||
|
bestAttemptContent.title = NSLocalizedString("Message received", comment: "")
|
||||||
|
bestAttemptContent.body = NSLocalizedString("IM_MSG", comment: "")
|
||||||
|
}
|
||||||
|
contentHandler(bestAttemptContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseMessage(message: PushNotificationMessage) -> MsgData? {
|
||||||
|
|
||||||
|
var content = ""
|
||||||
|
if message.isConferenceInvitationNew {
|
||||||
|
content = NSLocalizedString("📅 You are invited to a meeting", comment: "")
|
||||||
|
} else if message.isConferenceInvitationUpdate {
|
||||||
|
content = NSLocalizedString("📅 Meeting has been modified", comment: "")
|
||||||
|
} else if message.isConferenceInvitationCancellation {
|
||||||
|
content = NSLocalizedString("📅 Meeting has been cancelled", comment: "")
|
||||||
|
} else {
|
||||||
|
content = message.isText ? message.textContent! : "🗻"
|
||||||
|
}
|
||||||
|
|
||||||
|
let fromAddr = message.fromAddr?.username
|
||||||
|
let callId = message.callId
|
||||||
|
let localUri = message.localAddr?.asStringUriOnly()
|
||||||
|
let peerUri = message.peerAddr?.asStringUriOnly()
|
||||||
|
let reactionContent = message.reactionContent
|
||||||
|
let from: String
|
||||||
|
if let fromDisplayName = message.fromAddr?.asStringUriOnly().getDisplayNameFromSipAddress(lc: lc!) {
|
||||||
|
from = fromDisplayName
|
||||||
|
} else {
|
||||||
|
from = fromAddr!
|
||||||
|
}
|
||||||
|
|
||||||
|
var msgData = MsgData(from: fromAddr, body: "", subtitle: "", callId: callId, localAddr: localUri, peerAddr: peerUri)
|
||||||
|
|
||||||
|
if let showMsg = lc!.config?.getBool(section: "app", key: "show_msg_in_notif", defaultValue: true), showMsg == true {
|
||||||
|
if let subject = message.subject as String?, !subject.isEmpty {
|
||||||
|
msgData.subtitle = subject
|
||||||
|
if reactionContent == nil {
|
||||||
|
msgData.body = from + " : " + content
|
||||||
|
} else {
|
||||||
|
msgData.body = from + NSLocalizedString(" has reacted by ", comment: "") + reactionContent! + NSLocalizedString(" to: ", comment: "") + content
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msgData.subtitle = from
|
||||||
|
msgData.body = content
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let subject = message.subject as String?, !subject.isEmpty {
|
||||||
|
msgData.body = subject + " : " + from
|
||||||
|
} else {
|
||||||
|
msgData.body = from
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info("received msg size : \(content.count) \n")
|
||||||
|
return msgData
|
||||||
|
}
|
||||||
|
|
||||||
|
func createCore() {
|
||||||
|
Log.info("[msgNotificationService] create core")
|
||||||
|
|
||||||
|
lc = try? Factory.Instance.createSharedCoreWithConfig(config: Config.get(), systemContext: nil, appGroupId: Config.appGroupName, mainCore: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopCore() {
|
||||||
|
Log.info("stop core")
|
||||||
|
if let lc = lc {
|
||||||
|
lc.stop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateBadge() -> Int {
|
||||||
|
var count = 0
|
||||||
|
count += lc!.unreadChatMessageCount
|
||||||
|
count += lc!.missedCallsCount
|
||||||
|
count += lc!.callsNb
|
||||||
|
Log.info("badge: \(count)\n")
|
||||||
|
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:enable identifier_name
|
||||||
14
msgNotificationService/msgNotificationService.entitlements
Normal file
14
msgNotificationService/msgNotificationService.entitlements
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?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.org.linphone.phone.msgNotification</string>
|
||||||
|
</array>
|
||||||
|
<key>keychain-access-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>$(AppIdentifierPrefix)org.linphone.phone</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
Loading…
Add table
Reference in a new issue