本文にスキップする
Version: 5.5

1対1音声通話

1対1音声通話を実装するサンプルコードです。

前提条件

開始する前に、次の作業が必要です。

1対1音声通話実装時の考慮事項

受信者側で通話の通知を受けるには、通知用システムを実装するか、APNs(Apple Push Notification service)またはFCM(Firebase Cloud Messaging)といった外部のプッシュ通知システムを連携する必要があります。

また、受信者にどのような情報を伝えるべきかを知っておく必要があります。アプリサーバーの役割でアプリケーションが転送すべきデータであるcc_paramについて確認できます。

makeCall()またはverifyCall()を呼び出した後は、返却されたPlanetKitCallMakeResultまたはPlanetKitCallVerifyResultreasonを確認する必要があります。通話に失敗した場合は、reasonに応じて適切な処理を行う必要があります。

動作する全体のソースコードは、デモアプリのソースコードで確認できます。

共通 - PlanetKitCallDelegate実装

アプリケーションがコールセットアップ(call setup)中にイベントを受けて処理できるようにPlanetKitCallDelegateを実装する必要があります。

extension CallDelegateExample : PlanetKitCallDelegate {
func didWaitConnect(_ call: PlanetKitCall) {

// This is called after making a call on the caller side.
// Write your own code here.

}

func didVerify(_ call: PlanetKitCall, peerStartMessage: PlanetKitCallStartMessage?, peerUseResponderPreparation: Bool) {

// This is called after verifying a call on the callee side.
// Write your own code here.

}

func didConnect(_ call: PlanetKitCall, connected: PlanetKitCallConnectedParam) {

// This is called after the call is connected on both sides.
// Write your own code here.

}

func didDisconnect(_ call: PlanetKitCall, disconnected: PlanetKitDisconnectedParam) {

// This is called after the call is disconnected on both sides.
// Write your own code here.

}

...

//
// Also, you should implement other methods defined in the PlanetKitCallDelegate protocol.
//
...
}

発信側 - 通話の作成

通話を作成するための手順は、次のとおりです。

  1. PlanetKitMakeCallSettingBuilderを通じて設定情報を作成します。
  2. PlanetKitCallDelegateを含めてPlanetKitCallParamを作成します。
  3. PlanetKitManager.shared.makeCall()を呼び出します。
  4. PlanetKitCallMakeResultを確認してください。
class CallerExample
{
var call: PlanetKitCall?
}

...

extension CallerExample
{
func makeCallExample(myId: String, myServiceId: String, peerId: String, peerServiceId: String, accessToken: String, delegate: PlanetKitCallDelegate) {
let myUserId = PlanetKitUserId(id: myId, serviceId: myServiceId)
let peerUserId = PlanetKitUserId(id: peerId, serviceId: peerServiceId)

let settings = try! PlanetKitMakeCallSettingBuilder().build()
let param = PlanetKitCallParam(myUserId: myUserId, peerUserId: peerUserId, delegate: delegate, accessToken: accessToken)

let result = PlanetKitManager.shared.makeCall(param: param, settings: settings)

if result.reason != PlanetKitStartFailReason.none {
NSLog("Failed reason: result. \(result.reason)")
return
}

// The result.call instance is a call instance for calling other APIs from now on.
// You must keep this instance in your own context.
// In this example, the "call" variable holds the instance.
call = result.call
}
}

受信側 - プッシュ通知の受信

通話を受信した側はプッシュ通知システムを通じて新しい電話がかかってきたことに気づきます。このとき、userInfoからcc_paramをパーシングする必要があります。

新しい電話がかかってきたことを知らせるプッシュ通知を受け取った後、ユーザーが通話できるようにそのリクエストを受け取る必要があります。

class AppDelegate: UIResponder, UIApplicationDelegate {

...

var callee: CalleeExample
var callDelegate: PlanetKitCallDelegate

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

let message = userInfo as NSDictionary as! [String: AnyObject]
let param = message["cc_param"] as! String
let ccParam = PlanetKitCCParam(ccParam: param)

// Now we received a push notification.
// We should write code here to respond to the new call.
// For convenience, we assume this is done in verifyCallExample()

let myUserId = "Callee User ID value"
let myServiceId = "Callee Service ID value"

callee.verifyCallExample(myId: myUserId, myServiceId: myServiceId, ccParam: ccParam, delegate: PlanetKitCallDelegate)

}

...

}

受信側 - 通話の受信

PlanetKitManager.shared.verifyCall()を呼び出して通話を受信してみましょう。

以下のコードのverifyCallExample()で通話を受信する方法を見ることができます。この例でmyIdは受信者のユーザーID、myServiceIdは受信者のサービスIDです。

class CalleeExample
{
var verifiedCall: PlanetKitCall?
}

...

extension CalleeExample
{
func verifyCallExample(myId: String, myServiceId: String, ccParam: PlanetKitCCParam, delegate: PlanetKitCallDelegate) {
let settings = try! PlanetKitVerifyCallSettingBuilder().build()

let myUserId = PlanetKitUserId(id: myId, serviceId: myServiceId)

let result = PlanetKitManager.shared.verifyCall(myUserId: myUserId, ccParam: ccParam, delegate: delegate)

if result.reason != PlanetKitStartFailReason.none {
NSLog("Failed reason: result. \(result.reason)")
return
}

// The result.call instance is the verified call instance.
// You have to keep this instance in an application layer to call other APIs provided after call setup.
// This example keeps the verified call instance in the following verifiedCall variable.
verifiedCall = result.call
}
}

受信側 - 通話の応答

一般的に通話を受信した後、通話を受けるかどうかを決める時間が必要です。通話に応答するには、acceptCall()を呼び出します。

Note

verifiedCall変数は検証済みのインスタンスです。

extension CalleeExample
{
func acceptCallExample() {
verifiedCall.acceptCall(startMessage: nil, useResponderPreparation: false)
}
}

アプリケーションでApple CallKitを実装

CallKitは、通話インスタンスを提供するAppleのフレームワークの1つです。PlanetKit SDKは、CallKitに対してユーザーCallKit実装の連携、PlanetKit内部実装の連携、連携しないという3つのオプションをサポートします。

基本的にPlanetKit SDKは、CallKit連携なしで通話を作成したり、受信したりします。独自のCallKit実装を連携するには、PlanetKit SDKで通話を作成または受信する際にPlanetKitCallKitSettingtypeuserに設定する必要があります。

発信側の実装例

  1. PlanetKitCallKitSettingインスタンスを生成し、PlanetKitCallKitSettingtypeuserに設定します。

  2. PlanetKitMakeCallSettingBuilderwithCallKitSettingsKey()にインスタンスを渡し、通話作成設定(makeCallSettings)を作成します。

    // Code for Step 1 and Step 2

    func createMakeCallSettingsWithUserCallKitExample() -> [String: Any] {
    let callKitSetting = PlanetKitCallKitSetting(type: .user, param: nil)

    var settingsBuilder = try! PlanetKitMakeCallSettingBuilder().withCallKitSettingsKey(setting: callKitSetting)

    let makeCallSettings = settingsBuilder.build()
    }
  3. CXProviderDelegateprovider(_:didActivate:)PlanetKitCallnotifyCallKitAudioActivation()を呼び出します。

    // Code for Step 3

    extension YourCallKitHandler : CXProviderDelegate {
    ...

    func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
    // PlanetKitCall instance created from PlanetKitManager.makeCall()
    call.notifyCallKitAudioActivation()
    }

    ...
    }

受信側の実装例

  1. PlanetKitCallKitSettingインスタンスを生成し、PlanetKitCallKitSettingtypeuserに設定します。

  2. PlanetKitVerifyCallSettingBuilderwithCallKitSettingsKey()にインスタンスを渡し、通話受信設定(verifyCallSettings)を作成します。

    // Code for Step 1 and Step 2

    func createVerifyCallSettingsWithUserCallKitExample() -> [String: Any] {
    let callKitSetting = PlanetKitCallKitSetting(type: .user, param: nil)

    var settingsBuilder = try! PlanetKitVerifyCallSettingBuilder().withCallKitSettingsKey(setting: callKitSetting)

    let verifyCallSettings = settingsBuilder.build()
    }
  3. CXProviderDelegateprovider(_:perform:)CXCallActionをもとにPlanetKitCallacceptCall()およびdeclineCall()を呼び出します。

  4. CallKit動作を処理するためのCallKitハンドラーを実装します。

    class YourCallKitHandler {
    static let shared = SampleCallKitHandler()
    private var provider: CXProvider?
    private var callController: CXCallController?
    private var call: PlanetKitCall?
    ...
    // Implement initialization and other features to handle CallKit operations.
    }
  5. CXProviderDelegateprovider(_:didActivate:)PlanetKitCallnotifyCallKitAudioActivation()を呼び出します。

    // Code for Step 3 and Step 4

    extension YourCallKitHandler : CXProviderDelegate {

    ...

    func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
    call.acceptCall(useResponderPreparation: false, startMessage: nil)
    action.fulfill()
    }

    func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
    call.declineCall()
    action.fulfill()
    }

    func provider(_ provider: CXProvider, perform action: CXSetMutedCallAction) {
    call.muteMyAudio(action.isMuted) { success in }
    action.fulfill()
    }

    func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
    // PlanetKitCall instance created from PlanetKitManager.makeCall()
    call.notifyCallKitAudioActivation()
    }

    // Implement other delegate functions to handle other CXCallActions
    ...
    }
  6. CallKitとPlanetKitを同期させるためにCallKitを通じてPlanetKitCallmuteMyAudio()hold()およびunhold()を呼び出すようにUIコードを修正します。

    extension YourCallViewController {
    @IBAction func muteCall(_ sender: UIButton) {
    YourCallKitHandler.shared.muteCall()
    }
    }

    extension YourCallKitHandler {
    func muteCall() {
    let action = CXSetMutedCallAction(call: call.uuid , muted: true)
    callController.requestTransaction(with: action) { error in
    NSLog("\(error)")
    }
    }
    }

詳細は、CallKitドキュメントを参照してください。

関連サンプルコード

関連ドキュメント