Add configuration file to the push tutorial, in order to have have the incoming calls work even if the app was terminated and is launch by the push notification

This commit is contained in:
QuentinArguillere
2020-08-13 11:22:56 +02:00
parent 0f086498e4
commit cc895c57b0
4 changed files with 50 additions and 46 deletions

View File

@@ -12,7 +12,7 @@ import SwiftUI
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
@ObservedObject var tutorialContext = CallExampleContext()
@ObservedObject var tutorialContext = CallKitExampleContext()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

View File

@@ -9,7 +9,7 @@
import linphonesw
import AVFoundation
class CallExampleContext : ObservableObject
class CallKitExampleContext : ObservableObject
{
var mCore: Core! // We need a Core for... anything, basically
@Published var coreVersion: String = Core.getVersion
@@ -59,50 +59,59 @@ class CallExampleContext : ObservableObject
log!.logLevel = LogLevel.Debug
factory.enableLogCollection(state: LogCollectionState.Enabled)
// Initialize Linphone Core
try? mCore = factory.createCore(configPath: "", factoryConfigPath: "", systemContext: nil)
// Initialize Linphone Core.
// IMPORTANT : In this tutorial, we require the use of a core configuration file.
// This way, once the registration is done, and until it is cleared, it will return to the LoggedIn state on launch.
// This allows us to have a functional call when the app was closed and is started by a VOIP push notification (incoming call)
let configDir = factory.getConfigDir(context: nil)
try? mCore = factory.createCore(configPath: "\(configDir)/MyConfig", factoryConfigPath: "", systemContext: nil)
// main loop for receiving notifications and doing background linphonecore work:
mCore.autoIterateEnabled = true
mCore.callkitEnabled = true
mCore.pushNotificationEnabled = true
// This is necessary to register to the server and handle push Notifications. Make sure you have a certificate to match your app's bundle ID.
let pushConfig = mCore.pushNotificationConfig!
pushConfig.provider = "apns.dev"
try? mCore.start()
mVideoDevices = mCore.videoDevicesList
// Callbacks on registration and call events
mCore.addDelegate(delegate: mCallStateTracer)
mCore.addDelegate(delegate: mRegistrationDelegate)
// Available video devices that can be selected to be used in video calls
mVideoDevices = mCore.videoDevicesList
}
func registrationExample()
{
let factory = Factory.Instance
do {
proxy_cfg = try mCore.createProxyConfig()
let address = try factory.createAddress(addr: id)
let info = try factory.createAuthInfo(username: address.username, userid: "", passwd: passwd, ha1: "", realm: "", domain: address.domain)
mCore.addAuthInfo(info: info)
try proxy_cfg.setIdentityaddress(newValue: address)
let server_addr = "sip:" + address.domain + ";transport=tls"
try proxy_cfg.setServeraddr(newValue: server_addr)
proxy_cfg.registerEnabled = true
proxy_cfg.pushNotificationAllowed = true
try mCore.addProxyConfig(config: proxy_cfg)
if ( mCore.defaultProxyConfig == nil)
{
// IMPORTANT : default proxy config setting MUST be done AFTER adding the config to the core !
mCore.defaultProxyConfig = proxy_cfg
}
if (!loggedIn) // Do not allow multiple registrations for this tutorial
{
let factory = Factory.Instance
do {
proxy_cfg = try mCore.createProxyConfig()
let address = try factory.createAddress(addr: id)
let info = try factory.createAuthInfo(username: address.username, userid: "", passwd: passwd, ha1: "", realm: "", domain: address.domain)
mCore.addAuthInfo(info: info)
try proxy_cfg.setIdentityaddress(newValue: address)
let server_addr = "sip:" + address.domain + ";transport=tls"
try proxy_cfg.setServeraddr(newValue: server_addr)
proxy_cfg.registerEnabled = true
proxy_cfg.pushNotificationAllowed = true
try mCore.addProxyConfig(config: proxy_cfg)
if ( mCore.defaultProxyConfig == nil)
{
// IMPORTANT : default proxy config setting MUST be done AFTER adding the config to the core !
mCore.defaultProxyConfig = proxy_cfg
}
} catch {
print(error)
} catch {
print(error)
}
}
}
@@ -112,7 +121,6 @@ class CallExampleContext : ObservableObject
loggedIn = false
}
func createCallParams() throws -> CallParams
{
let callParams = try mCore.createCallParams(call: nil)
@@ -178,7 +186,7 @@ class CallExampleContext : ObservableObject
// Callback for actions when a change in the Registration State happens
class LinphoneRegistrationDelegate: CoreDelegate {
var tutorialContext : CallExampleContext!
var tutorialContext : CallKitExampleContext!
override func onRegistrationStateChanged(core lc: Core, proxyConfig cfg: ProxyConfig, state cstate: RegistrationState, message: String?) {
print("New registration state \(cstate) for user id \( String(describing: cfg.identityAddress?.asString()))\n")
@@ -192,7 +200,7 @@ class LinphoneRegistrationDelegate: CoreDelegate {
class LinphoneLoggingServiceManager: LoggingServiceDelegate {
var tutorialContext : CallExampleContext!
var tutorialContext : CallKitExampleContext!
override func onLogMessageWritten(logService: LoggingService, domain: String, level lev: LogLevel, message: String) {
if (tutorialContext.logsEnabled)
@@ -206,7 +214,7 @@ class LinphoneLoggingServiceManager: LoggingServiceDelegate {
// Callback for actions when a change in the Call State happens
class CallStateDelegate: CoreDelegate {
var tutorialContext : CallExampleContext!
var tutorialContext : CallKitExampleContext!
override func onCallStateChanged(core lc: Core, call: Call, state cstate: Call.State, message: String) {
print("CallTrace - \(cstate)")
@@ -219,11 +227,6 @@ class CallStateDelegate: CoreDelegate {
if (cstate == .PushIncomingReceived)
{
if (!tutorialContext.loggedIn)
{
// Cannot properly answer call if not registered. If the app was launched from a push notification, register.
tutorialContext.registrationExample()
}
// We're being called by someone (and app is in background)
initIncomingCall()
}

View File

@@ -16,12 +16,12 @@ class CallKitProviderDelegate : NSObject
{
private let provider: CXProvider
let mCallController = CXCallController()
var tutorialContext : CallExampleContext!
var tutorialContext : CallKitExampleContext!
var incomingCallUUID : UUID!
var outgoingCallUUID : UUID!
init(context : CallExampleContext)
init(context: CallKitExampleContext)
{
tutorialContext = context
let providerConfiguration = CXProviderConfiguration(localizedName: Bundle.main.infoDictionary!["CFBundleName"] as! String)
@@ -33,7 +33,7 @@ class CallKitProviderDelegate : NSObject
provider = CXProvider(configuration: providerConfiguration)
super.init()
provider.setDelegate(self, queue: nil)
provider.setDelegate(self, queue: nil) // The CXProvider delegate will trigger CallKit related callbacks
}
@@ -44,7 +44,7 @@ class CallKitProviderDelegate : NSObject
let startCallAction = CXStartCallAction(call: outgoingCallUUID, handle: handle)
let transaction = CXTransaction(action: startCallAction)
provider.reportOutgoingCall(with: outgoingCallUUID, startedConnectingAt: nil)
provider.reportOutgoingCall(with: outgoingCallUUID, startedConnectingAt: nil) // Report to CallKit a call is starting
mCallController.request(transaction, completion: { error in })
}
@@ -55,7 +55,7 @@ class CallKitProviderDelegate : NSObject
update.remoteHandle = CXHandle(type:.generic, value: tutorialContext.incomingCallName)
update.hasVideo = tutorialContext.videoEnabled
provider.reportNewIncomingCall(with: incomingCallUUID, update: update, completion: { error in })
provider.reportNewIncomingCall(with: incomingCallUUID, update: update, completion: { error in }) // Report to CallKit a call is incoming
}
func stopCall()
@@ -69,13 +69,14 @@ class CallKitProviderDelegate : NSObject
let endCallAction = CXEndCallAction(call: callId)
let transaction = CXTransaction(action: endCallAction)
mCallController.request(transaction, completion: { error in })
mCallController.request(transaction, completion: { error in }) // Report to CallKit a call is incoming
}
}
// In this extension, we implement the action we want to be done when CallKit is notified of something.
// This can happen through the CallKit GUI in the app, or directly in the code (see outgoingCall(), incomingCall(), stopCall() functions above)
extension CallKitProviderDelegate: CXProviderDelegate {
func provider(_ provider: CXProvider, perform action: CXEndCallAction) {

View File

@@ -10,7 +10,7 @@ import SwiftUI
struct ContentView: View {
@ObservedObject var tutorialContext : CallExampleContext
@ObservedObject var tutorialContext : CallKitExampleContext
func getCallButtonText() -> String
{
@@ -160,6 +160,6 @@ struct ContentView: View {
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(tutorialContext: CallExampleContext())
ContentView(tutorialContext: CallKitExampleContext())
}
}