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
相关产品推荐
相关产品推荐

