簡體   English   中英

Swift / SwiftUI - 在設備鎖定/置於后台之前執行函數?

[英]Swift / SwiftUI - Executing a function before the device locks / is put in the background?

我正在開發一個記錄視頻片段的應用程序(請參閱 Instagram 的卷軸以供參考),並且我目前正在處理應用程序移動到后台/屏幕被鎖定時的狀態。

我目前遇到的問題是,如果我在正在進行的視頻錄制期間將應用程序移至后台/鎖定屏幕,則 AVCaptureFileOutputRecordingDelegate 的 fileOutput 方法無法保存視頻。 我曾嘗試在 .plist 中添加“所需的背景模式”,並且我還偶然發現了以下線程,現在我不確定是否可以在應用程序移動到時實際保存正在進行的視頻錄制背景,以及如果您想遵守隱私准則,這樣做是否是個好主意。

我想知道是否有辦法延遲將應用程序移至后台,以便我可以執行通常用於在設備進入后台之前停止和保存視頻錄制的方法(最終失敗為我保存視頻的過程)。

注意:將我保存/停止正在進行的視頻錄制的方法放在以下觀察中不起作用,它將如上所述失敗:

.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
                print("Moving to the background!")
            toggleRecording() <--- this normally stops and saves the recording but it fails here.
            }

感謝您提供的任何意見!

研究場景協議。

我引用...

場景協議提供場景修飾符,定義為具有默認實現的協議方法,可用於配置場景。 例如,您可以使用 onChange(of:perform:) 修飾符在值更改時觸發操作。 當窗口組中的所有場景都移到后台時,以下代碼清空緩存:

並且要清楚這是Apple提供的示例......

struct MyScene: Scene {
    @Environment(\.scenePhase) private var scenePhase
    @StateObject private var cache = DataCache()

    var body: some Scene {
        WindowGroup {
            MyRootView()
        }
        .onChange(of: scenePhase) { newScenePhase in
            if newScenePhase == .background {
                cache.empty()
            }
        }
    }
}

對於您的情況,您可以使用toggleRecording()替換cache.empty命令。

以下代碼解決了我的特定情況下的問題:

當應用程序進入后台時,會調用AVCaptureFileOutputRecordingDelegate並且不可避免地會發生錯誤。 如果發生這種情況,我會告訴應用程序從我在開始錄制時生成/更新的 url ( var activeRecordingUrl: URL? ) 中查找任何錄制的數據。 如果找到了數據(對我來說似乎總是如此),我會像我一樣存儲它,就像用戶從 UI“手動”停止記錄一樣。


extension CameraViewController: AVCaptureFileOutputRecordingDelegate {
    func fileOutput(
        _ output: AVCaptureFileOutput,
        didFinishRecordingTo outputFileURL: URL,
        from connections: [AVCaptureConnection],
        error: Error?
    ) {
        guard error == nil else {
            // --------- Start of fix ---------
            NSLog("> ERROR: Recording was interrupted: \(String(describing: error?.localizedDescription)), attempting to salvage record data from activeRecordingUrl.")

            
            guard let outputUrl = activeRecordingUrl else {
                NSLog("> ERROR: found nil when unwrapping activeRecordingUrl.")
                onRecordingFinished(false)
                return
            }
            
            recordings.append(VideoSegment(avAssetUrl: outputUrl, cameraPosition: sessionInput.device.position, avAsset: AVAsset(url: outputUrl)))
            NSLog("Found record data from the session that was interrupted.")
            
            onRecordingFinished(true)
            // --------- End of fix ---------
            return
        }

        recordings.append(VideoSegment(
            avAssetUrl: outputFileURL,
            cameraPosition: sessionInput.device.position,
            avAsset: AVAsset(url: outputFileURL
        )))

        onRecordingFinished(true)
    }
}


暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM