Add tutorial for remote notification management through notification service app extension, and update pod files
This commit is contained in:
parent
002ee3d5a5
commit
083ddb165b
@ -5,7 +5,7 @@ source "https://github.com/CocoaPods/Specs.git"
|
||||
|
||||
def basic_pods
|
||||
if ENV['PODFILE_PATH'].nil?
|
||||
pod 'linphone-sdk', '~> 5.0.0'
|
||||
pod 'linphone-sdk', '~> 5.0.48'
|
||||
else
|
||||
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ source "https://github.com/CocoaPods/Specs.git"
|
||||
|
||||
def basic_pods
|
||||
if ENV['PODFILE_PATH'].nil?
|
||||
pod 'linphone-sdk', '~> 5.0.0'
|
||||
pod 'linphone-sdk', '~> 5.0.48'
|
||||
else
|
||||
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ source "https://github.com/CocoaPods/Specs.git"
|
||||
|
||||
def basic_pods
|
||||
if ENV['PODFILE_PATH'].nil?
|
||||
pod 'linphone-sdk', '~> 5.0.0'
|
||||
pod 'linphone-sdk', '~> 5.0.48'
|
||||
else
|
||||
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ source "https://github.com/CocoaPods/Specs.git"
|
||||
|
||||
def basic_pods
|
||||
if ENV['PODFILE_PATH'].nil?
|
||||
pod 'linphone-sdk', '~> 5.0.0'
|
||||
pod 'linphone-sdk', '~> 5.0.48'
|
||||
else
|
||||
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ source "https://github.com/CocoaPods/Specs.git"
|
||||
|
||||
def basic_pods
|
||||
if ENV['PODFILE_PATH'].nil?
|
||||
pod 'linphone-sdk', '~> 5.0.0'
|
||||
pod 'linphone-sdk', '~> 5.0.48'
|
||||
else
|
||||
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ source "https://github.com/CocoaPods/Specs.git"
|
||||
|
||||
def basic_pods
|
||||
if ENV['PODFILE_PATH'].nil?
|
||||
pod 'linphone-sdk', '~> 5.0.0'
|
||||
pod 'linphone-sdk', '~> 5.0.48'
|
||||
else
|
||||
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ source "https://github.com/CocoaPods/Specs.git"
|
||||
|
||||
def basic_pods
|
||||
if ENV['PODFILE_PATH'].nil?
|
||||
pod 'linphone-sdk', '~> 5.0.0'
|
||||
pod 'linphone-sdk', '~> 5.0.48'
|
||||
else
|
||||
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
|
||||
end
|
||||
|
34
ios/swift/8-RemoteNotification/Podfile
Normal file
34
ios/swift/8-RemoteNotification/Podfile
Normal file
@ -0,0 +1,34 @@
|
||||
# Uncomment the next line to define a global platform for your project
|
||||
platform :ios, '11.0'
|
||||
source "https://gitlab.linphone.org/BC/public/podspec.git"
|
||||
source "https://github.com/CocoaPods/Specs.git"
|
||||
|
||||
def all_pods
|
||||
if ENV['PODFILE_PATH'].nil?
|
||||
pod 'linphone-sdk', '~> 5.0.48'
|
||||
else
|
||||
pod 'linphone-sdk', :path => ENV['PODFILE_PATH'] # local sdk
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
target 'RemoteNotification' do
|
||||
# Comment the next line if you don't want to use dynamic frameworks
|
||||
use_frameworks!
|
||||
|
||||
# Pods for RemoteNotification
|
||||
all_pods
|
||||
|
||||
end
|
||||
|
||||
target 'notificationServiceAppExtension' do
|
||||
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
|
||||
use_frameworks!
|
||||
|
||||
# Pods for messagesNotification
|
||||
all_pods
|
||||
|
||||
end
|
||||
|
13
ios/swift/8-RemoteNotification/README.md
Normal file
13
ios/swift/8-RemoteNotification/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
Remote Push notifications tutorial
|
||||
====================
|
||||
|
||||
On mobile devices (Android & iOS), you probably want your app to be reachable even if it's not in the foreground.
|
||||
|
||||
To do that you need it to be able to receive push notifications from your SIP proxy, and in this tutorial, using [Apple Push Notification Service](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html), you'll learn how to simply send the device push information to your server.
|
||||
|
||||
|
||||
Compared to the previous tutorials, some changes have been required in `RemoteNotification.xcodeproj` in order to enable `Push Notifications`, `BackGround Modes (Remote Notifications)`, and 'App Groups' in the capabilities of your project.
|
||||
|
||||
A Notification App Service Extension target has also been added to the project. This extension implements UNNotificationServiceExtension, which will call the 'didReceive' when the app receives a notification in the background, or is terminated. We will then have a maximum of 30 second to process the notification, and customise the displayed contents, before it pops on the phone's screen.
|
||||
|
||||
The "group.org.linphone.tutorials.notification" App Group will allow the app extension to share files, such as the linphonerc configuration file, with the main app. This way, we can start the shared core in the background, register, and process the sip message that flexisip sent us.
|
@ -0,0 +1,623 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 51;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1BA393B95CFA47C282449D0D /* Pods_notificationServiceAppExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 432CF7AB83561E16C637E70C /* Pods_notificationServiceAppExtension.framework */; };
|
||||
41160BCD42850AC1D0891474 /* Pods_RemoteNotification.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DE48A29C8F332901C688A73 /* Pods_RemoteNotification.framework */; };
|
||||
6611382626AEFC88004BCA9C /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6611382526AEFC88004BCA9C /* NotificationService.swift */; };
|
||||
6611382A26AEFC88004BCA9C /* notificationServiceAppExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 6611382326AEFC88004BCA9C /* notificationServiceAppExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
662C17EF27186152002143AA /* extensionUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 662C17EE27186152002143AA /* extensionUtils.swift */; };
|
||||
6659236226AB0197007D90EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6659236126AB0197007D90EE /* AppDelegate.swift */; };
|
||||
6659236426AB0197007D90EE /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6659236326AB0197007D90EE /* SceneDelegate.swift */; };
|
||||
6659236626AB0197007D90EE /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6659236526AB0197007D90EE /* ContentView.swift */; };
|
||||
6659236826AB0199007D90EE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6659236726AB0199007D90EE /* Assets.xcassets */; };
|
||||
6659236B26AB0199007D90EE /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6659236A26AB0199007D90EE /* Preview Assets.xcassets */; };
|
||||
6659236E26AB0199007D90EE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6659236C26AB0199007D90EE /* LaunchScreen.storyboard */; };
|
||||
665925C026AEE9FF007D90EE /* RemoteNotificationExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 665925BF26AEE9FF007D90EE /* RemoteNotificationExample.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
6611382826AEFC88004BCA9C /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 6659235626AB0197007D90EE /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 6611382226AEFC88004BCA9C;
|
||||
remoteInfo = notificationServiceAppExtension;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
6611382E26AEFC88004BCA9C /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
6611382A26AEFC88004BCA9C /* notificationServiceAppExtension.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1ECEE82CAD9DE35AF82F1FC3 /* Pods-notificationServiceAppExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-notificationServiceAppExtension.release.xcconfig"; path = "Target Support Files/Pods-notificationServiceAppExtension/Pods-notificationServiceAppExtension.release.xcconfig"; sourceTree = "<group>"; };
|
||||
2CD554D3F199AD7F24240B45 /* Pods_notificationContentAppExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_notificationContentAppExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
41B1E7A1AA13BB7E5A2F1E84 /* Pods-notificationContentAppExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-notificationContentAppExtension.release.xcconfig"; path = "Target Support Files/Pods-notificationContentAppExtension/Pods-notificationContentAppExtension.release.xcconfig"; sourceTree = "<group>"; };
|
||||
432CF7AB83561E16C637E70C /* Pods_notificationServiceAppExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_notificationServiceAppExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6611381E26AEEFA8004BCA9C /* RemoteNotification.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RemoteNotification.entitlements; sourceTree = "<group>"; };
|
||||
6611382326AEFC88004BCA9C /* notificationServiceAppExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = notificationServiceAppExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6611382526AEFC88004BCA9C /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
|
||||
6611382726AEFC88004BCA9C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
662C17DC27185E40002143AA /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; };
|
||||
662C17DE27185E40002143AA /* UserNotificationsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotificationsUI.framework; path = System/Library/Frameworks/UserNotificationsUI.framework; sourceTree = SDKROOT; };
|
||||
662C17EE27186152002143AA /* extensionUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = extensionUtils.swift; sourceTree = "<group>"; };
|
||||
6659235E26AB0197007D90EE /* RemoteNotification.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RemoteNotification.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6659236126AB0197007D90EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
6659236326AB0197007D90EE /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||
6659236526AB0197007D90EE /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
6659236726AB0199007D90EE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
6659236A26AB0199007D90EE /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||
6659236D26AB0199007D90EE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
6659236F26AB0199007D90EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
665925BF26AEE9FF007D90EE /* RemoteNotificationExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteNotificationExample.swift; sourceTree = "<group>"; };
|
||||
6664E3DF26B2F06D00267E47 /* notificationServiceAppExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = notificationServiceAppExtension.entitlements; sourceTree = "<group>"; };
|
||||
6664E3EB26B3E16300267E47 /* linphonesw.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = linphonesw.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
66D473A0C66A9722D7DD956E /* Pods-RemoteNotification.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RemoteNotification.release.xcconfig"; path = "Target Support Files/Pods-RemoteNotification/Pods-RemoteNotification.release.xcconfig"; sourceTree = "<group>"; };
|
||||
8DE48A29C8F332901C688A73 /* Pods_RemoteNotification.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RemoteNotification.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A515A7171F0ECA2A24424178 /* Pods-RemoteNotification.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RemoteNotification.debug.xcconfig"; path = "Target Support Files/Pods-RemoteNotification/Pods-RemoteNotification.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
C46F9192382D6A567616CA53 /* Pods-notificationContentAppExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-notificationContentAppExtension.debug.xcconfig"; path = "Target Support Files/Pods-notificationContentAppExtension/Pods-notificationContentAppExtension.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
D27F8878EFCD630F3BCBE2B8 /* Pods-notificationServiceAppExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-notificationServiceAppExtension.debug.xcconfig"; path = "Target Support Files/Pods-notificationServiceAppExtension/Pods-notificationServiceAppExtension.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
6611382026AEFC88004BCA9C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1BA393B95CFA47C282449D0D /* Pods_notificationServiceAppExtension.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
6659235B26AB0197007D90EE /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
41160BCD42850AC1D0891474 /* Pods_RemoteNotification.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
004CBACAC0A9258EC1B47E68 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A515A7171F0ECA2A24424178 /* Pods-RemoteNotification.debug.xcconfig */,
|
||||
66D473A0C66A9722D7DD956E /* Pods-RemoteNotification.release.xcconfig */,
|
||||
D27F8878EFCD630F3BCBE2B8 /* Pods-notificationServiceAppExtension.debug.xcconfig */,
|
||||
1ECEE82CAD9DE35AF82F1FC3 /* Pods-notificationServiceAppExtension.release.xcconfig */,
|
||||
C46F9192382D6A567616CA53 /* Pods-notificationContentAppExtension.debug.xcconfig */,
|
||||
41B1E7A1AA13BB7E5A2F1E84 /* Pods-notificationContentAppExtension.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6611382426AEFC88004BCA9C /* notificationServiceAppExtension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6664E3DF26B2F06D00267E47 /* notificationServiceAppExtension.entitlements */,
|
||||
6611382526AEFC88004BCA9C /* NotificationService.swift */,
|
||||
6611382726AEFC88004BCA9C /* Info.plist */,
|
||||
);
|
||||
path = notificationServiceAppExtension;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6659235526AB0197007D90EE = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6659236026AB0197007D90EE /* RemoteNotification */,
|
||||
6611382426AEFC88004BCA9C /* notificationServiceAppExtension */,
|
||||
6659235F26AB0197007D90EE /* Products */,
|
||||
004CBACAC0A9258EC1B47E68 /* Pods */,
|
||||
F897FB884770B3DFE5695E44 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6659235F26AB0197007D90EE /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6659235E26AB0197007D90EE /* RemoteNotification.app */,
|
||||
6611382326AEFC88004BCA9C /* notificationServiceAppExtension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6659236026AB0197007D90EE /* RemoteNotification */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6611381E26AEEFA8004BCA9C /* RemoteNotification.entitlements */,
|
||||
665925BF26AEE9FF007D90EE /* RemoteNotificationExample.swift */,
|
||||
6659236126AB0197007D90EE /* AppDelegate.swift */,
|
||||
6659236326AB0197007D90EE /* SceneDelegate.swift */,
|
||||
6659236526AB0197007D90EE /* ContentView.swift */,
|
||||
6659236726AB0199007D90EE /* Assets.xcassets */,
|
||||
6659236C26AB0199007D90EE /* LaunchScreen.storyboard */,
|
||||
6659236F26AB0199007D90EE /* Info.plist */,
|
||||
6659236926AB0199007D90EE /* Preview Content */,
|
||||
662C17EE27186152002143AA /* extensionUtils.swift */,
|
||||
);
|
||||
path = RemoteNotification;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6659236926AB0199007D90EE /* Preview Content */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6659236A26AB0199007D90EE /* Preview Assets.xcassets */,
|
||||
);
|
||||
path = "Preview Content";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F897FB884770B3DFE5695E44 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6664E3EB26B3E16300267E47 /* linphonesw.framework */,
|
||||
8DE48A29C8F332901C688A73 /* Pods_RemoteNotification.framework */,
|
||||
432CF7AB83561E16C637E70C /* Pods_notificationServiceAppExtension.framework */,
|
||||
662C17DC27185E40002143AA /* UserNotifications.framework */,
|
||||
662C17DE27185E40002143AA /* UserNotificationsUI.framework */,
|
||||
2CD554D3F199AD7F24240B45 /* Pods_notificationContentAppExtension.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
6611382226AEFC88004BCA9C /* notificationServiceAppExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 6611382B26AEFC88004BCA9C /* Build configuration list for PBXNativeTarget "notificationServiceAppExtension" */;
|
||||
buildPhases = (
|
||||
84FF1DF49B090A0DEA49B794 /* [CP] Check Pods Manifest.lock */,
|
||||
6611381F26AEFC88004BCA9C /* Sources */,
|
||||
6611382026AEFC88004BCA9C /* Frameworks */,
|
||||
6611382126AEFC88004BCA9C /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = notificationServiceAppExtension;
|
||||
productName = notificationServiceAppExtension;
|
||||
productReference = 6611382326AEFC88004BCA9C /* notificationServiceAppExtension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
6659235D26AB0197007D90EE /* RemoteNotification */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 6659238826AB019A007D90EE /* Build configuration list for PBXNativeTarget "RemoteNotification" */;
|
||||
buildPhases = (
|
||||
EDEC068B598CCB116A697A11 /* [CP] Check Pods Manifest.lock */,
|
||||
6659235A26AB0197007D90EE /* Sources */,
|
||||
6659235B26AB0197007D90EE /* Frameworks */,
|
||||
6659235C26AB0197007D90EE /* Resources */,
|
||||
8A6F4F41B2DCEAB2B2C00CF2 /* [CP] Embed Pods Frameworks */,
|
||||
6611382E26AEFC88004BCA9C /* Embed App Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
6611382926AEFC88004BCA9C /* PBXTargetDependency */,
|
||||
);
|
||||
name = RemoteNotification;
|
||||
productName = RemoteNotification;
|
||||
productReference = 6659235E26AB0197007D90EE /* RemoteNotification.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
6659235626AB0197007D90EE /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1300;
|
||||
LastUpgradeCheck = 1250;
|
||||
TargetAttributes = {
|
||||
6611382226AEFC88004BCA9C = {
|
||||
CreatedOnToolsVersion = 12.5.1;
|
||||
};
|
||||
6659235D26AB0197007D90EE = {
|
||||
CreatedOnToolsVersion = 12.5.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 6659235926AB0197007D90EE /* Build configuration list for PBXProject "RemoteNotification" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 6659235526AB0197007D90EE;
|
||||
productRefGroup = 6659235F26AB0197007D90EE /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
6659235D26AB0197007D90EE /* RemoteNotification */,
|
||||
6611382226AEFC88004BCA9C /* notificationServiceAppExtension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
6611382126AEFC88004BCA9C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
6659235C26AB0197007D90EE /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6659236E26AB0199007D90EE /* LaunchScreen.storyboard in Resources */,
|
||||
6659236B26AB0199007D90EE /* Preview Assets.xcassets in Resources */,
|
||||
6659236826AB0199007D90EE /* Assets.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
84FF1DF49B090A0DEA49B794 /* [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-notificationServiceAppExtension-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;
|
||||
};
|
||||
8A6F4F41B2DCEAB2B2C00CF2 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-RemoteNotification/Pods-RemoteNotification-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-RemoteNotification/Pods-RemoteNotification-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RemoteNotification/Pods-RemoteNotification-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
EDEC068B598CCB116A697A11 /* [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-RemoteNotification-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;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
6611381F26AEFC88004BCA9C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6611382626AEFC88004BCA9C /* NotificationService.swift in Sources */,
|
||||
662C17EF27186152002143AA /* extensionUtils.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
6659235A26AB0197007D90EE /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6659236226AB0197007D90EE /* AppDelegate.swift in Sources */,
|
||||
665925C026AEE9FF007D90EE /* RemoteNotificationExample.swift in Sources */,
|
||||
6659236426AB0197007D90EE /* SceneDelegate.swift in Sources */,
|
||||
6659236626AB0197007D90EE /* ContentView.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
6611382926AEFC88004BCA9C /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 6611382226AEFC88004BCA9C /* notificationServiceAppExtension */;
|
||||
targetProxy = 6611382826AEFC88004BCA9C /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
6659236C26AB0199007D90EE /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
6659236D26AB0199007D90EE /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
6611382C26AEFC88004BCA9C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D27F8878EFCD630F3BCBE2B8 /* Pods-notificationServiceAppExtension.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = notificationServiceAppExtension/notificationServiceAppExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = Z2V957B3D6;
|
||||
INFOPLIST_FILE = notificationServiceAppExtension/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.tutorials.notification.notificationServiceAppExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
6611382D26AEFC88004BCA9C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1ECEE82CAD9DE35AF82F1FC3 /* Pods-notificationServiceAppExtension.release.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = notificationServiceAppExtension/notificationServiceAppExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = Z2V957B3D6;
|
||||
INFOPLIST_FILE = notificationServiceAppExtension/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.tutorials.notification.notificationServiceAppExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
6659238626AB019A007D90EE /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
6659238726AB019A007D90EE /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
6659238926AB019A007D90EE /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = A515A7171F0ECA2A24424178 /* Pods-RemoteNotification.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = RemoteNotification/RemoteNotification.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"RemoteNotification/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = Z2V957B3D6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = RemoteNotification/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.tutorials.notification;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
6659238A26AB019A007D90EE /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 66D473A0C66A9722D7DD956E /* Pods-RemoteNotification.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = RemoteNotification/RemoteNotification.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"RemoteNotification/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = Z2V957B3D6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
INFOPLIST_FILE = RemoteNotification/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.linphone.tutorials.notification;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
6611382B26AEFC88004BCA9C /* Build configuration list for PBXNativeTarget "notificationServiceAppExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
6611382C26AEFC88004BCA9C /* Debug */,
|
||||
6611382D26AEFC88004BCA9C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
6659235926AB0197007D90EE /* Build configuration list for PBXProject "RemoteNotification" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
6659238626AB019A007D90EE /* Debug */,
|
||||
6659238726AB019A007D90EE /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
6659238826AB019A007D90EE /* Build configuration list for PBXNativeTarget "RemoteNotification" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
6659238926AB019A007D90EE /* Debug */,
|
||||
6659238A26AB019A007D90EE /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 6659235626AB0197007D90EE /* Project object */;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
@ -0,0 +1,8 @@
|
||||
<?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>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,60 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// LoginTutorial
|
||||
//
|
||||
// Created by QuentinArguillere on 31/07/2020.
|
||||
// Copyright © 2020 BelledonneCommunications. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SwiftUI
|
||||
import UserNotifications
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
|
||||
|
||||
@ObservedObject var tutorialContext = RemoteNotificationTutorialContext()
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
registerForPushNotifications()
|
||||
return true
|
||||
}
|
||||
|
||||
// MARK: UISceneSession Lifecycle
|
||||
|
||||
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
|
||||
// Called when a new scene session is being created.
|
||||
// Use this method to select a configuration to create the new scene with.
|
||||
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
|
||||
// Called when the user discards a scene session.
|
||||
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
|
||||
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
||||
var stringifiedToken = deviceToken.map{String(format: "%02X", $0)}.joined()
|
||||
stringifiedToken.append(String(":remote"))
|
||||
tutorialContext.mCore.didRegisterForRemotePushWithStringifiedToken(deviceTokenStr: stringifiedToken)
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]
|
||||
, fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
|
||||
|
||||
}
|
||||
func registerForPushNotifications() {
|
||||
//1
|
||||
UNUserNotificationCenter.current()
|
||||
//2
|
||||
.requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
|
||||
//3
|
||||
print("Permission granted: \(granted)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "1x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x",
|
||||
"size" : "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
@ -0,0 +1,87 @@
|
||||
//
|
||||
// ContentView.swift
|
||||
// LoginTutorial
|
||||
//
|
||||
// Created by QuentinArguillere on 31/07/2020.
|
||||
// Copyright © 2020 BelledonneCommunications. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ContentView: View {
|
||||
|
||||
@ObservedObject var tutorialContext : RemoteNotificationTutorialContext
|
||||
|
||||
var body: some View {
|
||||
|
||||
VStack {
|
||||
Group {
|
||||
HStack {
|
||||
Text("Username:")
|
||||
.font(.title)
|
||||
TextField("", text : $tutorialContext.username)
|
||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
.disabled(tutorialContext.loggedIn)
|
||||
}
|
||||
HStack {
|
||||
Text("Password:")
|
||||
.font(.title)
|
||||
TextField("", text : $tutorialContext.passwd)
|
||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
.disabled(tutorialContext.loggedIn)
|
||||
}
|
||||
HStack {
|
||||
Text("Domain:")
|
||||
.font(.title)
|
||||
TextField("", text : $tutorialContext.domain)
|
||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
.disabled(tutorialContext.loggedIn)
|
||||
}
|
||||
Picker(selection: $tutorialContext.transportType, label: Text("Transport:")) {
|
||||
Text("TLS").tag("TLS")
|
||||
Text("TCP").tag("TCP")
|
||||
Text("UDP").tag("UDP")
|
||||
}.pickerStyle(SegmentedPickerStyle()).padding()
|
||||
VStack {
|
||||
HStack {
|
||||
Button(action: {
|
||||
if (self.tutorialContext.loggedIn)
|
||||
{
|
||||
self.tutorialContext.unregister()
|
||||
self.tutorialContext.delete()
|
||||
} else {
|
||||
self.tutorialContext.login()
|
||||
}
|
||||
})
|
||||
{
|
||||
Text(tutorialContext.loggedIn ? "Log out & \ndelete account" : "Create & \nlog in account")
|
||||
.font(.largeTitle)
|
||||
.foregroundColor(Color.white)
|
||||
.frame(width: 220.0, height: 90)
|
||||
.background(Color.gray)
|
||||
}
|
||||
|
||||
}
|
||||
HStack {
|
||||
Text("Login State : ")
|
||||
.font(.footnote)
|
||||
Text(tutorialContext.loggedIn ? "Logged in" : "Unregistered")
|
||||
.font(.footnote)
|
||||
.foregroundColor(tutorialContext.loggedIn ? Color.green : Color.black)
|
||||
}.padding(.top, 10.0)
|
||||
}
|
||||
}
|
||||
Group {
|
||||
Spacer()
|
||||
Text("Core Version is \(tutorialContext.coreVersion)")
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView(tutorialContext: RemoteNotificationTutorialContext())
|
||||
}
|
||||
}
|
68
ios/swift/8-RemoteNotification/RemoteNotification/Info.plist
Normal file
68
ios/swift/8-RemoteNotification/RemoteNotification/Info.plist
Normal file
@ -0,0 +1,68 @@
|
||||
<?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>RemoteNotification</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>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<false/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Default Configuration</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>remote-notification</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?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>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.org.linphone.tutorials.notification</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,103 @@
|
||||
//
|
||||
// LoginExample.swift
|
||||
// LoginTutorial
|
||||
//
|
||||
// Created by QuentinArguillere on 31/07/2020.
|
||||
// Copyright © 2020 BelledonneCommunications. All rights reserved.
|
||||
//
|
||||
|
||||
import linphonesw
|
||||
var APP_GROUP_ID = "group.org.linphone.tutorials.notification"
|
||||
|
||||
class RemoteNotificationTutorialContext : ObservableObject
|
||||
{
|
||||
var mCore: Core!
|
||||
@Published var coreVersion: String = Core.getVersion
|
||||
|
||||
/*------------ Login tutorial related variables -------*/
|
||||
var mRegistrationDelegate : CoreDelegate!
|
||||
@Published var username : String = "user"
|
||||
@Published var passwd : String = "password"
|
||||
@Published var domain : String = "sip.example.org"
|
||||
@Published var loggedIn: Bool = false
|
||||
@Published var transportType : String = "TLS"
|
||||
|
||||
init()
|
||||
{
|
||||
|
||||
LoggingService.Instance.logLevel = LogLevel.Debug
|
||||
|
||||
let config = Config.newForSharedCore(appGroupId: APP_GROUP_ID, configFilename: "linphonerc", factoryConfigFilename: "")!
|
||||
try? mCore = Factory.Instance.createSharedCoreWithConfig(config: config, systemContext: nil, appGroupId: APP_GROUP_ID, mainCore: true)
|
||||
mCore.pushNotificationEnabled = true
|
||||
// Core start/stop will be done in the scene delegate enter foreground/background
|
||||
|
||||
mRegistrationDelegate = CoreDelegateStub(onAccountRegistrationStateChanged: { (core: Core, account: Account, state: RegistrationState, message: String) in
|
||||
NSLog("New registration state is \(state) for user id \( String(describing: account.params?.identityAddress?.asString()))\n")
|
||||
if (state == .Ok) {
|
||||
self.loggedIn = true
|
||||
} else if (state == .Cleared) {
|
||||
self.loggedIn = false
|
||||
}
|
||||
})
|
||||
mCore.addDelegate(delegate: mRegistrationDelegate)
|
||||
}
|
||||
|
||||
func login() {
|
||||
|
||||
do {
|
||||
var transport : TransportType
|
||||
if (transportType == "TLS") { transport = TransportType.Tls }
|
||||
else if (transportType == "TCP") { transport = TransportType.Tcp }
|
||||
else { transport = TransportType.Udp }
|
||||
|
||||
let authInfo = try Factory.Instance.createAuthInfo(username: username, userid: "", passwd: passwd, ha1: "", realm: "", domain: domain)
|
||||
let accountParams = try mCore.createAccountParams()
|
||||
|
||||
let identity = try Factory.Instance.createAddress(addr: String("sip:" + username + "@" + domain))
|
||||
try! accountParams.setIdentityaddress(newValue: identity)
|
||||
|
||||
let address = try Factory.Instance.createAddress(addr: String("sip:" + domain))
|
||||
|
||||
try address.setTransport(newValue: transport)
|
||||
try accountParams.setServeraddress(newValue: address)
|
||||
accountParams.registerEnabled = true
|
||||
|
||||
// Set the provider to the development apple push notification servers, not the production ones.
|
||||
// Make sure your flexisip server has a matching certificate to send the pushes
|
||||
accountParams.pushNotificationConfig?.provider = "apns.dev"
|
||||
|
||||
// We use remote notifications in this tutorials, not VOIP ones
|
||||
accountParams.pushNotificationAllowed = false
|
||||
accountParams.remotePushNotificationAllowed = true
|
||||
|
||||
// We need a conference factory URI set on the Account to be able to create chat rooms with flexisip backend
|
||||
accountParams.conferenceFactoryUri = "sip:conference-factory@sip.linphone.org"
|
||||
|
||||
let account = try mCore.createAccount(params: accountParams)
|
||||
|
||||
mCore.addAuthInfo(info: authInfo)
|
||||
try mCore.addAccount(account: account)
|
||||
|
||||
mCore.defaultAccount = account
|
||||
|
||||
} catch { NSLog(error.localizedDescription) }
|
||||
}
|
||||
|
||||
func unregister()
|
||||
{
|
||||
if let account = mCore.defaultAccount {
|
||||
let params = account.params
|
||||
let clonedParams = params?.clone()
|
||||
clonedParams?.registerEnabled = false
|
||||
account.params = clonedParams
|
||||
}
|
||||
}
|
||||
func delete() {
|
||||
if let account = mCore.defaultAccount {
|
||||
mCore.removeAccount(account: account)
|
||||
mCore.clearAccounts()
|
||||
mCore.clearAllAuthInfo()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
//
|
||||
// SceneDelegate.swift
|
||||
// LoginTutorial
|
||||
//
|
||||
// Created by QuentinArguillere on 31/07/2020.
|
||||
// Copyright © 2020 BelledonneCommunications. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SwiftUI
|
||||
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
var tutorialContext = (UIApplication.shared.delegate as! AppDelegate).tutorialContext
|
||||
|
||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
||||
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
||||
|
||||
// Create the SwiftUI view that provides the window contents.
|
||||
let contentView = ContentView(tutorialContext: tutorialContext)
|
||||
|
||||
// Use a UIHostingController as window root view controller.
|
||||
if let windowScene = scene as? UIWindowScene {
|
||||
let window = UIWindow(windowScene: windowScene)
|
||||
window.rootViewController = UIHostingController(rootView: contentView)
|
||||
self.window = window
|
||||
window.makeKeyAndVisible()
|
||||
}
|
||||
}
|
||||
|
||||
func sceneDidDisconnect(_ scene: UIScene) {
|
||||
// Called as the scene is being released by the system.
|
||||
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
||||
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
||||
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
|
||||
}
|
||||
|
||||
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||
// Called when the scene has moved from an inactive state to an active state.
|
||||
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
||||
}
|
||||
|
||||
func sceneWillResignActive(_ scene: UIScene) {
|
||||
// Called when the scene will move from an active state to an inactive state.
|
||||
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
||||
}
|
||||
|
||||
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the background to the foreground.
|
||||
// Use this method to undo the changes made on entering the background.
|
||||
try! tutorialContext.mCore.start()
|
||||
}
|
||||
|
||||
func sceneDidEnterBackground(_ scene: UIScene) {
|
||||
// Called as the scene transitions from the foreground to the background.
|
||||
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
||||
// to restore the scene back to its current state.
|
||||
tutorialContext.mCore.stopAsync()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
|
||||
import linphonesw
|
||||
|
||||
enum LinphoneError: Error {
|
||||
case timeout
|
||||
case loggingServiceUninitialized
|
||||
}
|
||||
|
||||
class LinphoneLoggingServiceManager: LoggingServiceDelegate {
|
||||
init(config: Config, log: LoggingService?, domain: String) throws {
|
||||
if let log = log {
|
||||
let debugLevel = config.getInt(section: "app", key: "debugenable_preference", defaultValue: LogLevel.Debug.rawValue)
|
||||
let debugEnabled = (debugLevel >= LogLevel.Debug.rawValue && debugLevel < LogLevel.Error.rawValue)
|
||||
|
||||
Factory.Instance.logCollectionPath = Factory.Instance.getDownloadDir(context: UnsafeMutablePointer<Int8>(mutating: (APP_GROUP_ID as NSString).utf8String))
|
||||
Factory.Instance.enableLogCollection(state: debugEnabled ? LogCollectionState.Enabled : LogCollectionState.Disabled)
|
||||
log.domain = domain
|
||||
log.logLevel = debugLevel==0 ? LogLevel.Fatal : LogLevel(rawValue: debugLevel)
|
||||
log.addDelegate(delegate: self)
|
||||
} else {
|
||||
throw LinphoneError.loggingServiceUninitialized
|
||||
}
|
||||
}
|
||||
|
||||
func onLogMessageWritten(logService: LoggingService, domain: String, level: LogLevel, message: String) {
|
||||
let levelStr: String
|
||||
|
||||
switch level {
|
||||
case .Debug:
|
||||
levelStr = "Debug"
|
||||
case .Trace:
|
||||
levelStr = "Trace"
|
||||
case .Message:
|
||||
levelStr = "Message"
|
||||
case .Warning:
|
||||
levelStr = "Warning"
|
||||
case .Error:
|
||||
levelStr = "Error"
|
||||
case .Fatal:
|
||||
levelStr = "Fatal"
|
||||
default:
|
||||
levelStr = "unknown"
|
||||
}
|
||||
|
||||
NSLog("\(levelStr) [\(domain)] \(message)\n")
|
||||
}
|
||||
}
|
@ -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>notificationServiceAppExtension</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>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</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>
|
@ -0,0 +1,156 @@
|
||||
//
|
||||
// NotificationService.swift
|
||||
// notificationServiceAppExtension
|
||||
//
|
||||
// Created by QuentinArguillere on 26/07/2021.
|
||||
//
|
||||
|
||||
import UserNotifications
|
||||
import linphonesw
|
||||
|
||||
var APP_GROUP_ID = "group.org.linphone.tutorials.notification"
|
||||
var LINPHONE_DUMMY_SUBJECT = "dummy subject"
|
||||
|
||||
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?
|
||||
static var logDelegate: LinphoneLoggingServiceManager!
|
||||
static var log: LoggingService!
|
||||
|
||||
func stopCore() {
|
||||
NotificationService.log.message(message: "stop core")
|
||||
if let lc = lc {
|
||||
lc.stop()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This function will be called when the app received a notification while in background // closed
|
||||
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
|
||||
self.contentHandler = contentHandler
|
||||
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
||||
NSLog("[notificationServiceAppExtension] start notificationServiceAppExtension")
|
||||
|
||||
if let bestAttemptContent = bestAttemptContent {
|
||||
|
||||
NSLog("[notificationServiceAppExtension] create core")
|
||||
let config = Config.newForSharedCore(appGroupId: APP_GROUP_ID, configFilename: "linphonerc", factoryConfigFilename: "")
|
||||
if (NotificationService.log == nil) {
|
||||
NotificationService.log = LoggingService.Instance /*enable liblinphone logs.*/
|
||||
NotificationService.logDelegate = try! LinphoneLoggingServiceManager(config: config!, log: NotificationService.log, domain: "notificationServiceAppExtension")
|
||||
}
|
||||
// We are creating a shared core, which will use the configuration file form the main app thanks to the App Group
|
||||
lc = try! Factory.Instance.createSharedCoreWithConfig(config: config!, systemContext: nil, appGroupId: APP_GROUP_ID, mainCore: false)
|
||||
NotificationService.log.message(message: "received push payload : \(bestAttemptContent.userInfo.debugDescription)")
|
||||
|
||||
|
||||
// Flexisip sends 2 types of remote push : invitation to a group chatroom, or receiving a chat message
|
||||
if let chatRoomInviteAddr = bestAttemptContent.userInfo["chat-room-addr"] as? String, !chatRoomInviteAddr.isEmpty {
|
||||
NotificationService.log.message(message: "fetch chat room for invite, addr: \(chatRoomInviteAddr)")
|
||||
|
||||
// create a chatroom with the address we received
|
||||
let chatRoom = lc!.getNewChatRoomFromConfAddr(chatRoomAddr: chatRoomInviteAddr)
|
||||
|
||||
if let chatRoom = chatRoom {
|
||||
stopCore()
|
||||
NotificationService.log.message(message: "chat room invite received")
|
||||
|
||||
// Update notification body to display custom information
|
||||
bestAttemptContent.title = "You have been invited to a chatroom"
|
||||
if (chatRoom.hasCapability(mask:ChatRoomCapabilities.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 {
|
||||
NotificationService.log.message(message: "fetch msg for callid ["+callId+"]")
|
||||
// Get message content from the call id we received
|
||||
let message = lc!.getNewMessageFromCallid(callId: callId)
|
||||
|
||||
if let message = message {
|
||||
|
||||
func parseMessage(message: PushNotificationMessage) -> MsgData? {
|
||||
let content = message.isText ? message.textContent : "🗻"
|
||||
let fromAddr = message.fromAddr?.username
|
||||
let callId = message.callId
|
||||
let localUri = message.localAddr?.asStringUriOnly()
|
||||
let peerUri = message.peerAddr?.asStringUriOnly()
|
||||
var msgData = MsgData(from: fromAddr, body: "", subtitle: "", callId:callId, localAddr: localUri, peerAddr:peerUri)
|
||||
|
||||
if let subject = message.subject as String?, subject != "" {
|
||||
msgData.subtitle = subject
|
||||
msgData.body = fromAddr! + " : " + content
|
||||
} else {
|
||||
msgData.subtitle = fromAddr
|
||||
msgData.body = content
|
||||
}
|
||||
|
||||
NotificationService.log.message(message: "received msg size : \(content.count) \n")
|
||||
return msgData;
|
||||
}
|
||||
let msgData = parseMessage(message: message)
|
||||
|
||||
stopCore()
|
||||
|
||||
// Fill notification body with custom informations
|
||||
bestAttemptContent.title = "Message received"
|
||||
if let subtitle = msgData?.subtitle {
|
||||
bestAttemptContent.subtitle = subtitle
|
||||
}
|
||||
if let body = msgData?.body {
|
||||
bestAttemptContent.body = body
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
contentHandler(bestAttemptContent)
|
||||
return
|
||||
} else {
|
||||
NotificationService.log.message(message: "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.
|
||||
NotificationService.log.warning(message: "serviceExtensionTimeWillExpire")
|
||||
stopCore()
|
||||
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
|
||||
NSLog("[notificationServiceAppExtension] serviceExtensionTimeWillExpire")
|
||||
|
||||
if let chatRoomInviteAddr = bestAttemptContent.userInfo["chat-room-addr"] as? String, !chatRoomInviteAddr.isEmpty {
|
||||
bestAttemptContent.title = "You have been invited to a chatroom"
|
||||
} else {
|
||||
bestAttemptContent.title = "You have received a message"
|
||||
}
|
||||
contentHandler(bestAttemptContent)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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.org.linphone.tutorials.notification</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
Loading…
Reference in New Issue
Block a user