React Native iOS原生模块下载视频报错:AVAggregateAssetDownloadTask不支持currentRequest
问题描述
在React Native的iOS原生模块中实现视频下载功能,相同代码在独立iOS应用中可正常运行,但调用原生模块时抛出错误:Exception 'AVAggregateAssetDownloadTask does not support currentRequest property'。
错误调用栈
Exception 'AVAggregateAssetDownloadTask does not support currentRequest property' was thrown while invoking downloadVideoUsingUri on target CacheVideoModule with params ( "https://d14nfbmksdrc0w.cloudfront.net/Doctor_Strange_in_the_Multiverse_of_Madness_Official_Trailer/default.m3u8" ) callstack: ( 0 CoreFoundation 0x0000000193984e44 42CCFC7B-FF32-3D25-8F01-CCB2AD843A8B + 40516 1 libobjc.A.dylib 0x000000018cb1b8d8 objc_exception_throw + 60 2 CFNetwork 0x0000000194c820dc _CFNetworkErrorGetLocalizedDescription + 353964 3 ExoPlayPOC 0x00000001052521a0 __55+[FLEXNetworkObserver injectIntoNSURLSessionTaskResume]_block_invoke_2 + 52 4 ExoPlayPOC 0x0000000105780ec4 $s18react_native_video23AssetPersistenceManagerC14downloadStream3foryAA0D0C_tF + 1280 5 ExoPlayPOC 0x00000001057870a0 $s18react_native_video16CacheVideoModuleC08downloadE8UsingUriyySSF + 828 6 ExoPlayPOC 0x00000001057871ec $s18react_native_video16CacheVideoModuleC08downloadE8UsingUriyySSFTo + 60 7 CoreFoundation 0x00000001939ef6b4 42CCFC7B-FF32-3D25-8F01-CCB2AD843A8B + 476852 8 CoreFoundation 0x000000019399bb1c 42CCFC7B-FF32-3D25-8F01-CCB2AD843A8B + 133916 9 CoreFoundation 0x000000019399b534 42CCFC7B-FF32-3D25-8F01-CCB2AD843A8B + 132404 10 ExoPlayPOC 0x00000001053c136c -[RCTModuleMethod invokeWithBridge:module:arguments:] + 1744 11 ExoPlayPOC 0x00000001053c51b0 _ZN8facebook5reactL11invokeInnerEP9RCTBridgeP13RCTModuleDatajRKN5folly7dynamicEiN12_GLOBAL__N_117SchedulingContextE + 1544 12 ExoPlayPOC 0x00000001053c49cc _ZZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEiENK3$_0clEv + 144 13 ExoPlayPOC 0x00000001053c4930 ___ZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEi_block_invoke + 28 14 libdispatch.dylib 0x000000010850453c _dispatch_call_block_and_release + 32 15 libdispatch.dylib 0x0000000108505ff0 _dispatch_client_callout + 20 16 libdispatch.dylib 0x000000010850e0a0 _dispatch_lane_serial_drain + 988 17 libdispatch.dylib 0x000000010850edc8 _dispatch_lane_invoke + 420 18 libdispatch.dylib 0x000000010851bcac _dispatch_workloop_worker_thread + 740 19 libsystem_pthread.dylib 0x00000001e1bfcdf8 _pthread_wqthread + 288 20 libsystem_pthread.dylib 0x00000001e1bfcb98 start_wqthread + 8 )
相关代码
// 创建AVAssetDownloadURLSession配置 let backgroundConfiguration = URLSessionConfiguration.background(withIdentifier: "AAPL-Identifier") // 初始化AVAssetDownloadURLSession let assetDownloadURLSession = AVAssetDownloadURLSession(configuration: backgroundConfiguration, assetDownloadDelegate: self, delegateQueue: OperationQueue.main) let _asset = AVURLAsset(url: URL(string: "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8")!) let preferredMediaSelection = _asset.preferredMediaSelection guard let task = assetDownloadURLSession.aggregateAssetDownloadTask(with: _asset, mediaSelections: [preferredMediaSelection], assetTitle: "my asset", assetArtworkData: nil, options: [AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: 265_000]) else { return } task.taskDescription = "1" task.resume()
解决建议
从错误栈可明确,问题源于FLEXNetworkObserver在注入NSURLSessionTaskResume逻辑时,访问了AVAggregateAssetDownloadTask不支持的currentRequest属性。以下是具体解决方法:
- 临时关闭FLEX网络监听:如果项目集成了FLEX调试工具,在启动下载任务前调用
[FLEXNetworkObserver stopObserving],下载完成后再调用[FLEXNetworkObserver startObserving]恢复监听。 - 规避FLEX的方法注入:在启动下载任务的代码块前后,临时替换
NSURLSessionTask的resume方法实现,跳过FLEX的注入逻辑,示例代码:// 保存原始resume方法实现 let originalResume = class_getInstanceMethod(NSURLSessionTask.self, #selector(NSURLSessionTask.resume)) let originalImpl = method_getImplementation(originalResume!) // 自定义resume方法,直接调用原始实现 let customResume: @convention(block) (NSURLSessionTask) -> Void = { task in typealias ResumeBlock = @convention(c) (NSURLSessionTask, Selector) -> Void let resumeBlock = unsafeBitCast(originalImpl, to: ResumeBlock.self) resumeBlock(task, #selector(NSURLSessionTask.resume)) } let customImpl = imp_implementationWithBlock(customResume as Any) method_setImplementation(originalResume!, customImpl) // 启动下载任务 task.resume() // 恢复原始resume方法 method_setImplementation(originalResume!, originalImpl) - 生产环境移除FLEX依赖:FLEX是调试工具,生产包中不应包含,直接移除即可解决该问题。
- 排查其他调试工具冲突:除FLEX外,Flipper等React Native调试工具也可能hook
NSURLSessionTask,可尝试关闭相关网络插件或临时禁用工具。
内容的提问来源于stack exchange,提问作者rahulnainwal107
相关产品推荐
相关产品推荐

