Skip to content

Commit

Permalink
CallKit QuickStart sample app improvements (#56)
Browse files Browse the repository at this point in the history
This PR has following changes -

StartCall - Avoid updating call.
Report Connected Call state to CallKit for outgoing call.
Disconnect from the Room on providerDidReset callback.
Following speakerbox's guidelines to configure audio session while simulating incoming call
  • Loading branch information
piyushtank authored Dec 27, 2016
1 parent b06a895 commit e75d458
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 49 deletions.
68 changes: 35 additions & 33 deletions VideoCallKitQuickStart/ViewController+CallKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extension ViewController : CXProviderDelegate {
logMessage(messageText: "providerDidReset:")

localMedia?.audioController.stopAudio()
room?.disconnect()
}

func providerDidBegin(_ provider: CXProvider) {
Expand All @@ -39,30 +40,40 @@ extension ViewController : CXProviderDelegate {
func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
logMessage(messageText: "provider:performStartCallAction:")

/*
* Configure the audio session, but do not start call audio here, since it must be done once
* the audio session has been activated by the system after having its priority elevated.
*/
localMedia?.audioController.configureAudioSession(.videoChatSpeaker)

callKitProvider.reportOutgoingCall(with: action.callUUID, startedConnectingAt: nil)

performRoomConnect(uuid: action.callUUID, roomName: action.handle.value)

// Hang on to the action, as we will either fulfill it after we succesfully connect to the room, or fail
// it if there is an error connecting.
pendingAction = action

performRoomConnect(uuid: action.callUUID, roomName: action.handle.value) { (success) in
if (success) {
provider.reportOutgoingCall(with: action.callUUID, connectedAt: Date())
action.fulfill()
} else {
action.fail()
}
}
}

func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
logMessage(messageText: "provider:performAnswerCallAction:")

// NOTE: When using CallKit with VoIP pushes, the workaround from https://forums.developer.apple.com/message/169511
// suggests configuring audio in the completion block of the `reportNewIncomingCallWithUUID:update:completion:`
// method instead of in `provider:performAnswerCallAction:` per the Speakerbox example.
// localMedia?.audioController.configureAudioSession()

performRoomConnect(uuid: action.callUUID, roomName: self.roomTextField.text)
/*
* Configure the audio session, but do not start call audio here, since it must be done once
* the audio session has been activated by the system after having its priority elevated.
*/
self.localMedia?.audioController.configureAudioSession(.videoChatSpeaker)

// Hang on to the action, as we will either fulfill it after we succesfully connect to the room, or fail
// it if there is an error connecting.
pendingAction = action
performRoomConnect(uuid: action.callUUID, roomName: self.roomTextField.text) { (success) in
if (success) {
action.fulfill(withDateConnected: Date())
} else {
action.fail()
}
}
}

func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
Expand All @@ -76,7 +87,9 @@ extension ViewController : CXProviderDelegate {

func provider(_ provider: CXProvider, perform action: CXSetMutedCallAction) {
NSLog("provier:performSetMutedCallAction:")

toggleMic(sender: self)

action.fulfill()
}

Expand All @@ -96,7 +109,6 @@ extension ViewController : CXProviderDelegate {
} else {
holdCall(onHold: true)
}

action.fulfill()
}
}
Expand All @@ -107,25 +119,17 @@ extension ViewController {
func performStartCallAction(uuid: UUID, roomName: String?) {
let callHandle = CXHandle(type: .generic, value: roomName ?? "")
let startCallAction = CXStartCallAction(call: uuid, handle: callHandle)

startCallAction.isVideo = true

let transaction = CXTransaction(action: startCallAction)

callKitCallController.request(transaction) { error in
if let error = error {
NSLog("StartCallAction transaction request failed: \(error.localizedDescription)")
return
}

NSLog("StartCallAction transaction request successful")

let callUpdate = CXCallUpdate()
callUpdate.remoteHandle = callHandle
callUpdate.supportsDTMF = false
callUpdate.supportsHolding = true
callUpdate.supportsGrouping = false
callUpdate.supportsUngrouping = false
callUpdate.hasVideo = true

self.callKitProvider.reportCall(with: uuid, updated: callUpdate)
}
}

Expand All @@ -143,13 +147,9 @@ extension ViewController {
callKitProvider.reportNewIncomingCall(with: uuid, update: callUpdate) { error in
if error == nil {
NSLog("Incoming call successfully reported.")

// NOTE: CallKit with VoIP push workaround per https://forums.developer.apple.com/message/169511
self.localMedia?.audioController.configureAudioSession(.videoChatSpeaker)
} else {
NSLog("Failed to report incoming call successfully: \(error?.localizedDescription).")
}

completion?(error as? NSError)
}
}
Expand All @@ -168,7 +168,7 @@ extension ViewController {
}
}

func performRoomConnect(uuid: UUID, roomName: String?) {
func performRoomConnect(uuid: UUID, roomName: String? , completionHandler: @escaping (Bool) -> Swift.Void) {
// Configure access token either from server or manually.
// If the default wasn't changed, try fetching from server.
if (accessToken == "TWILIO_ACCESS_TOKEN") {
Expand Down Expand Up @@ -213,5 +213,7 @@ extension ViewController {
logMessage(messageText: "Attempting to connect to room \(roomName)")

self.showRoomUI(inRoom: true)

self.callKitCompletionHandler = completionHandler
}
}
21 changes: 5 additions & 16 deletions VideoCallKitQuickStart/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ViewController: UIViewController {
// CallKit components
let callKitProvider:CXProvider
let callKitCallController:CXCallController
var pendingAction:CXCallAction?
var callKitCompletionHandler: ((Bool)->Swift.Void?)? = nil

// MARK: UI Element Outlets and handles
@IBOutlet weak var remoteView: UIView!
Expand Down Expand Up @@ -228,35 +228,24 @@ extension ViewController : TVIRoomDelegate {
callKitProvider.reportOutgoingCall(with: uuid, connectedAt: nil)
}
}

// Mark the Start/Answer Call Action as being fullfilled
if let pendingAction = pendingAction {
pendingAction.fulfill()
}

pendingAction = nil

self.callKitCompletionHandler!(true)
}

func room(_ room: TVIRoom, didDisconnectWithError error: Error?) {
logMessage(messageText: "Disconncted from room \(room.name), error = \(error)")

self.cleanupRemoteParticipant()
self.room = nil

self.showRoomUI(inRoom: false)
self.callKitCompletionHandler = nil
}

func room(_ room: TVIRoom, didFailToConnectWithError error: Error) {
logMessage(messageText: "Failed to connect to room with error: \(error.localizedDescription)")

// Mark the Start/Answer Call Action as having failed
if let pendingAction = pendingAction {
pendingAction.fail()
}

pendingAction = nil
self.callKitCompletionHandler!(false)
self.room = nil

self.showRoomUI(inRoom: false)
}

Expand Down

0 comments on commit e75d458

Please sign in to comment.