# Migrating from 3.x to 4.x

This guide provides an introduction to the 3.x Programmable Video iOS SDK and a set of guidelines to migrate an application from 3.x to 4.x.

> \[!NOTE]
>
> For older migrations, see our [archived documentation policy](/docs/video/platform-sdk-support-policy#documentation-retention-policy).

## Programming Model

The programming model has not changed from 3.x to 4.x. To learn more about older migration guides, see our [documentation retention policy](/docs/video/platform-sdk-support-policy#documentation-retention-policy).

## Xcode and iOS Version Support

Twilio Video 4.x is built with Xcode 12. The framework can be consumed with previous versions of Xcode. However, re-compiling Bitcode when exporting for Ad Hoc or Enterprise distribution requires the use of Xcode 12.x. Twilio Video 4.2.0 and newer supports a minimum version of iOS 9.0 at build time, and 11.0 at run time.

## XCFramework Support

Twilio Video 4.x is now delivered as a `.xcframework` and now includes the `.dSYM` and `.bcsymbolmaps` to aid in symbolication of crash reports.

## Swift Package Manager Support

Twilio Video 4.x is now distributed via Swift Package Manager. To consume Twilio Video 4.x using Swift Package Manager, add the `https://github.com/twilio/twilio-video-ios` repository as a `Swift Package`.

## In-App Screen Capture Support

You can now share video of your app's screen to a room using `TVIAppScreenSource`. `TwilioVideo` uses `ReplayKit` internally for in-app screen capture. `TVIAppScreenSource` conforms to `TVIVideoSource` and uses `RPScreenRecorder` to capture video of your app's screen. Here is a brief example:

```swift
if let source = AppScreenSource(), let track = LocalVideoTrack(source: source) {
    room.localParticipant?.publishVideoTrack(track)
    source.startCapture()
}
```

## Discontinuous Transmission (DTX)

Discontinuous transmission (DTX) is enabled by default for the Opus codec. Disabling DTX will result in higher bitrate for silent audio while using the Opus codec. The TVIOpusCodec class now has a new initializer \[TVIOpusCodec initWithDtxEnabled:] and a property dtxEnabled.

## Removal of Carthage Support

Carthage does not currently work with `.xcframeworks` as documented [here](https://github.com/Carthage/Carthage/issues/2890). Once Carthage supports binary `.xcframeworks`, Carthage distribution will be re-added in a future release.

## Removal of Deprecated Items

The deprecated `TVIVideoView` APIs have been removed:

```bash
- VideoView.RenderingType
- [VideoView initWithFrame:delegate:renderingType:renderingType]
```

The deprecated `TVIIceOptions` and `TVIIceOptionsBuilder` APIs have been removed:

```bash
- TVIIceOptions.abortOnIceServersTimeout
- TVIIceOptionsBuilder.abortOnIceServersTimeout
- TVIIceOptions.iceServersTimeout
- TVIIceOptionsBuilder.iceServersTimeout
```

The `TVIRemoteParticipant.connected` property has been replaced with `TVIParticipant.state`.

## CallKit Integration

* This release has improved API for CallKit integration. In order to use CallKit with the SDK, you must set `ConnectOptions.uuid` while connecting to a Room. When `ConnectOptions.uuid` is set, it is your responsibility to enable and disable the audio device. You should enable the audio device in `[CXProviderDelegate provider\:didActivateAudioSession:]`, and disable the audio device in `[CXProviderDelegate provider\:didDeactivateAudioSession:]`.

Passing an uuid to make a Call with CallKit code snippets -

```swift
    let uuid = UUID()

    let connectOptions = ConnectOptions(accessToken: accessToken) { builder in
        builder.uuid = uuid
    }

    let room = TwilioVideoSDK.connect(options: connectOptions, delegate: self)
```

`ProviderDelegate` implementation code snippets -

```swift
    func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
        audioDevice.isEnabled = true
    }

    func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
        audioDevice.isEnabled = false
    }

    func providerDidReset(_ provider: CXProvider) {
        audioDevice.isEnabled = false
    }
```

If you are not using CallKit in your app, you must not set `ConnectOptions.uuid` while connecting to a Room. The Video SDK will enable the audio device for you when the `uuid` is `nil`.
