You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中使用ConnectSDK发现Roku设备速度过慢的问题求助

Roku设备发现速度极慢的问题解决

问题背景

使用ConnectSDK开发iOS应用时,在同一Wi-Fi网络下发现Roku设备的速度极慢,多数情况需要等待很长时间才能检测到设备,仅偶尔能瞬间发现,严重影响用户体验。已通过DiscoveryManager实现设备发现逻辑,且Info.plist中配置了NSLocalNetworkUsageDescription和NSBonjourServices权限,但问题仍未解决。

实现代码

DeviceManager 代码

import Foundation
import ConnectSDK

class DeviceManager: NSObject, DiscoveryManagerDelegate {
    static let shared = DeviceManager()

    private var discoveryManager: DiscoveryManager!
    private(set) var discoveredDevices: [ConnectableDevice] = []

    override private init() {
        super.init()
        
        // Initialize the DiscoveryManager
        discoveryManager = DiscoveryManager.shared()
        discoveryManager.delegate = self
        
        // Register RokuService with DiscoveryManager
        DiscoveryManager.shared().registerDeviceService(RokuService.self, withDiscovery: nil)
        print("DiscoveryManager Initialized and RokuService Registered")
    }

    func startDiscovery() {
        print("Starting device discovery...")
        
        // Start discovery process if it's not already running
        DispatchQueue.main.async { [weak self] in
            self?.discoveryManager.startDiscovery()
        }
    }

    func stopDiscovery() {
        DispatchQueue.main.async { [weak self] in
            self?.discoveryManager.stopDiscovery()
        }
    }

    // MARK: - DiscoveryManagerDelegate Methods

    func discoveryManager(_ manager: DiscoveryManager, didFind device: ConnectableDevice) {
        print("Device found: \(device.friendlyName ?? "Unknown") - IP: \(device.address ?? "No IP")")
        print("Device services: \(device.services ?? [])")
        if let services = device.services, services.contains(where: { $0 is RokuService }) {
            print("Roku Device Found: \(device.friendlyName ?? "Unknown") - IP: \(device.address ?? "No IP")")
            DispatchQueue.global(qos: .userInitiated).async { [weak self] in
                guard let self = self else { return }
                if !self.discoveredDevices.contains(where: { $0 == device }) {
                    self.discoveredDevices.append(device)
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: .deviceListUpdated, object: nil)
                    }
                }
            }
        } else {
            print("Non-Roku device ignored: \(device.friendlyName ?? "Unknown")")
        }
    }

    func discoveryManager(_ manager: DiscoveryManager, didFailWithError error: Error) {
        print("Discovery error: \(error.localizedDescription)")
    }

    func discoveryManager(_ manager: DiscoveryManager, didLose device: ConnectableDevice) {
        print("Device lost: \(device.friendlyName ?? "Unknown")")
        DispatchQueue.main.async { [weak self] in
            self?.discoveredDevices.removeAll { $0 == device }
            NotificationCenter.default.post(name: .deviceListUpdated, object: nil)
        }
    }

    func discoveryManager(_ manager: DiscoveryManager, didUpdate device: ConnectableDevice) {
        print("Device updated: \(device.friendlyName ?? "Unknown") - IP: \(device.address ?? "No IP")")

        // Check for updated Roku devices
        if let services = device.services, services.contains(where: { $0 is RokuService }) {
            print("Roku Device Updated: \(device.friendlyName ?? "Unknown") - IP: \(device.address ?? "No IP")")
            
            DispatchQueue.global(qos: .userInitiated).async { [weak self] in
                guard let self = self else { return }
                if !self.discoveredDevices.contains(where: { $0 == device }) {
                    self.discoveredDevices.append(device)
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: .deviceListUpdated, object: nil)
                    }
                }
            }
        } else {
            print("Non-Roku device update ignored: \(device.friendlyName ?? "Unknown")")
        }
    }
}

AppDelegate 代码

import UIKit
import ConnectSDK

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        DeviceManager.shared.startDiscovery()
        return true
    }

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
    }
}

Notification 扩展代码

import Foundation

extension Notification.Name {
    static let deviceListUpdated = Notification.Name("deviceListUpdated")
}

Info.plist 配置

<key>NSLocalNetworkUsageDescription</key>
<string>This app requires access to local network devices to discover and connect to streaming devices.</string>
<key>NSBonjourServices</key>
<array>
    <string>_roku._tcp</string>
</array>

优化方案

1. 精准配置Roku服务发现

当前代码未指定具体的Bonjour发现参数,导致DiscoveryManager可能做全局扫描,拖慢速度。修改服务注册逻辑,定向扫描Roku的Bonjour服务:

override private init() {
    super.init()
    discoveryManager = DiscoveryManager.shared()
    discoveryManager.delegate = self
    
    // 显式指定Roku的Bonjour服务类型与本地域,缩小扫描范围
    let rokuDiscovery = ServiceDiscovery(service: "_roku._tcp.", domain: "local.")
    DiscoveryManager.shared().registerDeviceService(RokuService.self, withDiscovery: rokuDiscovery)
    print("DiscoveryManager Initialized and RokuService Registered")
}

2. 优化发现启动时机与重试机制

避免在App启动时立即启动发现,建议在用户进入设备选择页面时再触发,同时添加超时重试逻辑,避免长时间等待:

// 在DeviceManager中添加重试逻辑
private var discoveryRetryTimer: Timer?

func startDiscoveryWithRetry() {
    startDiscovery()
    discoveryRetryTimer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { [weak self] _ in
        guard let self = self else { return }
        if self.discoveredDevices.isEmpty {
            self.discoveryManager.restartDiscovery()
            print("Retrying device discovery...")
        } else {
            self.discoveryRetryTimer?.invalidate()
        }
    }
}

3. 简化设备过滤与更新逻辑

当前代码在后台队列做设备存在性检查,且didFind和didUpdate逻辑重复,可提取为统一方法并移到主线程处理:

private func addRokuDeviceIfNeeded(_ device: ConnectableDevice) {
    DispatchQueue.main.async { [weak self] in
        guard let self = self else { return }
        // 用设备ID判断唯一性,比直接比较对象更可靠
        if !self.discoveredDevices.contains(where: { $0.id == device.id }) {
            self.discoveredDevices.append(device)
            NotificationCenter.default.post(name: .deviceListUpdated, object: nil)
        }
    }
}

// 修改didFind方法
func discoveryManager(_ manager: DiscoveryManager, didFind device: ConnectableDevice) {
    print("Device found: \(device.friendlyName ?? "Unknown") - IP: \(device.address ?? "No IP")")
    if device.services?.contains(where: { $0 is RokuService }) == true {
        print("Roku Device Found: \(device.friendlyName ?? "Unknown") - IP: \(device.address ?? "No IP")")
        addRokuDeviceIfNeeded(device)
    } else {
        print("Non-Roku device ignored: \(device.friendlyName ?? "Unknown")")
    }
}

// 修改didUpdate方法
func discoveryManager(_ manager: DiscoveryManager, didUpdate device: ConnectableDevice) {
    print("Device updated: \(device.friendlyName ?? "Unknown") - IP: \(device.address ?? "No IP")")
    if device.services?.contains(where: { $0 is RokuService }) == true {
        print("Roku Device Updated: \(device.friendlyName ?? "Unknown") - IP: \(device.address ?? "No IP")")
        addRokuDeviceIfNeeded(device)
    } else {
        print("Non-Roku device update ignored: \(device.friendlyName ?? "Unknown")")
    }
}

4. 排查网络与权限问题

  • 确认iOS设备与Roku处于同一Wi-Fi频段(避免2.4G与5G跨频段连接)
  • 主动检查本地网络权限状态,确保用户已授权:
import Network

func checkLocalNetworkPermission() {
    let monitor = NWPathMonitor()
    monitor.pathUpdateHandler = { path in
        if path.status == .satisfied && path.usesInterfaceType(.wifi) {
            print("Wi-Fi连接正常,可启动设备发现")
        } else {
            print("网络环境异常,无法进行设备发现")
        }
    }
    let queue = DispatchQueue(label: "NetworkMonitor")
    monitor.start(queue: queue)
}

5. 升级ConnectSDK版本

检查当前使用的ConnectSDK版本,升级到最新版可修复已知的Bonjour发现延迟bug,提升设备检测效率。

内容的提问来源于stack exchange,提问作者Ahsan Abdul Ghani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 05:15:02