Tạo ứng dụng chat voice sử dụng Twilio SDK
Lời giới thiệu
Như đã đề cập ở bài viết trước, hôm nay chúng tôi sẽ hướng dẫn bạn xây dựng 1 ứng dụng iOS chat voice sử dụng Twilio Video SDK.
Tổng quan, Twilio Video nổi tiếng là 1 nền tảng cung cấp rất nhiều dịch vụ để xây dựng các trải nghiệm về video: chat video(voice) thời gian thực, chia sẻ màn hình. Trên thế giới, nó nhận được khá nhiều đánh giá tích cực từ người dùng.
https://www.g2.com/products/twilio/reviews
https://www.trustradius.com/products/twilio-video/reviews
Trong bài viết này, chúng ta sẽ thử sử dụng Video API để xây dụng 1 ứng dụng chat voice.
Tạo 1 dự án trên Twilio
Tạo 1 tài khoản trên Twillo
Mở trang console
Tạo 1 dự án tên “TwilioDemoChat” hay bất kỳ tên nào mà bạn muốn tại link
Sau khi tạo dự án, sẽ hiện ra trang chào mừng
Chọn “Other” và di chuyển đến trang dashboard để hoàn thành bước tạo dự án.
Lưu ACCOUNT SID và AUTH TOKEN vào 1 file để sau này sử dụng.
Tạo API Key
Tạo 1 api key mới và lưu giữ cẩn thận, bởi vì nó chỉ hiển thị đúng 1 LẦN duy nhất.
Tạo Access Tokens
Tại đường dẫn này tạo 2 access token mới, bởi vì chúng ta sẽ test với 2 user cùng kết nối tới cùng 1 room tên là “TwilioDemoChatRoom” and có các định danh sau “TwilioDemoChatRoomUser1” và “TwilioDemoChatRoomUser2”, sau đó bấm vào nút “Generate Access Token” để lấy access token, lưu chúng lại để sử dụng cho iOS app.
CHÚ Ý: Ở môi trường release, bước này sẽ được phía server đảm nhiệm, nó sẽ tạo ra từng access token cho từng user sử dụng ở mỗi room, 1 access token là 1 chứng thực ngắn hạn để xác nhận user tới server Twilio.
Tạo ứng dụng voice chat trên iOS
Tạo 1 dự án mới tên là “TwilioDemoChat”
Cấu hình CocoaPods
Tạo 1 file rỗng đặt tên là PodFile đặt tại thư mục gốc của dự án, sau đó dán đoạn code sau vào :
platform :ios,'11.0' use_frameworks! def install_pods pod 'TwilioVideo' pod 'MBProgressHUD' end target 'TwilioDemoChat' do install_pods end
Mở ứng dụng Terminal chạy dòng lệnh sau ở thư mục gốc dự án để cài đặt TwilioVideo SDK:
pod install
Bởi vì ứng dụng chúng ta cần sử dụng micro để chat voice nên chúng ta cần thêm quyền hạn sử dụng micro vào file info.plist
NSMicrophoneUsageDescription Ứng dụng demo này sử dụng micro để chat thoại
Áp dụng Twilio
Trước tiên chúng ta tạo 1 controller để xử lý việc tham gia room tên là TwilioController.swift
import UIKit import TwilioVideo import MBProgressHUD let TWILIO_TEST_ROOM = "TwilioDemoChatRoom" let TWILIO_ACCESS_TOKEN_1 = "access_token_tạo_ra_từ_bước_Tạo_Access_Token" let TWILIO_ACCESS_TOKEN_2 = "access_token_tạo_ra_từ_bước_Tạo_Access_Token" let kTwilioController = TwilioController.shared public enum RoomStatus{ case Connected case Disconnected case ParticipantConnected case ParticipantDisconnected case Error } public typealias RoomStatusUpdatedHandler = (RoomStatus) -> (Void) class TwilioController: NSObject { static let shared = TwilioController() var room:Room? = nil var connected = false var roomStatusHandler:RoomStatusUpdatedHandler? private var localAudioTrack = LocalAudioTrack() //kết nối tới room được định nghĩa ở hằng số TWILIO_TEST_ROOM func connectToRoom(handler:RoomStatusUpdatedHandler?) { roomStatusHandler = handler //thay đổi access token cho từng device let connectOptions = ConnectOptions(token: TWILIO_ACCESS_TOKEN_2) { (builder) in builder.roomName = TWILIO_TEST_ROOM //cấu hình âm thanh if let audioTrack = self.localAudioTrack { builder.audioTracks = [ audioTrack ] } } room = TwilioVideoSDK.connect(options: connectOptions, delegate: self) } func disconnectFromRoom() { room?.disconnect() } // MARK: - các hàm nội bộ private func toastMessage(message:String){ print("toastMessage \(message)") DispatchQueue.main.asyncAfter(deadline: .now() ) { let hud = MBProgressHUD.showAdded(to: UIApplication.shared.keyWindow!, animated: true) hud.mode = .text hud.label.text = message hud.removeFromSuperViewOnHide = true hud.hide(animated: true, afterDelay: 2) } } } extension TwilioController : RoomDelegate{ //sự kiện khi user đã kết nối tới room func roomDidConnect(room: Room) { connected = true roomStatusHandler?(.Connected) } //sự kiện khi user đã rời khỏi room func roomDidDisconnect(room: Room, error: Error?) { connected = false roomStatusHandler?(.Disconnected) } //sự kiện khi user không thể kết nối room, bởi vì lỗi timeout hay kết nối mạng... func roomDidFailToConnect(room: Room, error: Error) { connected = false roomStatusHandler?(.Error) } //sự kiện khi người khác tham gia room func participantDidConnect(room: Room, participant: RemoteParticipant) { let message = "participant \(participant.identity) connected" toastMessage(message: message) roomStatusHandler?(.ParticipantConnected) } //sự kiện khi người tham gia rời room func participantDidDisconnect(room: Room, participant: RemoteParticipant) { let message = "participant \(participant.identity) disconnected" toastMessage(message: message) roomStatusHandler?(.ParticipantDisconnected) } }
Controller này chủ yếu có 2 hàm chính:
– connectToRoom(): kết nối tới room cụ thể được chỉ định bởi hằng số TWILIO_TEST_ROOM và access token (TWILIO_ACCESS_TOKEN_1 hay TWILIO_ACCESS_TOKEN_2). Nếu bạn chạy trên thiết bị thì hãy set access token khác nhau cho từng thiết bị. Ngoài ra function này còn xử lý các sự kiện sau:
- Connected: sự kiện khi user đã kết nối tới room
- Disconnected: sự kiện khi user đã rời khỏi room
- ParticipantConnected: sự kiện khi người khác tham gia room
- ParticipantDisconnected: sự kiện khi người tham gia rời room
- roomDidFailToConnect: sự kiện khi user không thể kết nối room, bởi vì lỗi timeout hay kết nối mạng…
– disconnectFromRoom(): rời khỏi room
Sau đó chúng ta tạo 1 view controller tên là CallViewController có UI đơn giản nhu sau:
Trong file CallViewController.swift chúng ta dán đoạn code sau vào:
import UIKit import MBProgressHUD class CallViewController: UIViewController { @IBOutlet weak var joinButton: UIButton! @IBOutlet weak var roomTxt: UITextField! //khi trạng thái tham gia room thay đổi, cập nhật tiêu đề tương ứng cho button tham gia private var joined = false{ didSet{ if joined { joinButton.setTitle("End call", for: .normal) }else{ joinButton.setTitle("Join", for: .normal) } } } override func viewDidLoad() { super.viewDidLoad() roomTxt.text = TWILIO_TEST_ROOM } @IBAction func joinRoom(_ sender: Any) { if !joined{ MBProgressHUD.showAdded(to: self.view, animated: true) kTwilioController.connectToRoom { (status) -> (Void) in if status == .Connected { self.joined = true } if status == .Disconnected{ self.joined = false } MBProgressHUD.hide(for: self.view, animated: true) } }else{ kTwilioController.disconnectFromRoom() } } }
Đơn giản chúng ta có 1 textfield để hiển thị tên room kết nối (TwilioDemoChatRoom, và không thể chỉnh sửa được), với 1 button để Join hay End Call ( Tuỳ vào trạng thái tham gia room mà chúng ta cập nhật tiêu đề button cho phù hợp để gọi hàm connectToRoom() hay disconnectFromRoom() ).
Bây giờ bạn hãy chạy dự án trên 2 thiết bị iOS (không hỗ trợ máy ảo) để xem nó hoạt động như thế nào.
Nhớ đổi access token cho từng thiết bị khi bắt đầu chạy dự án.
Tham khảo: