Skip to content

Commit 3e73d70

Browse files
committed
fix: clean files
1 parent b8947cf commit 3e73d70

2 files changed

Lines changed: 70 additions & 10 deletions

File tree

Camera/CameraViewModel.swift

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ final class CameraViewModel: NSObject, ObservableObject {
4343
deinit {
4444
// Ensure brightness is restored if we used screen torch
4545
setScreenTorchEnabled(false)
46+
47+
// Remove orientation observer
48+
if let observer = orientationObserver {
49+
NotificationCenter.default.removeObserver(observer)
50+
}
51+
UIDevice.current.endGeneratingDeviceOrientationNotifications()
4652
}
4753

4854
// MARK: - Grid
@@ -365,6 +371,15 @@ extension CameraViewModel {
365371
print("Video concatenation completed successfully")
366372
print("Output URL: \(outputURL)")
367373
self.saveVideoToPhotos(outputURL)
374+
375+
// CLEANUP segments ONLY after successful export
376+
for segment in self.segments {
377+
try? FileManager.default.removeItem(at: segment.url)
378+
}
379+
DispatchQueue.main.async {
380+
self.segments.removeAll()
381+
}
382+
368383
// Clean up temp file after a delay to ensure save completes
369384
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
370385
try? FileManager.default.removeItem(at: outputURL)
@@ -386,6 +401,15 @@ extension CameraViewModel {
386401
case .success(let filteredURL):
387402
print("Filter applied successfully, saving filtered video")
388403
self.saveVideoToPhotos(filteredURL)
404+
405+
// CLEANUP segments ONLY after successful filtered export
406+
for segment in self.segments {
407+
try? FileManager.default.removeItem(at: segment.url)
408+
}
409+
DispatchQueue.main.async {
410+
self.segments.removeAll()
411+
}
412+
389413
// Clean up temp files after a delay
390414
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
391415
try? FileManager.default.removeItem(at: filteredURL)
@@ -395,23 +419,22 @@ extension CameraViewModel {
395419
print("Filter application failed: \(error)")
396420
print("Saving unfiltered video instead")
397421
self.saveVideoToPhotos(outputURL)
422+
423+
// Even on failure, if we are saving the raw one, we cleanup segments after saving
424+
for segment in self.segments {
425+
try? FileManager.default.removeItem(at: segment.url)
426+
}
427+
DispatchQueue.main.async {
428+
self.segments.removeAll()
429+
}
430+
398431
// Clean up temp file after a delay
399432
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
400433
try? FileManager.default.removeItem(at: outputURL)
401434
}
402435
}
403436
}
404437
}
405-
406-
// Clean up individual segment files
407-
for segment in segments {
408-
try? FileManager.default.removeItem(at: segment.url)
409-
}
410-
411-
// Clear segments after processing
412-
DispatchQueue.main.async {
413-
self.segments.removeAll()
414-
}
415438
}
416439

417440
private func applyFilter(_ filterType: VideoFilter, to composition: AVMutableComposition, completion: @escaping (Result<URL, Error>) -> Void) {

Camera/CaptureSessionController.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ final class CaptureSessionController: NSObject {
3232
private var desiredTorchEnabled: Bool = false
3333
private var cachedZoomFactor: CGFloat = 1.0
3434
private var cachedIsTorchSupported: Bool = false
35+
private var sessionObservers: [Any] = []
3536

3637
// Current camera position convenience
3738
var currentPosition: AVCaptureDevice.Position {
@@ -40,6 +41,42 @@ final class CaptureSessionController: NSObject {
4041
return .unspecified
4142
}
4243

44+
override init() {
45+
super.init()
46+
setupSessionObservers()
47+
}
48+
49+
deinit {
50+
for observer in sessionObservers {
51+
NotificationCenter.default.removeObserver(observer)
52+
}
53+
sessionObservers.removeAll()
54+
}
55+
56+
private func setupSessionObservers() {
57+
let errorObserver = NotificationCenter.default.addObserver(forName: .AVCaptureSessionRuntimeError, object: session, queue: nil) { [weak self] notification in
58+
guard let self = self else { return }
59+
if let error = notification.userInfo?[AVCaptureSessionErrorKey] as? AVError {
60+
print("Camera session runtime error: \(error.localizedDescription)")
61+
if error.code == .mediaServicesWereReset {
62+
// Se o sistema de mídia resetou (raro mas fatal), precisamos tentar reiniciar
63+
if !self.session.isRunning {
64+
self.startSession()
65+
}
66+
}
67+
}
68+
}
69+
sessionObservers.append(errorObserver)
70+
71+
let interruptionObserver = NotificationCenter.default.addObserver(forName: .AVCaptureSessionWasInterrupted, object: session, queue: nil) { notification in
72+
if let reasonValue = notification.userInfo?[AVCaptureSessionInterruptionReasonKey] as? Int,
73+
let reason = AVCaptureSession.InterruptionReason(rawValue: reasonValue) {
74+
print("Camera session interrupted: \(reason)")
75+
}
76+
}
77+
sessionObservers.append(interruptionObserver)
78+
}
79+
4380
// MARK: - Permissions
4481
func requestPermissions(completion: @escaping (Bool) -> Void) {
4582
let group = DispatchGroup()

0 commit comments

Comments
 (0)