fix(iOS): use UIKit UIActivityViewController directly instead of SwiftUI .sheet

SwiftUI multiple .sheet modifiers can conflict — replaced the pendingExportURL
sheet binding with a direct UIKit UIActivityViewController presentation from
the key window's root VC. This bypasses any SwiftUI sheet stack issues.

Also added copyLocalFile() for local file recording (FileManager.copyItem
instead of URLSession.download which fails on file:// URLs).
This commit is contained in:
yumoqing 2026-07-17 21:21:16 +08:00
parent 4aec892151
commit 04fb3acecc

View File

@ -178,10 +178,10 @@ final class PlayerBridge: ObservableObject {
#if os(iOS)
hlsRecorder.onRecordingSaved = { [weak self] url in
NSLog("[MiniPlayer] onRecordingSaved called, setting pendingExportURL: %@", url.lastPathComponent)
NSLog("[MiniPlayer] onRecordingSaved called: %@", url.lastPathComponent)
self?.showToast("Saved: \(url.lastPathComponent)")
self?.pendingExportURL = url
NSLog("[MiniPlayer] pendingExportURL set to: %@", url.lastPathComponent)
// UIKit present SwiftUI sheet binding
self?.presentShareSheet(for: url)
}
hlsRecorder.onError = { [weak self] msg in
self?.showToast(msg)
@ -190,6 +190,26 @@ final class PlayerBridge: ObservableObject {
}
#if os(iOS)
/// UIKit present UIActivityViewController SwiftUI sheet sheet
func presentShareSheet(for url: URL) {
guard let windowScene = UIApplication.shared.connectedScenes
.compactMap({ $0 as? UIWindowScene })
.first(where: { $0.activationState == .foregroundActive })
?? UIApplication.shared.connectedScenes.compactMap({ $0 as? UIWindowScene }).first
else { return }
var topVC = windowScene.keyWindow?.rootViewController
?? windowScene.windows.first(where: { !$0.isHidden && $0.bounds.size != .zero })?.rootViewController
while let presented = topVC?.presentedViewController { topVC = presented }
let activityVC = UIActivityViewController(activityItems: [url], applicationActivities: nil)
activityVC.completionWithItemsHandler = { _, _, _, _ in
//
}
topVC?.present(activityVC, animated: true)
NSLog("[MiniPlayer] presentShareSheet: presented for %@", url.lastPathComponent)
}
/// AVAudioSession PiP
private func ensureAudioSession() {
let session = AVAudioSession.sharedInstance()