-
Notifications
You must be signed in to change notification settings - Fork 0
App Architecture & Software Stack
In this section I will describe the code layout and thought process when developing this project
The user interface for this application is developed using SwiftUI. So most of the Views in the project are written declaratively.
One issue we ran into in this project was that the RTCVideoRenderer (The render that actually renders the video chat) is only in UIKit views. Our project uses SwftUI. In order to maintain consistency in the project, we wrapped this View in a SwiftUI View.
One view however is a SwiftUI view containing a wrapper of a UIKit view. This is our RTCVideoView (the view that we use to display the video chat). You can see in the image of the RTCVideoView class that the videoView is using UIViewRepresentable. UIViewRepresentable allows us to wrap UIKits and display them in a SwiftUI view. We will use this RTCVideoView to make our SwiftUI view for RTCVideoWrapper.
And you can see the RTCVideoWrapper class we created to hold our RTCVideoRenderer. This is what really uses our Renderer that was only available in SwiftUI.
In order to explain how calling works, we have to explain a little bit about how calling in WebRTC works in general. Suppose Client A and Client B are connected to a server, Client A wants to call Client B (us). How does this happen?
First, Client A will have to get the UUID of Client B from the server.
Next, Client A must generate the unique address for the connectionId. To do this in Swift you can copy this code:
private func createDataChannel() -> String {
let uuid = UUID().uuidString.replacingOccurrences(of: "-", with: "")
return String(uuid.prefix(14))
}Then, using WebRTCClient's offer method, Client A will create an SDP offer, set the local SDP, and construct and send an SDP OFFER message (in JSON format) to send to the server.
The structure of the offer message is as follows:
let message: [String: Any] = [
"dst": id,
"payload": [
"connectionId": self.connectionId,
"sdp": [
"type": "offer",
"sdp": sdp.sdp,
],
"type": "media"
],
"type": "OFFER",
"src": self.ourPeerID
]The variable 'id', the destination, is the UUID of Client B.
Note that the type must of type OFFER
Switching perspectives, Client B will then receive this offer message and read it. If they choose to answer, they will construct and send an 'answer' message, which contains their answer SDP.
Then, Client A will grab the SDP from that message and create an RTCSessionDescription for the answer SDP, and set the remote SDP on the peer connection.