Created
June 10, 2021 20:48
-
-
Save wvteijlingen/29cae27d4fdc28c4d83460acbe4fe552 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import CallKit | |
import Foundation | |
class PhoneCaller: NSObject { | |
typealias OnCallConnected = () -> Void | |
static let shared: PhoneCaller = PhoneCaller() | |
private let observer = CXCallObserver() | |
private var isCalling: Bool = false | |
private var onCallConnected: OnCallConnected? | |
override init() { | |
super.init() | |
observer.setDelegate(self, queue: nil) | |
} | |
/// Shows the OS dialog for calling the given `telephoneNumber`. If the call connects, | |
/// the `onCallConnected` callback will be executed. | |
/// | |
/// - Parameters: | |
/// - telephoneNumber: The number to call. | |
/// - onCallConnected: Executed when the call connects. | |
func call(_ telephoneNumber: String, onCallConnected: OnCallConnected? = nil) { | |
reset() | |
guard | |
let url = URL(string: "tel://\(telephoneNumber)"), | |
UIApplication.shared.canOpenURL(url) | |
else { | |
return | |
} | |
self.onCallConnected = onCallConnected | |
UIApplication.shared.open(url, options: [:]) { success in | |
if !success { | |
self.reset() | |
} | |
} | |
} | |
private func reset() { | |
isCalling = false | |
onCallConnected = nil | |
} | |
private func debugPrint(_ call: CXCall) { | |
print("--------------") | |
print("hasConnected: \(call.hasConnected)") | |
print("hasEnded: \(call.hasEnded)") | |
print("isOnHold: \(call.isOnHold)") | |
print("isOutgoing: \(call.isOutgoing)") | |
print("appState: \(UIApplication.shared.applicationState.rawValue)") | |
print("--------------") | |
} | |
} | |
extension PhoneCaller: CXCallObserverDelegate { | |
func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) { | |
// debugPrint(call) | |
guard let onCallConnected = onCallConnected, call.isOutgoing else { return } | |
if UIApplication.shared.applicationState == .active && !call.hasEnded { | |
isCalling = true | |
} | |
if isCalling { | |
if call.hasConnected { | |
onCallConnected() | |
reset() | |
} else if call.hasEnded { | |
reset() | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment