122 lines
4.0 KiB
Swift
122 lines
4.0 KiB
Swift
//
|
|
// LinphoneAsyncWrapper.swift
|
|
// CallKitTutorial
|
|
//
|
|
// Created by CD on 13/09/2023.
|
|
// Copyright © 2023 BelledonneCommunications. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import Combine
|
|
import linphonesw
|
|
|
|
var coreQueue : DispatchQueue = DispatchQueue(label:"core.queue")
|
|
var cancellables = Set<AnyCancellable>()
|
|
|
|
// A publisher object that can old one or many LinphoneObject objects.
|
|
|
|
public class LinphoneObjectsPublisher <T> : Publisher {
|
|
public typealias Output = T
|
|
public typealias Failure = Error
|
|
let passThroughSubject = PassthroughSubject<Output, Failure>()
|
|
public func receive<S>(subscriber: S) where S : Subscriber, S.Failure == Failure, S.Input == Output {
|
|
passThroughSubject.receive(subscriber: subscriber)
|
|
}
|
|
|
|
public func send(completion: Subscribers.Completion<Failure>) {
|
|
passThroughSubject.send(completion: completion)
|
|
}
|
|
|
|
@discardableResult
|
|
public func postOnMainQueue(onError :@escaping ((Error) -> Void) = {_ in }, receiveValue:@escaping ((Output) -> Void)) -> LinphoneObjectsPublisher <T>{
|
|
doOnQueue(onError,receiveValue,queue: DispatchQueue.main)
|
|
return self
|
|
}
|
|
|
|
@discardableResult
|
|
public func postOnCoreQueue(onError :@escaping ((Error) -> Void) = {_ in }, receiveValue:@escaping ((Output) -> Void)) -> LinphoneObjectsPublisher <T>{
|
|
doOnQueue(onError,receiveValue,queue: coreQueue)
|
|
return self
|
|
}
|
|
|
|
|
|
private func doOnQueue(_ onError :@escaping ((Error) -> Void) = {_ in }, _ receiveValue:@escaping ((Output) -> Void), queue:DispatchQueue) {
|
|
passThroughSubject.receive(on:queue)
|
|
.sink { error in
|
|
onError(error as! Error)
|
|
} receiveValue: { result in
|
|
receiveValue(result)
|
|
}.store(in: &cancellables)
|
|
}
|
|
|
|
var savedReference : Any? = nil // Used when a reference is needed to avoid object from beeing GCd (example delegate stubs)
|
|
convenience init (reference: Any) {
|
|
self.init()
|
|
savedReference = reference
|
|
}
|
|
}
|
|
|
|
public class LinphoneAsyncHelper {
|
|
|
|
func postOnCoreQueue(lambda : @escaping ()->()) {
|
|
coreQueue.async {
|
|
lambda()
|
|
}
|
|
}
|
|
|
|
func postOnMainQueue(lambda : @escaping()->()) {
|
|
DispatchQueue.main.async {
|
|
lambda()
|
|
}
|
|
}
|
|
|
|
// Creates a publisher from the object created by the action passed as parameter
|
|
// For example if passed a create core call this function will create the LinphoneObject Core on core queue, and created object will be published through the built publisher
|
|
func createLinphoneObjectWithPublisher<LinphoneObject>(createAction:@escaping()throws -> LinphoneObject ) -> LinphoneObjectsPublisher<LinphoneObject> {
|
|
let publisher = LinphoneObjectsPublisher<LinphoneObject>()
|
|
coreQueue.async {
|
|
do {
|
|
publisher.passThroughSubject.send(try createAction())
|
|
} catch {
|
|
publisher.send(completion: .failure(error))
|
|
}
|
|
}
|
|
return publisher
|
|
}
|
|
|
|
}
|
|
|
|
extension Core {
|
|
|
|
// Methods below would generated by a script similar to the one that creates LinphoneWrapper
|
|
|
|
public func createAccountRegistrationStateChangedPublisher() -> LinphoneObjectsPublisher<(core:Core, account:Account, state:RegistrationState, message:String)> {
|
|
let publisher = LinphoneObjectsPublisher<(core:Core, account:Account, state:RegistrationState, message:String)>()
|
|
let coreDelegate = CoreDelegateStub (
|
|
onAccountRegistrationStateChanged: { (core: Core, account: Account, state: RegistrationState, message: String) in
|
|
publisher.passThroughSubject.send((core,account,state,message))
|
|
})
|
|
publisher.savedReference = coreDelegate
|
|
addDelegate(delegate: coreDelegate)
|
|
return publisher
|
|
}
|
|
|
|
public func createOnCallStateChangedPublisher() -> LinphoneObjectsPublisher<(core: Core, call: Call, state: Call.State, message: String)> {
|
|
let publisher = LinphoneObjectsPublisher<(core: Core, call: Call, state: Call.State, message: String)>()
|
|
let coreDelegate = CoreDelegateStub (
|
|
onCallStateChanged: { (core: Core, call: Call, state: Call.State, message: String) in
|
|
publisher.passThroughSubject.send((core,call,state,message))
|
|
})
|
|
publisher.savedReference = coreDelegate
|
|
addDelegate(delegate: coreDelegate)
|
|
return publisher
|
|
}
|
|
|
|
|
|
|
|
// ...
|
|
}
|
|
|
|
|
|
|