
iOSとFlutterを使ってアプリから電話へ電話をかける
所要時間:3 分
今日は iOSアプリケーションを アプリケーションを構築します。を使ってアプリケーションを構築し Vonage Client SDKを利用します。を使ってモバイルアプリケーションから電話をかける。 Vonage Conversation APIを使う。.アプリケーションには3つの画面(3つのUI状態)があります:

前提条件
このアプリケーションのソースコードは Flutter iOSアプリケーションのソースコードは GitHub.
アプリケーションの構築を始める前に Flutterアプリケーションの iOSデバイス用のアプリケーションを作り始める前に、以下の前提条件を準備する必要がある:
コール・コントロール・オブジェクト(NCCO)
を取り付ける。
Vonage CLI(以前はNexmo CLI)を設定する。
Vonage applicationをインストールします。
Flutter SDKを作成する。
Flutterプロジェクト
Vonageアプリケーション
NCCOの設立
A コール・コントロール・オブジェクト(NCCO)は JSONのフローを制御するために使用する配列である。 Voice API call.
そのためには NCCOは公開され、インターネットからアクセスできる必要があります。そのために、このチュートリアルでは GitHub Gistを使います。新しいGistを追加しよう:
次のサイトへ https://gist.github.com/(Githubにログインする必要があります)
新しいgistを
ncco.jsonをファイル名として以下の
JSONオブジェクトをgistに貼り付ける:
[
{
"action": "talk",
"text": "Please wait while we connect you."
},
{
"action": "connect",
"endpoint": [
{
"type": "phone",
"number": "PHONE_NUMBER"
}
]
}
]置き換える
PHONE_NUMBERを電話番号に置き換えてください。Vonageの電話番号はE.164形式です。,+であり-は無効です。電話番号を入力する際は、必ず国番号を指定してください:14155550100 および UK:447700900001)をクリックしてください。
Create secret gistボタンをクリックしてください。
Rawボタンブラウザに表示されたURLをメモしておく。
Vonage CLIをインストールする
Vonage CLI Vonage CLIを使用すると、コマンドラインを使用して多くの操作を実行できます。アプリケーションの作成、会話の作成、Vonage Numbersの購入などのタスクを実行したい場合は、Vonage CLIをインストールする必要があります。
Vonage CLIには Node.jsが必要なので をインストールする必要があります。.
npmを使ってCLIのベータ版をインストールするには、以下のコマンドを実行する:
npm install nexmo-cli@beta -gを設定します。 Vonage CLIを設定します。 API Keyと API Secret.これらは 設定ページダッシュボードの
ターミナルで以下のコマンドを実行する。 API_KEYと API_SECRETを ダッシュボード:
nexmo setup API_KEY API_SECRET Vonageアプリケーションのセットアップ
プロジェクト・ディレクトリを作成する。ターミナルで以下のコマンドを実行する:
mkdir vonage-tutorialプロジェクト・ディレクトリに移動する:
cd vonage-tutorial以下のコマンドをターミナルにコピー&ペーストしてVonageアプリケーションを作成する。引数の
--voice-answer-url引数のGIST-URLを前のステップの gist URL に置き換えてください。
nexmo app:create "App to Phone Tutorial" --capabilities=voice --keyfile=private.key --voice-event-url=https://example.com/ --voice-answer-url=GIST-URLをメモしておくこと。 Application IDをメモしておいてください。
注:プロジェクト・ディレクトリに
.nexmo-appという名前の隠しファイルがプロジェクト・ディレクトリに作成されます。Vonage Application IDと秘密鍵が含まれます。という名前の秘密鍵ファイルが作成されます。private.keyという名前の秘密鍵ファイルも現在のフォルダに作成されます。
ユーザー作成
各参加者は ユーザーオブジェクトで表され Client SDK.本番アプリケーションでは、通常このユーザー情報をデータベースに保存します。
というユーザーを作成するために以下のコマンドを実行する。 Alice:
nexmo user:create name="Alice" JWTの生成
はユーザー認証に使用される。 JWTはユーザーの認証に使われる。ターミナルで以下のコマンドを実行して JWTを生成する。 Alice.以下のコマンドの APPLICATION_IDをアプリケーションのIDに置き換えてください:
nexmo jwt:generate sub=Alice exp=$(($(date +%s)+86400)) acl='{"paths":{"/*/users/**":{},"/*/conversations/**":{},"/*/sessions/**":{},"/*/devices/**":{},"/*/image/**":{},"/*/media/**":{},"/*/push/**":{},"/*/knocking/**":{},"/*/legs/**":{}}}' application_id=APPLICATION_ID上記のコマンドでは JWTの有効期限を1日後に設定する。
をメモしておいてください。 JWTに対して生成した Alice.
注:本番環境では、アプリケーションは各クライアントからのリクエストに対して
JWTを生成するエンドポイントを公開する必要があります。
Xcodeをインストールする
AppStoreを開き、インストールする Xcode.
フラッターセットアップ
Flutter SDKをインストールする
ダウンロードとインストール Flutter SDK.
このステップは MacOS, Winや Linuxによって異なるが、一般的には Flutter SDKをダウンロードし Flutter SDKファイルを解凍し sdk\binフォルダをシステム PATH変数に追加することである。全プラットフォームの詳しい説明は こちら.
幸いなことに、 FlutterをVerifyできるツールが付属している。 SDKとすべての必要な "コンポーネント "が存在し、正しく設定されているかどうかを確認できるツールがある。次のコマンドを実行する:
flutter doctorFlutter DoctorはVerifyする。 Flutter SDKがインストールされているか、その他のコンポーネントが正しくインストールされ、設定されているかを確認します。
Flutterプロジェクトの作成
ターミナルを使って Flutterプロジェクトを作成します:
flutter create app_to_phone_flutter上記のコマンドは app_to_phone_flutterフォルダが作成されます。 Flutterプロジェクトを含むフォルダを作成します。
Flutterプロジェクトにはiosフォルダが含まれています。iOSプロジェクトが含まれます;androidプロジェクトを含むAndroidプロジェクトを含むwebプロジェクトを含むwebプロジェクト。
ファイルを開き pubspec.yamlファイルを開き permission_handlerを追加する。 sdk: flutter):
dependencies:
flutter:
sdk: flutter
permission_handler: ^6.0.1+1ファイルではインデントが重要です。
yamlファイルではインデントが重要なのでpermission_handlerと同じインデント・レベルであることを確認してください。flutter:項目と同じインデントレベルであることを確認してください。
次のコマンドを実行する(パスはプロジェクトのルート)。 Flutterプロジェクトのルート)を実行し、上記の依存関係をダウンロードする:
flutter pub get上記のコマンドは Podfileを作成します。 iosサブフォルダーにも作成されます。開く ios\Podfile行を開き platform行を開き、プラットフォームのバージョンを 11:
platform :ios, '11.0'同じファイルの最後に pod 'NexmoClient':
target 'Runner' do
use_frameworks!
use_modular_headers!
pod 'NexmoClient'開く app_to_phone_flutter/iosフォルダを開き、ポッドをインストールする:
pod install上記のコマンドは、以下を含むすべての必要な依存関係をダウンロードする。 Flutterパーミッションハンドラー Client SDK.
オープン Runner.xcworkspaceで Xcodeで開き、アプリを実行して、上記のセットアップが正しく行われたことを確認する。
FlutterとiOSの双方向通信
現在 Client SDKは Flutterパッケージとして提供されていないため AndroidネイティブClient SDKと iOSと Flutterの間で通信する必要があります。 メソッドチャネル- を使用します、 FlutterはAndroidのメソッドを呼び出します、 iOSは Flutterメソッドを呼び出します。
Flutterのコードは lib/main.dartファイルに格納され iOSネイティブコードは ios/Runner/AppDelegate.swiftファイルに格納される。
Flutterアプリケーションの初期化
Flutterアプリケーションは、以下のプログラミング言語を使って構築される。 ダート.
ファイルを開き lib/main.dartファイルを開き、すべての内容を以下のコードに置き換える:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: CallWidget(title: 'app-to-phone-flutter'),
);
}
}
class CallWidget extends StatefulWidget {
CallWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_CallWidgetState createState() => _CallWidgetState();
}
class _CallWidgetState extends State<CallWidget> {
SdkState _sdkState = SdkState.LOGGED_OUT;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 64),
_updateView()
],
),
),
);
}
Widget _updateView() {
if (_sdkState == SdkState.LOGGED_OUT) {
return ElevatedButton(
child: Text("LOGIN AS ALICE")
);
}
}
Future<void> _loginUser() async {
// Login user
}
Future<void> _makeCall() async {
// Make call
}
Future<void> _endCall() async {
// End call
}
}
enum SdkState {
LOGGED_OUT,
LOGGED_IN,
WAIT,
ON_CALL,
ERROR
}上記のコードには、アプリケーションの状態を管理するカスタム CallWidgetが含まれており、アプリケーションの状態(ユーザーのログ記録と呼び出しの管理)を管理します。この SdkStateenumはVonageの可能な状態を表します。 Client SDK.このenumは2回定義される。 Dartと iOSSwift を使う場合です。ウィジェットには _updateViewメソッドが含まれています。 SdkState値に基づいてUIを変更するメソッドが含まれています。
からアプリケーションを実行する。 Xcode:

ボタンが表示されるはずです。 Login as Aliceボタンが表示される:

ログイン画面
ボタンが無効になっています。 Login as Aliceボタンは無効になっているので onPressedハンドラを ElevatedButtonを追加します:
Widget _updateView() {
if (_sdkState == SdkState.LOGGED_OUT) {
return ElevatedButton(
onPressed: () { _loginUser(); },
child: Text("LOGIN AS ALICE")
);
}
}の本体を更新する。 _loginUserメソッド本体を更新し、ネイティブコードと通信してユーザーにログインする:
Future<void> _loginUser() async {
String token = "ALICE_TOKEN";
try {
await platformMethodChannel.invokeMethod('loginUser', <String, dynamic>{'token': token});
} on PlatformException catch (e) {
print(e);
}
}を ALICE_TOKENを JWTトークンに置き換えてください。 Vonage CLIから取得したトークンに置き換えてください。 Aliceに置き換えてください。 Flutterは loginUserメソッドを呼び出し、引数として tokenを引数として渡します。メソッドは loginUserメソッドは MainActivityクラスで定義されています。からこのメソッドを呼び出すには Flutterからこのメソッドを呼び出すには MethodChannel.フィールドを定義しなければなりません。 platformMethodChannelフィールドを定義しなければならない。 _CallWidgetStateフィールドを追加します:
追加 platformMethodChannelフィールドを _CallWidgetStateクラスの先頭にフィールドを追加する:
class _CallWidgetState extends State<CallWidget> {
SdkState _sdkState = SdkState.LOGGED_OUT;
static const platformMethodChannel = const MethodChannel('com.vonage');この com.vonage文字列は一意なチャンネル ID を表し、ネイティブの iOSコード (AppDelegateクラス)にも参照される。ここで、ネイティブ側でこのメソッド呼び出しを処理する必要があります。 iOS側でこのメソッド呼び出しを処理する必要があります。
オープン ios/Runner/AppDelegateクラスと vonageChannelプロパティへの参照を保持する。 FlutterMethodChannel:
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
var vonageChannel: FlutterMethodChannel?
...から発信されるメソッドコールをリッスンする Flutterを追加します。 addFlutterChannelListenerメソッド AppDelegateクラス(上記の applicationメソッドと同じレベル):
func addFlutterChannelListener() {
let controller = window?.rootViewController as! FlutterViewController
vonageChannel = FlutterMethodChannel(name: "com.vonage",
binaryMessenger: controller.binaryMessenger)
vonageChannel?.setMethodCallHandler({ [weak self]
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
guard let self = self else { return }
switch(call.method) {
case "loginUser":
if let arguments = call.arguments as? [String: String],
let token = arguments["token"] {
self.loginUser(token: token)
}
result("")
default:
result(FlutterMethodNotImplemented)
}
})
}上記のメソッドは Flutterメソッド呼び出しを AppDelegateクラスで定義されているメソッドに loginUser今のところは)。
そして loginUser同じクラス内のメソッドも欠落している:
func loginUser(token: String) {
}ここで addFlutterChannelListenerメソッドを追加します。 applicationメソッドを追加します:
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
addFlutterChannelListener()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}コードは所定の位置にある。 Login As Aliceボタンを押すと、Flutterアプリは _loginUserメソッドを呼び出します。プラットフォームチャンネルを通して Flutterプラットフォームチャネルを通して loginUserクラスで定義された AppDelegateクラスで定義されたメソッドを呼び出します。
アプリケーションを Xcodeからアプリケーションを実行し、コンパイルされていることを確認する。
ユーザーをログインさせる前に、初期化する必要があります。 Vonage SDK Client.
クライアントの初期化
開く AppDelegateクラスを開き NexmoClientインポートをファイルの先頭に追加する:
import NexmoClient同じファイルに clientプロパティを追加する。 Vonage Client.
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
var vonageChannel: FlutterMethodChannel?
let client = NXMClient.shared
...ここで initClientメソッドを追加する:
func initClient() {
client.setDelegate(self)
}既存の initClientメソッドを呼び出すには applicationメソッドを呼び出すには、以下の例のように initClient()行を追加する必要がある:
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
initClient()
addFlutterChannelListener()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}会話を許可する前に、ユーザーが正しくログインしていることを知る必要がある。そのために AppDelegateファイルに Vonage Client SDKデリゲートを追加します:
extension AppDelegate: NXMClientDelegate {
func client(_ client: NXMClient, didChange status: NXMConnectionStatus, reason: NXMConnectionStatusReason) {
switch status {
case .connected:
notifyFlutter(state: .loggedIn)
case .disconnected:
notifyFlutter(state: .loggedOut)
case .connecting:
notifyFlutter(state: .wait)
@unknown default:
notifyFlutter(state: .error)
}
}
}最後に notifyFlutterメソッドを同じクラスに追加する必要がある:
func client(_ client: NXMClient, didReceiveError error: Error) {
notifyFlutter(state: .error)
}
} ログイン
メソッド本体を修正する loginUserメソッド本体を修正して loginを呼び出すように修正する:
func loginUser(token: String) {
self.client.login(withAuthToken: token)
}この方法では、ユーザー(Alice)にログインできるようになります。 Client SDKを使用して会話にアクセスします。
Client SDKの状態変更をFlutterに通知する
通知 Flutterを通知するために Client SDKの状態を表す enumを追加する必要がある。 Client SDK.に相当する SdkState列挙型を main.dartファイルに追加した。次の SdkStateenumを追加する。 MainActivity.ktファイルの一番下に
enum SdkState: String {
case loggedOut = "LOGGED_OUT"
case loggedIn = "LOGGED_IN"
case wait = "WAIT"
case onCall = "ON_CALL"
case error = "ERROR"
}これらの状態を Flutter(上記のデリゲートから)これらの状態を送るには notifyFlutterメソッドを AppDelegateメソッドを追加する必要がある:
func notifyFlutter(state: SdkState) {
vonageChannel?.invokeMethod("updateState", arguments: state.rawValue)
}状態を列挙型に保存しているが、文字列として送信していることに注目してほしい。
FlutterによるSDK状態更新の取得
状態の更新を Flutterの状態更新を取得するには、メソッド・チャネルの更新をリッスンする必要がある。ファイルを開き main.dartファイルを開いて _CallWidgetStateコンストラクタにカスタムハンドラを追加する:
_CallWidgetState() {
platformMethodChannel.setMethodCallHandler(methodCallHandler);
}同じクラス (_CallWidgetState) の中にハンドラー・メソッドを追加する:
Future<dynamic> methodCallHandler(MethodCall methodCall) async {
switch (methodCall.method) {
case 'updateState':
{
setState(() {
var arguments = 'SdkState.${methodCall.arguments}';
_sdkState = SdkState.values.firstWhere((v) {return v.toString() == arguments;}
);
});
}
break;
default:
throw MissingPluginException('notImplemented');
}
}これらのメソッドはAndroidから「シグナル」を受け取り、それをenumに変換する。ここで _updateViewメソッドの内容を更新して SdkState.WAITそして SdkState.LOGGED_INの状態に更新する:
Widget _updateView() {
if (_sdkState == SdkState.LOGGED_OUT) {
return ElevatedButton(
onPressed: () { _loginUser(); },
child: Text("LOGIN AS ALICE")
);
} else if (_sdkState == SdkState.WAIT) {
return Center(
child: CircularProgressIndicator(),
);
} else if (_sdkState == SdkState.LOGGED_IN) {
return ElevatedButton(
onPressed: () { _makeCall(); },
child: Text("MAKE PHONE CALL")
);
}
}期間中 SdkState.WAITプログレスバーが表示されます。ログインに成功すると MAKE PHONE CALLボタンが表示されます。
アプリを起動し LOGIN AS ALICE.をクリックする。 MAKE PHONE CALLボタンが表示されるはずです。 Flutterアプリの別の状態である SdkStateenum`)に基づいたアプリの別の状態です。この例を下の画像に示す:

電話をかける
次に、電話をかける機能を追加する必要がある。ファイルを開き main.dartファイルを開き _makeCallメソッドのボディを更新します:
Future<void> _makeCall() async {
try {
await platformMethodChannel
.invokeMethod('makeCall');
} on PlatformException catch (e) {
print(e);
}
}上記のメソッドは iOSと通信するので AppDelegateクラスのコードも更新しなければならない。追加 makeCall節を switch文の中に addFlutterChannelListenerメソッドに節を追加する:
func addFlutterChannelListener() {
let controller = window?.rootViewController as! FlutterViewController
vonageChannel = FlutterMethodChannel(name: "com.vonage",
binaryMessenger: controller.binaryMessenger)
vonageChannel?.setMethodCallHandler({ [weak self]
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
guard let self = self else { return }
switch(call.method) {
case "loginUser":
if let arguments = call.arguments as? [String: String],
let token = arguments["token"] {
self.loginUser(token: token)
}
result("")
case "makeCall":
self.makeCall()
result("")
default:
result(FlutterMethodNotImplemented)
}
})
}次に同じファイルに onGoingCallプロパティを追加する:
var onGoingCall: NXMCall?注:現在
Client SDKは進行中の呼び出し参照を保存しない。AppDelegateクラスに格納しなければならない。後で通話を終了するときに使用します。
同じクラスに makeCallメソッドを追加します:
func makeCall() {
client.call("IGNORED_NUMBER", callHandler: .server) { [weak self] (error, call) in
guard let self = self else { return }
if error != nil {
self.notifyFlutter(state: .error)
return
}
self.onGoingCall = call
self.notifyFlutter(state: .onCall)
}
}上記のメソッドは Flutterアプリの状態を SdkState.WAITに設定し Client SDKレスポンス(エラーまたは成功)を待つ。ここで、両方の状態 (SdkState.ON_CALLと SdkState.ERROR) のサポートを main.dartファイルに追加する必要がある。以下のように _updateViewメソッドのボディを以下のように更新する:
Widget _updateView() {
if (_sdkState == SdkState.LOGGED_OUT) {
return ElevatedButton(
onPressed: () { _loginUser(); },
child: Text("LOGIN AS ALICE")
);
} else if (_sdkState == SdkState.WAIT) {
return Center(
child: CircularProgressIndicator(),
);
} else if (_sdkState == SdkState.LOGGED_IN) {
return ElevatedButton(
onPressed: () { _makeCall(); },
child: Text("MAKE PHONE CALL")
);
} else if (_sdkState == SdkState.ON_CALL) {
return ElevatedButton(
onPressed: () { _endCall(); },
child: Text("END CALL")
);
} else {
return Center(
child: Text("ERROR")
);
}
}状態が変わるたびに、UIが変更される。通話を行う前に、アプリケーションはマイクを使用するための特定のパーミッションが必要です。次のステップでは、これらの許可を要求する機能をプロジェクトに追加します。
リクエスト許可
アプリケーションはマイクにアクセスできる必要があるので、マイクへのアクセスをリクエストしなければならない(Permission.microphoneのために Flutter).
ファイルを開く ios/Runner/info.plistファイルを開き Privacy - Microphone Usage Descriptionキーに Make a call値を追加する:

すでに パッケージパッケージを Flutterプロジェクトに追加しました。次に main.dartファイルの先頭に permission_handlerパッケージをインポートする必要があります:
import 'package:permission_handler/permission_handler.dart';特定のパーミッションのリクエストをトリガーするには requestPermissions()メソッドを _CallWidgetStateクラス内のメソッドを main.dartファイルに追加する必要がある。そこで、この新しいメソッドをクラス内に追加します:
Future<void> requestPermissions() async {
await [ Permission.microphone ].request();
}上記のメソッドは permission_handler.
同じクラスで、メソッド・チャネル経由でメソッドを呼び出す前に、パーミッションを要求するように _makeCallクラスの本体を修正して、メソッド・チャネル経由でメソッドを呼び出す前にパーミッションを要求するようにします:
Future<void> _makeCall() async {
try {
await requestPermissions();
...
}アプリを起動し MAKE PHONE CALLをクリックして通話を開始します。許可ダイアログが表示され、許可を与えると通話が開始されます。
備考:電話番号の定義は、先ほど
NCCO
アプリケーションの状態は SdkState.ON_CALLに更新され、UIが更新されます:

通話終了
呼び出しを終了するには、ネイティブ・アプリケーションで iOSメソッドをトリガーする必要がある。 platformMethodChannel.インサイド main.dartファイルの内部で _endCallメソッドのボディを更新する:
Future<void> _endCall() async {
try {
await platformMethodChannel.invokeMethod('endCall');
} on PlatformException catch (e) {}
}上記のメソッドは iOSと通信するので AppDelegateクラスのコードも更新しなければならない。そのため、クラス内のコードも更新しなければならない。 endCall節を switch文に節を追加する。 addFlutterChannelListenerメソッド内に追加する:
func addFlutterChannelListener() {
let controller = window?.rootViewController as! FlutterViewController
vonageChannel = FlutterMethodChannel(name: "com.vonage",
binaryMessenger: controller.binaryMessenger)
vonageChannel?.setMethodCallHandler({ [weak self]
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
guard let self = self else { return }
switch(call.method) {
case "loginUser":
if let arguments = call.arguments as? [String: String],
let token = arguments["token"] {
self.loginUser(token: token)
}
result("")
case "makeCall":
self.makeCall()
result("")
case "endCall":
self.endCall()
result("")
default:
result(FlutterMethodNotImplemented)
}
})
}
同じクラスに endCallメソッドを追加します:
func endCall() {
onGoingCall?.hangup()
onGoingCall = nil
notifyFlutter(state: .loggedIn)
}上記のメソッドは Flutterアプリの状態を SdkState.WAITに設定し Client SDKからのレスポンスを待ちます。どちらのUIステートも Flutterアプリケーション (_updateViewメソッド)。
のボタンを押して通話を終了するようにしました。 END CALLボタンを押すことで FlutterアプリケーションのUIでしかし、通話はアプリの外でも終了できます。 Flutter例えば、通話は拒否されるか、応答され、後で着信側(実際の電話)で終了します。
これらのケースをサポートするには、コールインスタンスに NexmoCallEventListenerリスナーをコールインスタンスに追加し、コール固有のイベントをリッスンする必要がある。
ファイルに AppDelegares.swiftファイルに NXMCallDelegate:
extension AppDelegate: NXMCallDelegate {
func call(_ call: NXMCall, didUpdate callMember: NXMCallMember, with status: NXMCallMemberStatus) {
if (status == .completed || status == .cancelled) {
onGoingCall = nil
notifyFlutter(state: .loggedIn)
}
}
func call(_ call: NXMCall, didUpdate callMember: NXMCallMember, isMuted muted: Bool) {
}
func call(_ call: NXMCall, didReceive error: Error) {
notifyFlutter(state: .error)
}
}上記のリスナーを登録するには onSuccessコールバック makeCallメソッドを修正します:
func makeCall() {
client.call("IGNORED_NUMBER", callHandler: .server) { [weak self] (error, call) in
guard let self = self else { return }
if error != nil {
self.notifyFlutter(state: .error)
return
}
self.onGoingCall = call
self.onGoingCall?.setDelegate(self)
self.notifyFlutter(state: .onCall)
}
}アプリを起動し、モバイルアプリから物理的な電話番号に電話をかける。
概要
我々はアプリケーションの構築に成功した。そうすることで、モバイル・アプリケーションからVonageを使って電話をかける方法を学びました。 Client SDK.プロジェクト全体については GitHub.このプロジェクトにはさらに、Androidネイティブ・コード (androidフォルダ)が含まれており、Android上でもこのアプリを実行することができます。
その他の機能については、以下を参照してください。 他のチュートリアルおよび Vonage 開発者センター.