1対1音声通話
1対1音声通話を実装するサンプルコードです。
前提条件
開始する前に、次の作業が必要です。
- PlanetKitを初期化してください。
- 適切なアクセストークンを取得してください。
- 1対1通話フローにて、APIを使用するための全般的なプロセスを確認してください。
1対1音声通話実装時の考慮事項
受信者側で通話の通知を受けるには、通知用システムを実装するか、APNs(Apple Push Notification service)といった外部プッシュ通知システムを連携する必要があります。
また、受信者にどのような情報を渡すべきかを知っておく必要があります。アプリサーバーの役割にて、アプリケーションが渡すべきデータであるcc_param
について確認できます。
makeCall()
またはverifyCall()
を呼び出した後は、返却されたPlanetKitCallMakeResult
またはPlanetKitCallVerifyResult
でreason
を確認する必要があります。
reason
がPlanetKitStartFailReason.none
の場合、成功を意味します。- それ以外は失敗を意味し、
reason
に応じて適切に処理する必要があります。
イベントデリゲートの実装
通話で使用されるイベントデリゲート(delegate)を実装します。
PlanetKitCallDelegate
は、通話セットアップに関連するイベントを処理するのに使用されます。PlanetKitMyMediaStatusDelegate
は、ローカルユーザーのメディアステータス変更イベントを処理するのに使用されます。マイクがミュートもしくはミュート解除された場合、またはオーディオの説明がアップデートされた場合など、イベントに基づいてローカルユーザーのUIをアップデートできます。
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.
}
func didFinishPreparation(_ call: PlanetKitCall) {
// This is called after making a call on the caller side.
// Write your own code here.
}
...
//
// Also, you should implement other methods defined in the PlanetKitCallDelegate protocol.
//
...
}
extension MyMediaStatusDelegateExample: PlanetKitMyMediaStatusDelegate {
func didMuteMic(_ myMediaStatus: PlanetKitMyMediaStatus) {
// This is called when the local user's audio is muted.
// Write your own code here.
}
func didUnmuteMic(_ myMediaStatus: PlanetKitMyMediaStatus) {
// This is called when the local user's audio is unmuted.
// Write your own code here.
}
func didUpdateAudioDescription(_ myMediaStatus: PlanetKitMyMediaStatus, description: PlanetKitMyAudioDescription) {
// This is called when the local user's audio description is updated.
// Write your own code here.
}
}
通話の作成(発信側)
通話を作成するための手順は、次のとおりです。
PlanetKitMakeCallSettingBuilder
を通じて設定情報を作成します。PlanetKitCallDelegate
を含めてPlanetKitCallParam
を作成します。PlanetKitManager.shared.makeCall()
を呼び出します。PlanetKitCallMakeResult
を確認してください。
class CallerExample
{
var call: PlanetKitCall?
var myMediaStatusDelegate: MyMediaStatusDelegateExample
}
...
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 = PlanetKitMakeCallSettingBuilder().build()
let param = PlanetKitCallParam(myUserId: myUserId, peerUserId: peerUserId, delegate: delegate, accessToken: accessToken)
let result = PlanetKitManager.shared.makeCall(param: param, settings: settings)
guard result.reason == .none else {
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
をパーシングする必要があります。
新しい電話がかかってきたことを知らせるプッシュ通知を受け取った後、ユーザーが通話できるようにそのリクエストを受け取る必要があります。
extension YourPushHandler : PKPushRegistryDelegate {
...
var callee: CalleeExample
var callDelegate: PlanetKitCallDelegate
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
// Update the push token for the application's push server.
}
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
let message = payload.dictionaryPayload 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?
var myMediaStatusDelegate: MyMediaStatusDelegateExample
}
...
extension CalleeExample
{
func verifyCallExample(myId: String, myServiceId: String, ccParam: PlanetKitCCParam, delegate: PlanetKitCallDelegate) {
let settings = PlanetKitVerifyCallSettingBuilder().build()
let myUserId = PlanetKitUserId(id: myId, serviceId: myServiceId)
let result = PlanetKitManager.shared.verifyCall(myUserId: myUserId, ccParam: ccParam, delegate: delegate)
guard result.reason == .none else {
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()
を呼び出します。
verifiedCall
変数は、verifyCall()
で検証済みのPlanetKitCall
インスタンスです。
extension CalleeExample
{
func acceptCallExample() {
verifiedCall.acceptCall(startMessage: nil, useResponderPreparation: false)
}
}
ローカルユーザーに対するメディアステータスのイベントデリゲート設定
通話が接続されると、ローカルユーザーに対するメディアステータスのイベントデリゲートを設定します。
// Caller side
extension CallerExample
{
func addMyMediaStatusHandlerExample() {
call.myMediaStatus.addHandler(myMediaStatusDelegate) {
// completion callback
}
}
}
// Callee side
extension CalleeExample
{
func addMyMediaStatusHandlerExample() {
verifiedCall.myMediaStatus.addHandler(myMediaStatusDelegate) {
// completion callback
}
}
}
通話の切断
通話を切断するには、endCall()
を呼び出します。
// Caller side
extension CallerExample
{
func endCallExample() {
call.endCall()
}
}
// Callee side
extension CalleeExample
{
func endCallExample() {
verifiedCall.endCall()
}
}