diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index d008c309612c..e913461816f4 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.22+10 + +* Fixes error handling in `startWriting`. + ## 0.9.22+9 * Migrates `FLTSavePhotoDelegate`, `FLTWritableData`, and `FLTImageStreamHandler` classes to Swift. diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/SampleBufferTests.swift b/packages/camera/camera_avfoundation/example/ios/RunnerTests/SampleBufferTests.swift index 86130035d14a..ab2baf287563 100644 --- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/SampleBufferTests.swift +++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/SampleBufferTests.swift @@ -359,4 +359,31 @@ final class CameraSampleBufferTests: XCTestCase { AVAudioSession.sharedInstance().category == .playAndRecord, "Category should be PlayAndRecord.") } + func testStartVideoRecordingReportsErrorWhenStartWritingFails() { + let (camera, writerMock, _, _) = createCamera() + + // Configure the mock to return false for startWriting + writerMock.startWritingStub = { + return false + } + + // Configure a mock error + let mockError = NSError( + domain: "test", code: 123, userInfo: [NSLocalizedDescriptionKey: "Mock write error"]) + writerMock.error = mockError + + let expectation = self.expectation(description: "Completion handler called with error") + + camera.startVideoRecording( + completion: { error in + XCTAssertNotNil(error) + XCTAssertEqual(error?.code, "IOError") + XCTAssertEqual(error?.message, "Unable to start writing") + XCTAssertEqual(error?.details as? String, "Mock write error") + XCTAssertFalse(camera.isRecording) + expectation.fulfill() + }, messengerForStreaming: nil) + + waitForExpectations(timeout: 1.0, handler: nil) + } } diff --git a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift index 15a001d63ef0..85fff282d38e 100644 --- a/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift +++ b/packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift @@ -97,7 +97,7 @@ final class DefaultCamera: NSObject, Camera { private var latestPixelBuffer: CVPixelBuffer? private var videoRecordingPath: String? - private var isRecording = false + private(set) var isRecording = false private var isRecordingPaused = false private var isFirstVideoSample = false private var videoIsDisconnected = false @@ -512,7 +512,14 @@ final class DefaultCamera: NSObject, Camera { // didOutputSampleBuffer had chance to call startWriting and lag at start of video // https://github.com/flutter/flutter/issues/132016 // https://github.com/flutter/flutter/issues/151319 - let _ = videoWriter?.startWriting() + guard let videoWriter = videoWriter, videoWriter.startWriting() else { + completion( + FlutterError( + code: "IOError", + message: "Unable to start writing", + details: videoWriter?.error?.localizedDescription)) + return + } isFirstVideoSample = true isRecording = true isRecordingPaused = false diff --git a/packages/camera/camera_avfoundation/pubspec.yaml b/packages/camera/camera_avfoundation/pubspec.yaml index 4f53f2d6d57f..bc6d1928fb4d 100644 --- a/packages/camera/camera_avfoundation/pubspec.yaml +++ b/packages/camera/camera_avfoundation/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_avfoundation description: iOS implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.9.22+9 +version: 0.9.22+10 environment: sdk: ^3.9.0