Skip to content

Commit

Permalink
[camera] Remove @throw from iOS implementation (flutter#5034)
Browse files Browse the repository at this point in the history
Using `@throw` in iOS code violates the style guide, so it shouldn't be done in the plugin as mechanism for communicating errors. More importantly, `NSError` is not intended to be used with `@throw`/`@catch`, and is causing issues when compiled with the iOS 17 SDK.

This removes all use of `@throw`, and all `@catch (NSError* e)`, in favor of other methods of communicating errors. It explicitly does not try to fix all the other strange things about this code (having an `NSError` out-param in an init method, using Cocoa and NSURL error domains and codes for some reason), and instead preserves existing behavior as much as possible. In practice, none of these codepaths should ever actually happen (they indicate programming errors within the plugin, not unexpected runtime behavior), and all of this code will go away when converting to Pigeon anyway, so there's not much value in trying to unwind this structure further.

Fixes flutter/flutter#135195
  • Loading branch information
stuartmorgan authored Sep 29, 2023
1 parent 5862201 commit 95b9959
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 94 deletions.
4 changes: 4 additions & 0 deletions packages/camera/camera_avfoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.9.13+6

* Fixes incorrect use of `NSError` that could cause crashes on launch.

## 0.9.13+5

* Ignores audio samples until the first video sample arrives.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "The Flutter Authors";
TargetAttributes = {
03BB76672665316900CE5A93 = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ - (void)testFLTGetFLTFlashModeForString {
XCTAssertEqual(FLTFlashModeAuto, FLTGetFLTFlashModeForString(@"auto"));
XCTAssertEqual(FLTFlashModeAlways, FLTGetFLTFlashModeForString(@"always"));
XCTAssertEqual(FLTFlashModeTorch, FLTGetFLTFlashModeForString(@"torch"));
XCTAssertThrows(FLTGetFLTFlashModeForString(@"unkwown"));
XCTAssertEqual(FLTFlashModeInvalid, FLTGetFLTFlashModeForString(@"unknown"));
}

- (void)testFLTGetAVCaptureFlashModeForFLTFlashMode {
Expand All @@ -34,27 +34,27 @@ - (void)testFLTGetAVCaptureFlashModeForFLTFlashMode {
- (void)testFLTGetStringForFLTExposureMode {
XCTAssertEqualObjects(@"auto", FLTGetStringForFLTExposureMode(FLTExposureModeAuto));
XCTAssertEqualObjects(@"locked", FLTGetStringForFLTExposureMode(FLTExposureModeLocked));
XCTAssertThrows(FLTGetStringForFLTExposureMode(-1));
XCTAssertNil(FLTGetStringForFLTExposureMode(-1));
}

- (void)testFLTGetFLTExposureModeForString {
XCTAssertEqual(FLTExposureModeAuto, FLTGetFLTExposureModeForString(@"auto"));
XCTAssertEqual(FLTExposureModeLocked, FLTGetFLTExposureModeForString(@"locked"));
XCTAssertThrows(FLTGetFLTExposureModeForString(@"unknown"));
XCTAssertEqual(FLTExposureModeInvalid, FLTGetFLTExposureModeForString(@"unknown"));
}

#pragma mark - focus mode tests

- (void)testFLTGetStringForFLTFocusMode {
XCTAssertEqualObjects(@"auto", FLTGetStringForFLTFocusMode(FLTFocusModeAuto));
XCTAssertEqualObjects(@"locked", FLTGetStringForFLTFocusMode(FLTFocusModeLocked));
XCTAssertThrows(FLTGetStringForFLTFocusMode(-1));
XCTAssertNil(FLTGetStringForFLTFocusMode(-1));
}

- (void)testFLTGetFLTFocusModeForString {
XCTAssertEqual(FLTFocusModeAuto, FLTGetFLTFocusModeForString(@"auto"));
XCTAssertEqual(FLTFocusModeLocked, FLTGetFLTFocusModeForString(@"locked"));
XCTAssertThrows(FLTGetFLTFocusModeForString(@"unknown"));
XCTAssertEqual(FLTFocusModeInvalid, FLTGetFLTFocusModeForString(@"unknown"));
}

#pragma mark - resolution preset tests
Expand All @@ -67,7 +67,7 @@ - (void)testFLTGetFLTResolutionPresetForString {
XCTAssertEqual(FLTResolutionPresetVeryHigh, FLTGetFLTResolutionPresetForString(@"veryHigh"));
XCTAssertEqual(FLTResolutionPresetUltraHigh, FLTGetFLTResolutionPresetForString(@"ultraHigh"));
XCTAssertEqual(FLTResolutionPresetMax, FLTGetFLTResolutionPresetForString(@"max"));
XCTAssertThrows(FLTGetFLTFlashModeForString(@"unknown"));
XCTAssertEqual(FLTResolutionPresetInvalid, FLTGetFLTResolutionPresetForString(@"unknown"));
}

#pragma mark - video format tests
Expand All @@ -89,7 +89,7 @@ - (void)testFLTGetUIDeviceOrientationForString {
XCTAssertEqual(UIDeviceOrientationLandscapeLeft,
FLTGetUIDeviceOrientationForString(@"landscapeRight"));
XCTAssertEqual(UIDeviceOrientationPortrait, FLTGetUIDeviceOrientationForString(@"portraitUp"));
XCTAssertThrows(FLTGetUIDeviceOrientationForString(@"unknown"));
XCTAssertEqual(UIDeviceOrientationUnknown, FLTGetUIDeviceOrientationForString(@"unknown"));
}

- (void)testFLTGetStringForUIDeviceOrientation {
Expand Down
12 changes: 12 additions & 0 deletions packages/camera/camera_avfoundation/ios/Classes/CameraProperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ typedef NS_ENUM(NSInteger, FLTFlashMode) {
FLTFlashModeAuto,
FLTFlashModeAlways,
FLTFlashModeTorch,
// This should never occur; it indicates an unknown value was received over
// the platform channel.
FLTFlashModeInvalid,
};

/**
Expand All @@ -39,6 +42,9 @@ extern AVCaptureFlashMode FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashMode m
typedef NS_ENUM(NSInteger, FLTExposureMode) {
FLTExposureModeAuto,
FLTExposureModeLocked,
// This should never occur; it indicates an unknown value was received over
// the platform channel.
FLTExposureModeInvalid,
};

/**
Expand All @@ -61,6 +67,9 @@ extern FLTExposureMode FLTGetFLTExposureModeForString(NSString *mode);
typedef NS_ENUM(NSInteger, FLTFocusMode) {
FLTFocusModeAuto,
FLTFocusModeLocked,
// This should never occur; it indicates an unknown value was received over
// the platform channel.
FLTFocusModeInvalid,
};

/**
Expand Down Expand Up @@ -100,6 +109,9 @@ typedef NS_ENUM(NSInteger, FLTResolutionPreset) {
FLTResolutionPresetVeryHigh,
FLTResolutionPresetUltraHigh,
FLTResolutionPresetMax,
// This should never occur; it indicates an unknown value was received over
// the platform channel.
FLTResolutionPresetInvalid,
};

/**
Expand Down
63 changes: 13 additions & 50 deletions packages/camera/camera_avfoundation/ios/Classes/CameraProperties.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ FLTFlashMode FLTGetFLTFlashModeForString(NSString *mode) {
} else if ([mode isEqualToString:@"torch"]) {
return FLTFlashModeTorch;
} else {
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSURLErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey : [NSString
stringWithFormat:@"Unknown flash mode %@", mode]
}];
@throw error;
return FLTFlashModeInvalid;
}
}

Expand All @@ -48,14 +42,11 @@ AVCaptureFlashMode FLTGetAVCaptureFlashModeForFLTFlashMode(FLTFlashMode mode) {
return @"auto";
case FLTExposureModeLocked:
return @"locked";
case FLTExposureModeInvalid:
// This value should never actually be used.
return nil;
}
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSURLErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey : [NSString
stringWithFormat:@"Unknown string for exposure mode"]
}];
@throw error;
return nil;
}

FLTExposureMode FLTGetFLTExposureModeForString(NSString *mode) {
Expand All @@ -64,13 +55,7 @@ FLTExposureMode FLTGetFLTExposureModeForString(NSString *mode) {
} else if ([mode isEqualToString:@"locked"]) {
return FLTExposureModeLocked;
} else {
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSURLErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey : [NSString
stringWithFormat:@"Unknown exposure mode %@", mode]
}];
@throw error;
return FLTExposureModeInvalid;
}
}

Expand All @@ -82,14 +67,11 @@ FLTExposureMode FLTGetFLTExposureModeForString(NSString *mode) {
return @"auto";
case FLTFocusModeLocked:
return @"locked";
case FLTFocusModeInvalid:
// This value should never actually be used.
return nil;
}
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSURLErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey : [NSString
stringWithFormat:@"Unknown string for focus mode"]
}];
@throw error;
return nil;
}

FLTFocusMode FLTGetFLTFocusModeForString(NSString *mode) {
Expand All @@ -98,13 +80,7 @@ FLTFocusMode FLTGetFLTFocusModeForString(NSString *mode) {
} else if ([mode isEqualToString:@"locked"]) {
return FLTFocusModeLocked;
} else {
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSURLErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey : [NSString
stringWithFormat:@"Unknown focus mode %@", mode]
}];
@throw error;
return FLTFocusModeInvalid;
}
}

Expand All @@ -120,14 +96,7 @@ UIDeviceOrientation FLTGetUIDeviceOrientationForString(NSString *orientation) {
} else if ([orientation isEqualToString:@"portraitUp"]) {
return UIDeviceOrientationPortrait;
} else {
NSError *error = [NSError
errorWithDomain:NSCocoaErrorDomain
code:NSURLErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey :
[NSString stringWithFormat:@"Unknown device orientation %@", orientation]
}];
@throw error;
return UIDeviceOrientationUnknown;
}
}

Expand Down Expand Up @@ -163,13 +132,7 @@ FLTResolutionPreset FLTGetFLTResolutionPresetForString(NSString *preset) {
} else if ([preset isEqualToString:@"max"]) {
return FLTResolutionPresetMax;
} else {
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSURLErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey : [NSString
stringWithFormat:@"Unknown resolution preset %@", preset]
}];
@throw error;
return FLTResolutionPresetInvalid;
}
}

Expand Down
Loading

0 comments on commit 95b9959

Please sign in to comment.