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:
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user