Skip to content

Commit e2c7222

Browse files
[camera_avfoundation] Implementation swift migration - part 7 (#9595)
Migrates camera implementation as part of flutter/flutter#119109 This PR migrates the 4th chunk of `FLTCam` class to Swift: * `setZoomLevel` * `setFlashMode` * `flutterErrorFromNSError` Some properties of the `FLTCam` have to be temporarily made public so that they are accessible in `DefaultCamera`. [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 12fad6d commit e2c7222

File tree

5 files changed

+98
-73
lines changed

5 files changed

+98
-73
lines changed

packages/camera/camera_avfoundation/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.9.20+3
2+
3+
* Migrates `setZoomLevel` and `setFlashMode` methods to Swift.
4+
15
## 0.9.20+2
26

37
* Migrates exposure offset and zoom factor limit getters to Swift.

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation/DefaultCamera.swift

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ final class DefaultCamera: FLTCam, Camera {
4545
private var exposureMode = FCPPlatformExposureMode.auto
4646
private var focusMode = FCPPlatformFocusMode.auto
4747

48+
private static func flutterErrorFromNSError(_ error: NSError) -> FlutterError {
49+
return FlutterError(
50+
code: "Error \(error.code)",
51+
message: error.localizedDescription,
52+
details: error.domain)
53+
}
54+
4855
func reportInitializationState() {
4956
// Get all the state on the current thread, not the main thread.
5057
let state = FCPPlatformCameraState.make(
@@ -241,6 +248,91 @@ final class DefaultCamera: FLTCam, Camera {
241248
return CGPoint(x: x, y: y)
242249
}
243250

251+
func setZoomLevel(_ zoom: CGFloat, withCompletion completion: @escaping (FlutterError?) -> Void) {
252+
if zoom < captureDevice.minAvailableVideoZoomFactor
253+
|| zoom > captureDevice.maxAvailableVideoZoomFactor
254+
{
255+
completion(
256+
FlutterError(
257+
code: "ZOOM_ERROR",
258+
message:
259+
"Zoom level out of bounds (zoom level should be between \(captureDevice.minAvailableVideoZoomFactor) and \(captureDevice.maxAvailableVideoZoomFactor).",
260+
details: nil))
261+
return
262+
}
263+
264+
do {
265+
try captureDevice.lockForConfiguration()
266+
} catch let error as NSError {
267+
completion(DefaultCamera.flutterErrorFromNSError(error))
268+
return
269+
}
270+
271+
captureDevice.videoZoomFactor = zoom
272+
captureDevice.unlockForConfiguration()
273+
completion(nil)
274+
}
275+
276+
func setFlashMode(
277+
_ mode: FCPPlatformFlashMode,
278+
withCompletion completion: @escaping (FlutterError?) -> Void
279+
) {
280+
switch mode {
281+
case .torch:
282+
guard captureDevice.hasTorch else {
283+
completion(
284+
FlutterError(
285+
code: "setFlashModeFailed",
286+
message: "Device does not support torch mode",
287+
details: nil)
288+
)
289+
return
290+
}
291+
guard captureDevice.isTorchAvailable else {
292+
completion(
293+
FlutterError(
294+
code: "setFlashModeFailed",
295+
message: "Torch mode is currently not available",
296+
details: nil))
297+
return
298+
}
299+
if captureDevice.torchMode != .on {
300+
try? captureDevice.lockForConfiguration()
301+
captureDevice.torchMode = .on
302+
captureDevice.unlockForConfiguration()
303+
}
304+
case .off, .auto, .always:
305+
guard captureDevice.hasFlash else {
306+
completion(
307+
FlutterError(
308+
code: "setFlashModeFailed",
309+
message: "Device does not have flash capabilities",
310+
details: nil))
311+
return
312+
}
313+
let avFlashMode = FCPGetAVCaptureFlashModeForPigeonFlashMode(mode)
314+
guard capturePhotoOutput.supportedFlashModes.contains(NSNumber(value: avFlashMode.rawValue))
315+
else {
316+
completion(
317+
FlutterError(
318+
code: "setFlashModeFailed",
319+
message: "Device does not support this specific flash mode",
320+
details: nil))
321+
return
322+
}
323+
if captureDevice.torchMode != .off {
324+
try? captureDevice.lockForConfiguration()
325+
captureDevice.torchMode = .off
326+
captureDevice.unlockForConfiguration()
327+
}
328+
@unknown default:
329+
assertionFailure("Unknown flash mode")
330+
}
331+
332+
flashMode = mode
333+
completion(nil)
334+
}
335+
244336
func pausePreview() {
245337
isPreviewPaused = true
246338
}

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/FLTCam.m

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ @interface FLTCam () <AVCaptureVideoDataOutputSampleBufferDelegate,
5555
@property(nonatomic, copy) CaptureDeviceFactory captureDeviceFactory;
5656
@property(nonatomic, copy) AudioCaptureDeviceFactory audioCaptureDeviceFactory;
5757
@property(readonly, nonatomic) NSObject<FLTCaptureDeviceInputFactory> *captureDeviceInputFactory;
58-
@property(assign, nonatomic) FCPPlatformFlashMode flashMode;
5958
@property(nonatomic, copy) AssetWriterFactory assetWriterFactory;
6059
@property(nonatomic, copy) InputPixelBufferAdaptorFactory inputPixelBufferAdaptorFactory;
6160
/// Reports the given error message to the Dart side of the plugin.
@@ -511,51 +510,6 @@ - (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable,
511510
}
512511
}
513512

514-
- (void)setFlashMode:(FCPPlatformFlashMode)mode
515-
withCompletion:(void (^)(FlutterError *_Nullable))completion {
516-
if (mode == FCPPlatformFlashModeTorch) {
517-
if (!_captureDevice.hasTorch) {
518-
completion([FlutterError errorWithCode:@"setFlashModeFailed"
519-
message:@"Device does not support torch mode"
520-
details:nil]);
521-
return;
522-
}
523-
if (!_captureDevice.isTorchAvailable) {
524-
completion([FlutterError errorWithCode:@"setFlashModeFailed"
525-
message:@"Torch mode is currently not available"
526-
details:nil]);
527-
return;
528-
}
529-
if (_captureDevice.torchMode != AVCaptureTorchModeOn) {
530-
[_captureDevice lockForConfiguration:nil];
531-
[_captureDevice setTorchMode:AVCaptureTorchModeOn];
532-
[_captureDevice unlockForConfiguration];
533-
}
534-
} else {
535-
if (!_captureDevice.hasFlash) {
536-
completion([FlutterError errorWithCode:@"setFlashModeFailed"
537-
message:@"Device does not have flash capabilities"
538-
details:nil]);
539-
return;
540-
}
541-
AVCaptureFlashMode avFlashMode = FCPGetAVCaptureFlashModeForPigeonFlashMode(mode);
542-
if (![_capturePhotoOutput.supportedFlashModes
543-
containsObject:[NSNumber numberWithInt:((int)avFlashMode)]]) {
544-
completion([FlutterError errorWithCode:@"setFlashModeFailed"
545-
message:@"Device does not support this specific flash mode"
546-
details:nil]);
547-
return;
548-
}
549-
if (_captureDevice.torchMode != AVCaptureTorchModeOff) {
550-
[_captureDevice lockForConfiguration:nil];
551-
[_captureDevice setTorchMode:AVCaptureTorchModeOff];
552-
[_captureDevice unlockForConfiguration];
553-
}
554-
}
555-
_flashMode = mode;
556-
completion(nil);
557-
}
558-
559513
- (void)setDescriptionWhileRecording:(NSString *)cameraName
560514
withCompletion:(void (^)(FlutterError *_Nullable))completion {
561515
if (!_isRecording) {
@@ -667,29 +621,6 @@ - (void)stopImageStream {
667621
}
668622
}
669623

670-
- (void)setZoomLevel:(CGFloat)zoom withCompletion:(void (^)(FlutterError *_Nullable))completion {
671-
if (_captureDevice.maxAvailableVideoZoomFactor < zoom ||
672-
_captureDevice.minAvailableVideoZoomFactor > zoom) {
673-
NSString *errorMessage = [NSString
674-
stringWithFormat:@"Zoom level out of bounds (zoom level should be between %f and %f).",
675-
_captureDevice.minAvailableVideoZoomFactor,
676-
_captureDevice.maxAvailableVideoZoomFactor];
677-
678-
completion([FlutterError errorWithCode:@"ZOOM_ERROR" message:errorMessage details:nil]);
679-
return;
680-
}
681-
682-
NSError *error = nil;
683-
if (![_captureDevice lockForConfiguration:&error]) {
684-
completion(FlutterErrorFromNSError(error));
685-
return;
686-
}
687-
_captureDevice.videoZoomFactor = zoom;
688-
[_captureDevice unlockForConfiguration];
689-
690-
completion(nil);
691-
}
692-
693624
- (BOOL)setupWriterForPath:(NSString *)path {
694625
NSError *error = nil;
695626
NSURL *outputURL;

packages/camera/camera_avfoundation/ios/camera_avfoundation/Sources/camera_avfoundation_objc/include/camera_avfoundation/FLTCam.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ NS_ASSUME_NONNULL_BEGIN
5050
@property(readonly, nonatomic) NSObject<FLTDeviceOrientationProviding> *deviceOrientationProvider;
5151
@property(assign, nonatomic) UIDeviceOrientation lockedCaptureOrientation;
5252
@property(assign, nonatomic) UIDeviceOrientation deviceOrientation;
53+
@property(assign, nonatomic) FCPPlatformFlashMode flashMode;
5354

5455
/// Initializes an `FLTCam` instance with the given configuration.
5556
/// @param error report to the caller if any error happened creating the camera.
@@ -66,16 +67,13 @@ NS_ASSUME_NONNULL_BEGIN
6667
messengerForStreaming:(nullable NSObject<FlutterBinaryMessenger> *)messenger;
6768
- (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable,
6869
FlutterError *_Nullable))completion;
69-
- (void)setFlashMode:(FCPPlatformFlashMode)mode
70-
withCompletion:(void (^)(FlutterError *_Nullable))completion;
7170

7271
- (void)setDescriptionWhileRecording:(NSString *)cameraName
7372
withCompletion:(void (^)(FlutterError *_Nullable))completion;
7473

7574
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger
7675
completion:(nonnull void (^)(FlutterError *_Nullable))completion;
7776
- (void)stopImageStream;
78-
- (void)setZoomLevel:(CGFloat)zoom withCompletion:(void (^)(FlutterError *_Nullable))completion;
7977
- (void)setUpCaptureSessionForAudioIfNeeded;
8078

8179
// Methods exposed for the Swift DefaultCamera subclass

packages/camera/camera_avfoundation/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: camera_avfoundation
22
description: iOS implementation of the camera plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
5-
version: 0.9.20+2
5+
version: 0.9.20+3
66

77
environment:
88
sdk: ^3.6.0

0 commit comments

Comments
 (0)