This guide provides you with an overview of the key objects you'll use in the Programmable Video API to build your video application with the Twilio Programmable Video iOS SDK.

Note: If you haven’t already done so, then take a look at the Twilio Video iOS QuickStart Application [Swift, Objective-C]. Once you've played with the QuickStart, come back to this guide for more detail on how to add video to your own app.

The Twilio Video iOS SDK dynamic framework can be installed using Carthage, CocoaPods or manually, as you prefer. As of the 2.5.2 release, the Twilio Video iOS SDK is also distributed as a static library which can be manually installed.

You can add Programmable Video for iOS by adding the following line to your Cartfile:

github "twilio/twilio-video-ios"

続いて、carthage bootstrap を実行します。 (SDKを更新している場合は carthage update)

On your application targets’ General settings page, in the Linked Frameworks and Libraries section, drag and drop each framework you want to use from the Carthage/Build folder on disk.

On your application targets’ Build Phases settings tab, click the “+” icon and choose New Run Script Phase. Create a Run Script in which you specify your shell (ex: /bin/sh), add the following contents to the script area below the shell:

/usr/local/bin/carthage copy-frameworks

Add the paths to the frameworks you want to use under Input Files, e.g.:

Next, you will need to open your project's Linked Frameworks and Libraries configuration. You should see TwilioVideo.framework there already. Add the following frameworks to that list:

AudioToolbox.framework

VideoToolbox.framework

AVFoundation.framework

CoreTelephony.framework

GLKit.framework

CoreMedia.framework

SystemConfiguration.framework

libc++.tbd

In your Build Settings, you will also need to modify Other Linker Flags to include -ObjC.

Before distributing your app to the  App Store, you will need to strip the simulator binaries from the embedded framework. Navigate to your target's Build Phases screen and create a new Run Script Phase. Ensure that this new run script phase is after the Embed Frameworks phase. Paste the following command in the script text field:

Once you've downloaded and unpacked the static library, drag and drop the lib and headers folders into your project. Ensure that "Copy items if needed" is checked and press Finish. This will add libTwilioVideo.a to the Linked Frameworks and Libraries section.

Next, you will need to open your project's Linked Frameworks and Libraries configuration. You should see libTwilioVideo.a there already. Add the following frameworks to that list:

AudioToolbox.framework

VideoToolbox.framework

AVFoundation.framework

CoreTelephony.framework

GLKit.framework

CoreMedia.framework

SystemConfiguration.framework

libc++.tbd

In your Build Settings, you will also need to modify Other Linker Flags to include -ObjC.

To allow a connection to a Room to be persisted while an application is running in the background, you must select the Audio, AirPlay, and Picture in Picture background mode from the Capabilities project settings page.

The iOS SDK supports iOS 9.0 or higher. It is built for armv7, arm64, x86 and x86_64 architectures with Bitcode slices for armv7 and arm64 devices. Devices based on the A5 SoC (iPhone 4s, iPad 2, iPad Mini 1, iPod Touch 5G) are not supported, and the SDK will not perform well on them.

The TwilioVideo.framework is built with Xcode 9.4. The framework can successfully be consumed with previous versions of Xcode. However, re-compiling Bitcode when exporting for Ad Hoc or Enterprise distribution requires the use of Xcode 9.x.

To execute the code samples below, you can use the Testing Tools page in the Twilio Console to generate an Access Token. An Access Token is a short-lived credential used to authenticate your client-side application to Twilio.

In a production application, your back-end server will need to generate an Access Token for every user in your application. An Access Token is a short-lived credential used to authenticate your client-side application to Twilio. Visit the User Identity and Access Token guide to learn more.

You can also set the room type from the Room Settings page in the Twilio Video Console. Twilio will use the room type set on Room Settings page, when you create a room from the client-side or the REST API.

Recordings can be enabled only on Group Rooms. Set Recordings to Enabled to record participants when they connect to a Group Room. Recordings can also be enabled on Group Rooms through via the Rest API at Room creation time by setting the RecordParticipantsOnConnect property to true.

If you'd like to join a Room you know already exists, you handle that exactly the same way as creating a room: just pass the Room name to the connect method. Once in a Room, you'll receive a room:participantDidConnect: callback for each Participant that successfully joins. Querying the remoteParticipants getter will return any existing Participants who have already joined the Room.

// Create an audio trackvarlocalAudioTrack=TVILocalAudioTrack()// Create a data trackvarlocalDataTrack=TVILocalDataTrack()// Create a Capturer to provide content for the video trackvarlocalVideoTrack:TVILocalVideoTrack?// Create a video track with the capturer.ifletcamera=TVICameraCapturer(source:.frontCamera){localVideoTrack=TVILocalVideoTrack.init(capturer:camera)}

When Participants connect to or disconnect from a Room that you're connected to, you'll be notified via an event listener: Similar to Room Events, Twilio will fire Participant events if the StatusCallback webhook URL is set when the Room is created. These events help your application keep track of the participants who join or leave a Room.

// MARK: TVIRoomDelegate// First, we set a Participant Delegate when a Participant first connects:funcroom(_room:TVIRoom,participantDidConnectparticipant:TVIRemoteParticipant){print("Participant connected: \(participant.identity!)")participant.delegate=self}

// MARK: TVIRemoteParticipantDelegate/* * In the Participant Delegate, we can respond when the Participant adds a Video * Track by rendering it on screen. */funcsubscribed(tovideoTrack:TVIRemoteVideoTrack,publication:TVIRemoteVideoTrackPublication,forparticipant:TVIRemoteParticipant){print("Participant \(participant.identity) added a video track.")self.remoteView=TVIVideoView.init(frame:self.view.bounds,delegate:self)videoTrack.addRenderer(self.remoteView)self.view.addSubview(self.remoteView!)}// MARK: TVIVideoViewDelegate// Lastly, we can subscribe to important events on the VideoViewfuncvideoView(_view:TVIVideoView,videoDimensionsDidChangedimensions:CMVideoDimensions){print("The dimensions of the video track changed to: \(dimensions.width)x\(dimensions.height)")self.view.setNeedsLayout()}

Sometimes you need to make sure you're looking fantastic before entering a Room. We get it. The iOS SDK provides a means to render a local camera preview outside the context of an active Room:

// Use TVICameraCapturer to produce video from the device's front camera.ifletcamera=TVICameraCapturer(source:.frontCamera),letvideoTrack=TVILocalVideoTrack(capturer:camera){// TVIVideoView is a TVIVideoRenderer and can be added to any TVIVideoTrack.letrenderer=TVIVideoView(frame:view.bounds)// Add renderer to the video trackvideoTrack.addRenderer(renderer)self.localVideoTrack=videoTrackself.camera=cameraself.view.addSubview(renderer)}else{print("Couldn't create TVICameraCapturer or TVILocalVideoTrack")}

// To disconnect from a Room, we call:room?.disconnect()// This results in a callback to TVIRoomDelegate#room:didDisconnectWithError// MARK: TVIRoomDelegatefuncroom(_room:TVIRoom,didDisconnectWithErrorerror:Error?){print("Disconnected from room \(room.name)")}

As of the 2.7.0 release, the Video SDK will raise notifications when a Room is reconnecting due to a network disruption. A Room reconnection is triggered due to a signaling or media reconnection event. To capture when a reconnection is triggered or that it has reconnected:

// MARK: TVIRoomDelegate// Error will be either TVIErrorSignalingConnectionDisconnectedError or TVIErrorMediaConnectionErrorfuncroom(_room:TVIRoom,isReconnectingWithErrorerror:Error){print("Reconnecting to room \(room.name), error = \(String(describing:error))")}funcdidReconnect(toroom:TVIRoom){print("Reconnected to room \(room.name)")}

In a Peer-to-Peer Room, each Participant has media connections to all the other Participants in the Room. If a media connection between two Participants is broken, then both Participants will enter the reconnecting state until media connectivity between the peers is re-established.