Close Menu
  • Home
  • AI
  • Big Data
  • Cloud Computing
  • iOS Development
  • IoT
  • IT/ Cybersecurity
  • Tech
    • Nanotechnology
    • Green Technology
    • Apple
    • Software Development
    • Software Engineering

Subscribe to Updates

Get the latest technology news from Bigteetechhub about IT, Cybersecurity and Big Data.

    What's Hot

    Non-Abelian anyons: anything but easy

    January 25, 2026

    Announcing Amazon EC2 G7e instances accelerated by NVIDIA RTX PRO 6000 Blackwell Server Edition GPUs

    January 25, 2026

    Tech CEOs boast and bicker about AI at Davos

    January 25, 2026
    Facebook X (Twitter) Instagram
    Facebook X (Twitter) Instagram
    Big Tee Tech Hub
    • Home
    • AI
    • Big Data
    • Cloud Computing
    • iOS Development
    • IoT
    • IT/ Cybersecurity
    • Tech
      • Nanotechnology
      • Green Technology
      • Apple
      • Software Development
      • Software Engineering
    Big Tee Tech Hub
    Home»iOS Development»ios – Sometimes LiveKit SwiftUI SDK not showing partner’s video
    iOS Development

    ios – Sometimes LiveKit SwiftUI SDK not showing partner’s video

    big tee tech hubBy big tee tech hubJanuary 14, 20260112 Mins Read
    Share Facebook Twitter Pinterest Copy Link LinkedIn Tumblr Email Telegram WhatsApp
    Follow Us
    Google News Flipboard
    ios – Sometimes LiveKit SwiftUI SDK not showing partner’s video
    Share
    Facebook Twitter LinkedIn Pinterest Email Copy Link


    I’m developing an app for visionOS and testing it on AVP (visionOS 26), on iOS 17 and 26 devices, and in simulators (visionOS 2.5). The idea of the app is random video calls.

    For video calls I use LiveKit SDK. At the moment, SDK the version is 2.11.0.

    Maybe this will help clarify where the problem is:

    A user presses the “Start” button, which calls matchingViewModel.startMatching(). After that, matchingViewModel.connectionState changes to .searching. Another user presses “Start” and the same thing happens.

    Then the API returns information for both users (myInfo, partners, roomId, myLiveKitToken). When a user receives the room information, matchingViewModel.connectionState changes to .connecting.

    At this point, the connection to LiveKit should happen.

    In the MatchingWrapperView file, the handleChangeRoomIdOrPartners method checks whether it should connect to LiveKit (when partner information and a room ID are available) or disconnect from the room (when the partner ends the call).
    The connectRoom method handles connecting to the LiveKit room, enables the camera, and runs emitHasConnectedToLiveKit() (matchingViewModel.connectionState changes to .connected, and information is sent to the other partner that the user has joined LiveKit).

    When testing visionOS device + visionOS device or iPhone or visionOS simulator, most of the time the video from the iPhone is not shown on the visionOS device. Less often, the video from the visionOS device is not shown on the iPhone or in the simulator.

    When testing iPhone + iPhone + visionOS simulator, everything usually works fine. Occasionally the video doesn’t appear, but this happens much less often.

    Here is all the code for the core functionality. If you need any additional code, please let me know.

    RoomModel.swift

    import Combine
    import SwiftUI
    
    final class RoomModel: Notifiable, ObservableObject {
        @Injected var services: Services
    
        private var cancellables: Set = Set()
    
        var globalManager: RoomGlobalManager?
        //    var invitesManager: RoomInvitesManager?
        //    var eventsManager: RoomEventsManager?
    
        @Published private(set) var socketConnected: Bool = false
        @Published private(set) var shouldCall: Bool = false
    
        @Published private(set) var roomId: String = ""
        @Published private(set) var myInfo: UserProfileModel?
        @Published private(set) var partners: [UserProfileModel] = []
        @Published private(set) var joinedVideoPartners: [String] = []
        @Published private(set) var myLiveKitToken: String = ""
    
        @Published private(set) var timerValue: Int = -1
        @Published private(set) var hasExtendedTimer: Bool = false
        @Published private(set) var currentMaxTimerValue: Int = AppSettings
            .callTimerValue
    
        @Published private(set) var sentConnectUserRequests: [String] = []
        @Published private var partnersSentConnectUserRequest: [String] = []
        @Published private var friendsUsers: [String] = []
    
        @Published private var usersOnline: [UserOnlineStatusModel] = []
    
        private let socketService = SocketIOService.shared
        private let userId: String
        private let token: String
    
        init(userId: String, token: String) {
            self.userId = userId
            self.token = token
    
            setupManagers()
            socketService.initSocket(userId: userId, token: token)
        }
    
        private func setupManagers() {
            self.globalManager = RoomGlobalManager(
                roomModel: self,
                userId: userId,
                token: token
            )
            //        self.invitesManager = RoomInvitesManager(roomModel: self)
            //        self.eventsManager = RoomEventsManager(roomModel: self)
    
            self.bindService()
        }
    
        var notificationModel: OrnamentNotificationModel?
    
        func setNotificationModel(_ model: OrnamentNotificationModel) {
            self.notificationModel = model
        }
    
        func destroySocket() {
            socketService.disconnectAndDestroy()
        }
    
        func reset() {
            roomId = ""
            myInfo = nil
            partners = []
            joinedVideoPartners = []
            myLiveKitToken = ""
            timerValue = -1
            hasExtendedTimer = false
            currentMaxTimerValue = AppSettings.callTimerValue
        }
    
        private(set) var settingsViewModel: SettingsViewModel?
    
        func bindSettingsViewModel(_ settingsViewModel: SettingsViewModel) {
            self.settingsViewModel = settingsViewModel
        }
    }
    
    // MARK: Variables
    extension RoomModel {
        var myId: String {
            services.storageService.userProfile?.id ?? ""
        }
    }
    
    extension RoomModel {
        // MARK: Matching
    
        func changeShouldCall(_ shouldCall: Bool) {
            self.shouldCall = shouldCall
            socketService.changeShouldCall(shouldCall: shouldCall)
    
            UIApplication.shared.isIdleTimerDisabled = shouldCall
        }
    
        func endCall() {
            self.changeShouldCall(false)
            socketService.sendEnd()
            self.reset()
        }
    
        func joinedVideo() {
            socketService
                .joinedVideo(
                    roomId: self.roomId,
                    meetTime: self.currentMaxTimerValue
                )
        }
    
        // MARK: Listeners
    
        private func bindService() {
            socketService.onSocketConnected = { [weak self] in
                self?.socketConnected = true
    
                self?.changeUserOnline(
                    isOnline: true,
                    isBusy: false,
                    completion: self?.getUsersOnline
                )
            }
    
            socketService.onSocketDisconnected = { [weak self] in
                self?.socketConnected = false
                self?.shouldCall = false
            }
    
            socketService.onShowNotification = { [weak self] payload in
                guard let self = self else { return }
    
                let notificationInfo = RoomModel.decodeNotificationInfo(
                    from: payload
                )
    
                guard let notificationInfo = notificationInfo else { return }
    
                self.notificationModel?.showNotification(
                    OrnamentNotification(
                        title: notificationInfo.text,
                        message: notificationInfo.description,
                        type: notificationInfo.type,
                        customData: [
                            "roomId": self.roomId,
                            "hideOnEndCall": notificationInfo.hideOnEndCall
                                ?? false,
                        ],
                        customDuration: notificationInfo.customDuration
                    )
                )
            }
    
            socketService.onError = { [weak self] text, description in
                self?.notificationModel?.showNotification(
                    OrnamentNotification(
                        title: text,
                        message: description,
                        type: .error
                    )
                )
    
                SentryService
                    .sendMessage(
                        "Received error. Title: \(text) Description: \(description ?? "")"
                    )
            }
    
            // MARK: Matching listeners
    
            socketService.onGetPartnerInfo = { [weak self] payload in
                guard let self = self, self.shouldCall else { return }
    
                let roomInfo = RoomModel.decodeRoomInfo(from: payload)
                guard let roomInfo = roomInfo else { return }
    
                var shouldUpdate: Bool
    
                if self.partners.isEmpty {
                    shouldUpdate = true
                } else {
                    let currentIDs = Set(self.partners.map { $0.id })
                    let newIDs = Set(roomInfo.partners.map { $0.id })
                    shouldUpdate = currentIDs != newIDs
                }
    
                guard shouldUpdate else { return }
    
                self.roomId = roomInfo.roomId
                self.myInfo = roomInfo.myInfo
                self.partners = roomInfo.partners
                self.myLiveKitToken = roomInfo.myLiveKitToken
    
                if let friendIds = roomInfo.myInfo.friendIds, !friendIds.isEmpty {
                    for friendId in friendIds {
                        if !self.friendsUsers.contains(friendId) {
                            self.friendsUsers.append(friendId)
                        }
                    }
                }
    
                services.storageService.updateUserProfile(
                    \.matchesCount,
                    value: myInfo?.matchesCount
                )
            }
    
            socketService.onPartnerLeft = { [weak self] partnerId in
                guard let self = self, self.shouldCall else { return }
    
                self.partners.removeAll {
                    $0.id == partnerId
                }
    
                if self.partners.isEmpty {
                    self.reset()
                }
            }
    
            socketService.onPartnerJoinedVideo = { [weak self] userId in
                guard let self = self, !userId.isEmpty else { return }
    
                self.joinedVideoPartners.append(userId)
            }
    
            // MARK: Timer listeners
    
            socketService.onTimerUpdate = { [weak self] timerValue in
                self?.timerValue = timerValue
            }
    
            socketService.onTimerExtended = { time in
                self.hasExtendedTimer = true
            }
    
            socketService.onTimerEnded = { [weak self] in
                guard let self = self else { return }
    
                self.reset()
            }
    
            // MARK: Users Online listenrs
    
            socketService.onUserOnlineChanged = { [weak self] payload in
                guard let self = self,
                    let userOnlineInfo = RoomModel.decodeUserOnlineInfo(
                        from: payload
                    )
                else {
                    return
                }
    
                self.updateUserStatus(userOnlineInfo)
            }
    
            // MARK: Connect Book listeners
    
            socketService.onConnectedUser = {
                [weak self] userId, cancel, isFriends in
                guard let self = self, !userId.isEmpty else { return }
    
                if cancel {
                    self.partnersSentConnectUserRequest
                        .removeAll(where: { $0 == userId })
                } else {
                    self.partnersSentConnectUserRequest.append(userId)
    
                    if self.sentConnectUserRequests.contains(userId) {
                        let partner = self.partners
                            .first(where: { $0.id == userId })
    
                        if settingsViewModel?.audioSettings?.allSounds == true {
                            services.soundService.playSound(
                                named: "Friend-Accepted",
                                duration: 3
                            )
                        }
    
                        self.notificationModel?.showNotification(
                            OrnamentNotification(
                                title: "Partner has accepted your connection",
                                type: .success,
                                contentView: {
                                    AnyView(
                                        AcceptedConnectionNotificationContentView(
                                            user: partner ?? nil
                                        )
                                    )
                                }
                            )
                        )
    
                        NotificationCenter.default.post(
                            name: .didAddFriend,
                            object: nil,
                            userInfo: nil
                        )
                    }
                }
            }
    
            socketService.onRemovedUser = { userId in
                guard !userId.isEmpty else { return }
    
                NotificationCenter.default.post(
                    name: .didRemoveUser,
                    object: nil,
                    userInfo: ["userId": userId]
                )
    
                self.removeFriendLocal(userId: userId)
                //            self.removeInvitation(fromUserId: userId)
            }
        }
    }
    
    

    RoomGlobalManager.swift

    import Combine
    import SwiftUI
    
    final class RoomGlobalManager: ObservableObject {
        private weak var roomModel: RoomModel?
        let socketService = SocketIOService.shared
        private let userId: String
        private let token: String
    
        init(roomModel: RoomModel, userId: String, token: String) {
            self.roomModel = roomModel
            self.userId = userId
            self.token = token
        }
    
        // MARK: - Matching Methods
    
        func startMatch() {
            guard !(roomModel?.shouldCall ?? true) else { return }
    
            roomModel?.changeShouldCall(true)
            socketService.connect(userId: userId, token: token)
        }
    
        func restartMatch() {
            socketService.connect(userId: userId, token: token)
        }
    
        func skip(completion: SocketAckCompletion? = nil) {
            socketService.sendSkipCall(completion: completion)
            roomModel?.reset()
        }
    }
    

    MatchingViewModel.swift

    import Combine
    @preconcurrency import LiveKit
    import LiveKitComponents
    import SwiftUI
    
    let wsURL = "wss://*****.livekit.cloud"
    
    enum ConnectionState {
        case searching  // when on waiting room, but play
        case connecting  // when receive roomID
        case connected  // users LiveKit connection started
        case disconnecting  // user has pressed exit/skip
        case disconnected  // when no lobby
    
        var isNotConnected: Bool {
            switch self {
            case .disconnecting,
                .searching,
                .disconnected:
                return true
            default:
                return false
            }
        }
    }
    
    enum ConnectionType {
        case global
        case invites
        case events
    }
    
    class MatchingViewModel: NotifiableWrapper, ObservableObject {
        @Injected private var services: Services
    
        @Published private(set) var connectionType: ConnectionType? = nil
        @Published private(set) var connectionState: ConnectionState = .disconnected
    
        private var globalMatchingViewModel: GlobalMatchingViewModel?
    
        private var currentMatchingViewModel: (any MatchingTypeViewModel)? {
            switch connectionType {
            case .global:
                return globalMatchingViewModel
            default:
                return nil
            }
        }
    
        override init() {
            super.init()
            setupViewModels()
        }
    
        private(set) var room: Room?
        private(set) var roomModel: RoomModel?
    
        private func setupViewModels() {
            globalMatchingViewModel = GlobalMatchingViewModel()
    
            setupStateObservers()
        }
    
        private func setupStateObservers() {
            globalMatchingViewModel?.onStateChange = { [weak self] state in
                self?.handleChildStateChange(.global, state: state)
            }
        }
    
        func attachRoom(_ room: Room) {
            self.room = room
            globalMatchingViewModel?.attachRoom(room)
        }
    
        func bindSocket(_ roomModel: RoomModel) {
            self.roomModel = roomModel
            globalMatchingViewModel?.bindSocket(roomModel)
        }
    
        override func setNotificationModel(_ model: OrnamentNotificationModel) {
            super.setNotificationModel(model)
    
            globalMatchingViewModel?.setNotificationModel(model)
        }
    
        func changeConnectionType(_ newType: ConnectionType) {
            guard newType != self.connectionType else { return }
    
            if connectionState != .disconnected {
                endCall(state: .disconnected, notifyChangeCallStatus: false)
            }
    
            self.connectionType = newType
            self.connectionState = .disconnected
        }
    
        func changeConnectionState(
            _ newState: ConnectionState,
            connectionType: ConnectionType? = nil
        ) {
            guard newState != self.connectionState else { return }
    
            if let connectionType = connectionType {
                self.connectionType = connectionType
            }
    
            self.connectionState = newState
        }
    
        private func handleChildStateChange(
            _ type: ConnectionType,
            state: ConnectionState
        ) {
            if self.connectionType == nil {
                self.connectionType = type
            }
    
            guard self.connectionType == type else { return }
    
            self.connectionState = state
        }
    }
    
    extension MatchingViewModel {
        public func startMatching() {
            currentMatchingViewModel?.startMatching()
        }
    
        public func skipOrEndCall() {
            self.skip()
        }
    
        public func skip(completion: SocketAckCompletion? = nil) {
            currentMatchingViewModel?.skip(completion: completion)
        }
    
        public func endCall(
            state: ConnectionState,
            notifyChangeCallStatus: Bool? = true
        ) {
            if let currentVM = currentMatchingViewModel {
                currentVM.endCall(
                    state: state,
                    notifyChangeCallStatus: notifyChangeCallStatus
                )
            } else {
                print("end call - no current VM, executing directly")
                DispatchQueue.main.async {
                    Task {
                        self.roomModel?.endCall()
                        await self.room?.disconnect()
                        self.changeConnectionState(state)
                    }
                }
            }
        }
    
        func emitHasConnectedToLiveKit() {
            self.changeConnectionState(.connected)
            roomModel?.joinedVideo()
        }
    }
    
    protocol MatchingTypeViewModel: ObservableObject {
        var onStateChange: ((ConnectionState) -> Void)? { get set }
    
        func startMatching()
        func skip(completion: SocketAckCompletion?)
        func endCall(state: ConnectionState, notifyChangeCallStatus: Bool?)
    }
    

    GlobalMatchingViewModel.swift

    import Combine
    @preconcurrency import LiveKit
    import SwiftUI
    
    class GlobalMatchingViewModel: NotifiableWrapper, MatchingTypeViewModel {
        @Injected private var services: Services
    
        var onStateChange: ((ConnectionState) -> Void)?
    
        private(set) var room: Room?
        private(set) var roomModel: RoomModel?
    
        override init() {
            super.init()
        }
    
        func attachRoom(_ room: Room) {
            self.room = room
        }
    
        func bindSocket(_ roomModel: RoomModel) {
            self.roomModel = roomModel
        }
    
        private func propagateState(_ newState: ConnectionState) {
            onStateChange?(newState)
        }
    }
    
    extension GlobalMatchingViewModel {
        func startMatching() {
            roomModel?.globalManager?.startMatch()
        }
    
        func skip(completion: SocketAckCompletion? = nil) {
            DispatchQueue.main.async {
                Task {
                    self.roomModel?.globalManager?.skip(completion: completion)
                    await self.room?.disconnect()
                }
            }
        }
    
        func endCall(
            state: ConnectionState,
            notifyChangeCallStatus: Bool? = true
        ) {
            guard self.roomModel?.shouldCall == true else { return }
    
            DispatchQueue.main.async {
                Task {
                    self.roomModel?.endCall()
                    await self.room?.disconnect()
    
                    self.propagateState(state)
                }
            }
        }
    }
    

    MatchingContentView.swift

    import Combine
    @preconcurrency import LiveKit
    import LiveKitComponents
    import SDWebImageSwiftUI
    import SwiftUI
    
    struct MatchingContentView: View {
        @EnvironmentObject private var matchingViewModel: MatchingViewModel
        @EnvironmentObject private var roomModel: RoomModel
        @EnvironmentObject private var room: Room
    
        @Environment(\.isFocused) var isFocused: Bool
    
        @State private var partnerCountryName: String = ""
    
        var body: some View {
            Group {
                GeometryReader { geometry in
                    VStack(spacing: 16) {
                        if matchingViewModel.connectionState.isNotConnected {
                            self.searchingStateView(geometry: geometry)
                        } else {
                            #if os(visionOS)
                                self.connectedStateView(geometry: geometry)
                            #else
                                ScrollView(.horizontal) {
                                    ScrollView {
                                        self.connectedStateView(geometry: geometry)
                                    }
                                }
                            #endif
                        }
                    }
            }
        }
    }
    
    extension MatchingContentView {
        //MARK: UI Views
    
        private func searchingStateView(geometry: GeometryProxy) -> some View {
            WaitingRoomView(geometry: geometry)
        }
    
        private func connectedStateView(geometry: GeometryProxy) -> some View {
            Group {
                #if os(visionOS)
                    HStack(spacing: 15) {
                        ParticipantsList(geometry: geometry)
                        ParticipantInfoView()
                    }
                #else
                    ScrollView {
                        VStack(spacing: 15) {
                            ParticipantsList(geometry: geometry)
                            ParticipantInfoView()
                        }
                        .background(.gray.opacity(0.5))
                    }
                #endif
            }
            .padding()
        }
    }
    
    

    MatchingWrapperView.swift. This file contains all views that use MatchingViewModel.

    import AVFoundation
    import Combine
    @preconcurrency import LiveKit
    import LiveKitComponents
    import SwiftUI
    import os
    
    struct MatchingWrapperView: View {
        let content: () -> Content
    
        init(@ViewBuilder content: @escaping () -> Content) {
            self.content = content
        }
    
        @EnvironmentObject private var matchingViewModel: MatchingViewModel
        @EnvironmentObject private var roomModel: RoomModel
        @EnvironmentObject private var eventsViewModel: EventsViewModel
        @EnvironmentObject private var settingsViewModel: SettingsViewModel
        @EnvironmentObject private var notificationModel: OrnamentNotificationModel
        @EnvironmentObject private var room: Room
        @EnvironmentObject private var soundService: SoundService
    
        @Environment(\.selection) private var selection
    
        @State private var isConnecting = false
        @State private var connectTask: Task? = nil
    
        let logger = Logger(subsystem: "persona.vision", category: "LiveKit")
    
        var body: some View {
            content()
                .onAppear {
                    self.handleConnectionStateChange(
                        from: nil,
                        to: matchingViewModel.connectionState
                    )
                }
                .onChange(of: room.connectionState) {
                    oldState,
                    newState in
    
                    guard roomModel.shouldCall else {
                        return
                    }
    
                    switch newState {
    
                    case .disconnected:
                        // here check selection status to start new matching or end it
                        if matchingViewModel.connectionState == .disconnecting {
    
                            if selection != 2 {
                                matchingViewModel
                                    .changeConnectionState(
                                        .disconnected,
                                        connectionType: nil
                                    )
    
                                roomModel.changeShouldCall(false)
    
                                return
                            } else {
                                matchingViewModel.changeConnectionState(.searching)
                            }
                        }
    
                        roomModel.globalManager?.restartMatch()
    
                        break
    
                    case .connected:
                        // if partners are empty skip call to prevent show empty partner info
                        if roomModel.partners.isEmpty {
                            matchingViewModel.changeConnectionState(.disconnecting)
    
                            self.notificationModel.showNotification(
                                OrnamentNotification(
                                    title: "Failed to receive partner info",
                                    type: .error,
                                    customDuration: 5
                                )
                            )
                        }
    
                    case .disconnecting:
                        break
    
                    default:
                        break
                    }
                }
                .onChange(of: roomModel.partners.count) {
                    self.handleChangeRoomIdOrPartners()
                }
                .onChange(of: matchingViewModel.connectionState) {
                    oldState,
                    newState in
                    self.handleConnectionStateChange(
                        from: oldState,
                        to: newState
                    )
                }
        }
    }
    
    extension MatchingWrapperView {
        // MARK: Functions
    
        func connectRoom(token: String) {
            guard room.connectionState == .disconnected else {
                return
            }
    
            Task {
                do {
                    try await room.connect(
                        url: wsURL,
                        token: token,
                        connectOptions: ConnectOptions(enableMicrophone: true)
                    )
                } catch {
                    return
                }
    
                await enableCamera()
    
                matchingViewModel.emitHasConnectedToLiveKit()
            }
        }
    
        private func enableCamera(
            maxRetries: Int = 10,
            delaySeconds: Double = 0.5
        ) async {
            #if !targetEnvironment(simulator)
                do {
                    try await room.localParticipant.setCamera(enabled: true)
                    return
                } catch {
                }
            #endif
        }
    
        private func reattemptConnect(token: String) {
            Task { [self] in
                self.connectRoom(token: token)
            }
        }
    
        private func handleConnectionStateChange(
            from oldState: ConnectionState?,
            to newState: ConnectionState
        ) {
            guard oldState != newState else { return }
    
            print(
                "Connection state changed: \(String(describing: oldState)) → \(newState)"
            )
    
            if newState == .searching {
                matchingViewModel.startMatching()
    
                if settingsViewModel.audioSettings?.waitingSound == true {
                    soundService.playAudio(
                        name: "music_for_waiting_with_delay",
                        type: "mp3",
                        volume: 0.5
                    )
                }
            } else if oldState == .searching && newState == .disconnected {
                matchingViewModel.endCall(state: .disconnected)
                soundService.stopAudio()
            } else {
                soundService.stopAudio()
            }
        }
    
        @MainActor
        func handleChangeRoomIdOrPartners() {
            guard matchingViewModel.connectionState != .disconnected
            else { return }
    
            let hasRoomId = !roomModel.roomId.isEmpty
            let hasPartner = !roomModel.partners.isEmpty
            let isDisconnectedRoom = room.connectionState == .disconnected
            let isConnected = matchingViewModel.connectionState == .connected
            let isDisconnecting =
                matchingViewModel.connectionState == .disconnecting
    
            if hasRoomId, hasPartner, isDisconnectedRoom, !isConnected {
                self.connectToLiveKit()
    
                return
            }
    
            if isDisconnecting || isDisconnectedRoom {
                return
            }
    
            matchingViewModel.changeConnectionState(.disconnecting)
    
            Task {
                await room.disconnect()
            }
    
            if self.notificationModel.notification?.contentView != nil {
                self.notificationModel.dismissNotification()
            }
        }
    
        func connectToLiveKit() {
            matchingViewModel.changeConnectionState(.connecting)
    
            let roomId = self.roomModel.roomId
            let token = self.roomModel.myLiveKitToken
    
            guard !roomId.isEmpty, !token.isEmpty else {
                self.notificationModel.showNotification(
                    OrnamentNotification(
                        title: "Failed to receive room id or LiveKit token",
                        type: .error,
                        customDuration: 5
                    )
                )
    
                matchingViewModel.changeConnectionState(.searching)
    
                SentryService
                    .sendMessage(
                        "Failed to receive room id or LiveKit token",
                        context: SentryContext(extra: ["userId": roomModel.myId])
                    )
    
                return
            }
    
            connectRoom(token: token)
        }
    }
    



    Source link

    iOS LiveKit partners SDK Showing SwiftUI Video
    Follow on Google News Follow on Flipboard
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email Copy Link
    tonirufai
    big tee tech hub
    • Website

    Related Posts

    This week in AI updates: GitHub Copilot SDK, Claude’s new constitution, and more (January 23, 2026)

    January 25, 2026

    ios – Why does my page scroll up when I tap on a button?

    January 25, 2026

    swift – iOS suspends app after BLE discovery even though I start Always-authorized location udpates

    January 24, 2026
    Add A Comment
    Leave A Reply Cancel Reply

    Editors Picks

    Non-Abelian anyons: anything but easy

    January 25, 2026

    Announcing Amazon EC2 G7e instances accelerated by NVIDIA RTX PRO 6000 Blackwell Server Edition GPUs

    January 25, 2026

    Tech CEOs boast and bicker about AI at Davos

    January 25, 2026

    How Content Management Is Transforming Construction ERP

    January 25, 2026
    About Us
    About Us

    Welcome To big tee tech hub. Big tee tech hub is a Professional seo tools Platform. Here we will provide you only interesting content, which you will like very much. We’re dedicated to providing you the best of seo tools, with a focus on dependability and tools. We’re working to turn our passion for seo tools into a booming online website. We hope you enjoy our seo tools as much as we enjoy offering them to you.

    Don't Miss!

    Non-Abelian anyons: anything but easy

    January 25, 2026

    Announcing Amazon EC2 G7e instances accelerated by NVIDIA RTX PRO 6000 Blackwell Server Edition GPUs

    January 25, 2026

    Subscribe to Updates

    Get the latest technology news from Bigteetechhub about IT, Cybersecurity and Big Data.

      • About Us
      • Contact Us
      • Disclaimer
      • Privacy Policy
      • Terms and Conditions
      © 2026 bigteetechhub.All Right Reserved

      Type above and press Enter to search. Press Esc to cancel.