[camera] Remove iOS thread-safe result class (#6498)
`FlutterResult` is thread-safe in all versions of Flutter that this plugin now supports, so the wrapper class to move result calls to the main thread is no longer necessary.
diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md
index 10cb652..260df0c 100644
--- a/packages/camera/camera_avfoundation/CHANGELOG.md
+++ b/packages/camera/camera_avfoundation/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.9.15+1
+
+* Simplifies internal handling of method channel responses.
+
## 0.9.15
* Adds support to control video FPS and bitrate. See `CameraController.withSettings`.
diff --git a/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj b/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj
index dad7730..86296ea 100644
--- a/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/project.pbxproj
@@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
033B94BE269C40A200B4DF97 /* CameraMethodChannelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 033B94BD269C40A200B4DF97 /* CameraMethodChannelTests.m */; };
03BB766B2665316900CE5A93 /* CameraFocusTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 03BB766A2665316900CE5A93 /* CameraFocusTests.m */; };
- 03F6F8B226CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F6F8B126CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
236906D1621AE863A5B2E770 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 89D82918721FABF772705DB0 /* libPods-Runner.a */; };
25C3919135C3D981E6F800D0 /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1944D8072499F3B5E7653D44 /* libPods-RunnerTests.a */; };
@@ -36,7 +35,6 @@
E0CDBAC227CD9729002561D9 /* CameraTestUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */; };
E0F95E3D27A32AB900699390 /* CameraPropertiesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E0F95E3C27A32AB900699390 /* CameraPropertiesTests.m */; };
E487C86026D686A10034AC92 /* CameraPreviewPauseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E487C85F26D686A10034AC92 /* CameraPreviewPauseTests.m */; };
- F6EE622F2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m in Sources */ = {isa = PBXBuildFile; fileRef = F6EE622E2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -68,7 +66,6 @@
03BB766A2665316900CE5A93 /* CameraFocusTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraFocusTests.m; sourceTree = "<group>"; };
03BB766C2665316900CE5A93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
03BB767226653ABE00CE5A93 /* CameraOrientationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CameraOrientationTests.m; sourceTree = "<group>"; };
- 03F6F8B126CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ThreadSafeFlutterResultTests.m; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
14AE82C910C2A12F2ECB2094 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
@@ -106,8 +103,6 @@
E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraTestUtils.m; sourceTree = "<group>"; };
E0F95E3C27A32AB900699390 /* CameraPropertiesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraPropertiesTests.m; sourceTree = "<group>"; };
E487C85F26D686A10034AC92 /* CameraPreviewPauseTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CameraPreviewPauseTests.m; sourceTree = "<group>"; };
- F63F9EED27143B19002479BF /* MockFLTThreadSafeFlutterResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockFLTThreadSafeFlutterResult.h; sourceTree = "<group>"; };
- F6EE622E2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MockFLTThreadSafeFlutterResult.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -138,7 +133,6 @@
03BB767226653ABE00CE5A93 /* CameraOrientationTests.m */,
03BB766C2665316900CE5A93 /* Info.plist */,
033B94BD269C40A200B4DF97 /* CameraMethodChannelTests.m */,
- 03F6F8B126CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m */,
E0C6E1FF2770F01A00EA6AA3 /* ThreadSafeEventChannelTests.m */,
E0C6E1FD2770F01A00EA6AA3 /* ThreadSafeMethodChannelTests.m */,
E0C6E1FE2770F01A00EA6AA3 /* ThreadSafeTextureRegistryTests.m */,
@@ -150,8 +144,6 @@
E0CDBAC027CD9729002561D9 /* CameraTestUtils.h */,
E0CDBAC127CD9729002561D9 /* CameraTestUtils.m */,
E487C85F26D686A10034AC92 /* CameraPreviewPauseTests.m */,
- F6EE622E2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m */,
- F63F9EED27143B19002479BF /* MockFLTThreadSafeFlutterResult.h */,
E032F24F279F5E94009E9028 /* CameraCaptureSessionQueueRaceConditionTests.m */,
E0F95E3C27A32AB900699390 /* CameraPropertiesTests.m */,
788A065927B0E02900533D74 /* StreamingTest.m */,
@@ -287,7 +279,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1430;
+ LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "The Flutter Authors";
TargetAttributes = {
03BB76672665316900CE5A93 = {
@@ -445,7 +437,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 03F6F8B226CBB4670024B8D3 /* ThreadSafeFlutterResultTests.m in Sources */,
033B94BE269C40A200B4DF97 /* CameraMethodChannelTests.m in Sources */,
E071CF7227B3061B006EF3BA /* FLTCamPhotoCaptureTests.m in Sources */,
E0F95E3D27A32AB900699390 /* CameraPropertiesTests.m in Sources */,
@@ -455,7 +446,6 @@
E071CF7427B31DE4006EF3BA /* FLTCamSampleBufferTests.m in Sources */,
E04F108627A87CA600573D0C /* FLTSavePhotoDelegateTests.m in Sources */,
43ED1537282570DE00EB00DE /* AvailableCamerasTest.m in Sources */,
- F6EE622F2710A6FC00905E4A /* MockFLTThreadSafeFlutterResult.m in Sources */,
E0CDBAC227CD9729002561D9 /* CameraTestUtils.m in Sources */,
334733EA2668111C00DCC49E /* CameraOrientationTests.m in Sources */,
CEF6611A2B5E36A500D33FD4 /* CameraSessionPresetsTests.m in Sources */,
diff --git a/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index 1ff4b57..5e1cf7e 100644
--- a/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/packages/camera/camera_avfoundation/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "1430"
+ LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/AvailableCamerasTest.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/AvailableCamerasTest.m
index 6074b87..341d532 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/AvailableCamerasTest.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/AvailableCamerasTest.m
@@ -7,7 +7,6 @@
@import XCTest;
@import AVFoundation;
#import <OCMock/OCMock.h>
-#import "MockFLTThreadSafeFlutterResult.h"
@interface AvailableCamerasTest : XCTestCase
@end
@@ -56,17 +55,19 @@
}
OCMStub([discoverySessionMock devices]).andReturn([NSArray arrayWithArray:cameras]);
- MockFLTThreadSafeFlutterResult *resultObject =
- [[MockFLTThreadSafeFlutterResult alloc] initWithExpectation:expectation];
-
// Set up method call
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"availableCameras"
arguments:nil];
- [camera handleMethodCallAsync:call result:resultObject];
+ __block id resultValue;
+ [camera handleMethodCallAsync:call
+ result:^(id _Nullable result) {
+ resultValue = result;
+ [expectation fulfill];
+ }];
// Verify the result
- NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult;
+ NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
if (@available(iOS 13.0, *)) {
XCTAssertTrue([dictionaryResult count] == 4);
} else {
@@ -104,17 +105,19 @@
[cameras addObjectsFromArray:@[ wideAngleCamera, frontFacingCamera ]];
OCMStub([discoverySessionMock devices]).andReturn([NSArray arrayWithArray:cameras]);
- MockFLTThreadSafeFlutterResult *resultObject =
- [[MockFLTThreadSafeFlutterResult alloc] initWithExpectation:expectation];
-
// Set up method call
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"availableCameras"
arguments:nil];
- [camera handleMethodCallAsync:call result:resultObject];
+ __block id resultValue;
+ [camera handleMethodCallAsync:call
+ result:^(id _Nullable result) {
+ resultValue = result;
+ [expectation fulfill];
+ }];
// Verify the result
- NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult;
+ NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
XCTAssertTrue([dictionaryResult count] == 2);
}
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraCaptureSessionQueueRaceConditionTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraCaptureSessionQueueRaceConditionTests.m
index 89f4030..bc3713b 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraCaptureSessionQueueRaceConditionTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraCaptureSessionQueueRaceConditionTests.m
@@ -30,10 +30,9 @@
[disposeExpectation fulfill];
}];
[camera createCameraOnSessionQueueWithCreateMethodCall:createCall
- result:[[FLTThreadSafeFlutterResult alloc]
- initWithResult:^(id _Nullable result) {
- [createExpectation fulfill];
- }]];
+ result:^(id _Nullable result) {
+ [createExpectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:1 handler:nil];
// `captureSessionQueue` must not be nil after `create` call. Otherwise a nil
// `captureSessionQueue` passed into `AVCaptureVideoDataOutput::setSampleBufferDelegate:queue:`
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraFocusTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraFocusTests.m
index 1b6ada5..3575cd2 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraFocusTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraFocusTests.m
@@ -114,11 +114,11 @@
[_camera setValue:_mockDevice forKey:@"captureDevice"];
// Run test
- [_camera setFocusPointWithResult:[[FLTThreadSafeFlutterResult alloc]
- initWithResult:^(id _Nullable result){
- }]
- x:1
- y:1];
+ [_camera
+ setFocusPointWithResult:^(id _Nullable result) {
+ }
+ x:1
+ y:1];
// Verify the focus point of interest has been set
OCMVerify([_mockDevice setFocusPointOfInterest:CGPointMake(1, 1)]);
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.m
index bd20134..423b8e8 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraMethodChannelTests.m
@@ -7,7 +7,6 @@
@import XCTest;
@import AVFoundation;
#import <OCMock/OCMock.h>
-#import "MockFLTThreadSafeFlutterResult.h"
@interface CameraMethodChannelTests : XCTestCase
@end
@@ -28,19 +27,21 @@
OCMStub([avCaptureSessionMock alloc]).andReturn(avCaptureSessionMock);
OCMStub([avCaptureSessionMock canSetSessionPreset:[OCMArg any]]).andReturn(YES);
- MockFLTThreadSafeFlutterResult *resultObject =
- [[MockFLTThreadSafeFlutterResult alloc] initWithExpectation:expectation];
-
// Set up method call
FlutterMethodCall *call = [FlutterMethodCall
methodCallWithMethodName:@"create"
arguments:@{@"resolutionPreset" : @"medium", @"enableAudio" : @(1)}];
- [camera createCameraOnSessionQueueWithCreateMethodCall:call result:resultObject];
+ __block id resultValue;
+ [camera createCameraOnSessionQueueWithCreateMethodCall:call
+ result:^(id _Nullable result) {
+ resultValue = result;
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:1 handler:nil];
// Verify the result
- NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult;
+ NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
XCTAssertNotNil(dictionaryResult);
XCTAssert([[dictionaryResult allKeys] containsObject:@"cameraId"]);
}
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPreviewPauseTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPreviewPauseTests.m
index 1dfc90b..2ce7b86 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPreviewPauseTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraPreviewPauseTests.m
@@ -7,7 +7,6 @@
@import XCTest;
@import AVFoundation;
#import <OCMock/OCMock.h>
-#import "MockFLTThreadSafeFlutterResult.h"
@interface CameraPreviewPauseTests : XCTestCase
@end
@@ -16,17 +15,17 @@
- (void)testPausePreviewWithResult_shouldPausePreview {
FLTCam *camera = [[FLTCam alloc] init];
- MockFLTThreadSafeFlutterResult *resultObject = [[MockFLTThreadSafeFlutterResult alloc] init];
- [camera pausePreviewWithResult:resultObject];
+ [camera pausePreviewWithResult:^(id _Nullable result){
+ }];
XCTAssertTrue(camera.isPreviewPaused);
}
- (void)testResumePreviewWithResult_shouldResumePreview {
FLTCam *camera = [[FLTCam alloc] init];
- MockFLTThreadSafeFlutterResult *resultObject = [[MockFLTThreadSafeFlutterResult alloc] init];
- [camera resumePreviewWithResult:resultObject];
+ [camera resumePreviewWithResult:^(id _Nullable result){
+ }];
XCTAssertFalse(camera.isPreviewPaused);
}
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.m
index ecf2b17..3177fe4 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraSettingsTests.m
@@ -8,7 +8,6 @@
@import AVFoundation;
#import <OCMock/OCMock.h>
#import "CameraTestUtils.h"
-#import "MockFLTThreadSafeFlutterResult.h"
static const char *gTestResolutionPreset = "medium";
static const int gTestFramesPerSecond = 15;
@@ -19,44 +18,33 @@
@interface CameraCreateWithMediaSettingsParseTests : XCTestCase
@end
-@interface MockErrorFlutterResult : MockFLTThreadSafeFlutterResult
-@property(nonatomic, nullable) NSError *receivedError;
-@end
-
-@implementation MockErrorFlutterResult
-
-- (void)sendError:(NSError *)error {
- _receivedError = error;
- [self.expectation fulfill];
-}
-
-@end
-
/// Expect that optional positive numbers can be parsed
@implementation CameraCreateWithMediaSettingsParseTests
-- (NSError *)failingTestWithArguments:(NSDictionary *)arguments {
+- (FlutterError *)failingTestWithArguments:(NSDictionary *)arguments {
CameraPlugin *camera = [[CameraPlugin alloc] initWithRegistry:nil messenger:nil];
XCTestExpectation *expectation = [self expectationWithDescription:@"Result finished"];
- MockErrorFlutterResult *resultObject =
- [[MockErrorFlutterResult alloc] initWithExpectation:expectation];
-
// Set up method call
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"create"
arguments:arguments];
- [camera createCameraOnSessionQueueWithCreateMethodCall:call result:resultObject];
+ __block id resultValue;
+ [camera createCameraOnSessionQueueWithCreateMethodCall:call
+ result:^(id _Nullable result) {
+ resultValue = result;
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:1 handler:nil];
// Verify the result
- NSError *receivedError = resultObject.receivedError;
- XCTAssertNotNil(receivedError);
- return receivedError;
+ XCTAssertNotNil(resultValue);
+ XCTAssertTrue([resultValue isKindOfClass:[FlutterError class]]);
+ return (FlutterError *)resultValue;
}
-- (NSError *)goodTestWithArguments:(NSDictionary *)arguments {
+- (void)goodTestWithArguments:(NSDictionary *)arguments {
CameraPlugin *camera = [[CameraPlugin alloc] initWithRegistry:nil messenger:nil];
XCTestExpectation *expectation = [self expectationWithDescription:@"Result finished"];
@@ -70,93 +58,82 @@
OCMStub([avCaptureSessionMock alloc]).andReturn(avCaptureSessionMock);
OCMStub([avCaptureSessionMock canSetSessionPreset:[OCMArg any]]).andReturn(YES);
- MockErrorFlutterResult *resultObject =
- [[MockErrorFlutterResult alloc] initWithExpectation:expectation];
-
// Set up method call
FlutterMethodCall *call = [FlutterMethodCall
methodCallWithMethodName:@"create"
arguments:@{@"resolutionPreset" : @"medium", @"enableAudio" : @(1)}];
- [camera createCameraOnSessionQueueWithCreateMethodCall:call result:resultObject];
+ __block id resultValue;
+ [camera createCameraOnSessionQueueWithCreateMethodCall:call
+ result:^(id _Nullable result) {
+ resultValue = result;
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:1 handler:nil];
// Verify the result
- NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult;
- XCTAssertNotNil(dictionaryResult);
+ XCTAssertNotNil(resultValue);
+ XCTAssertFalse([resultValue isKindOfClass:[FlutterError class]]);
+ NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
XCTAssert([[dictionaryResult allKeys] containsObject:@"cameraId"]);
-
- return resultObject.receivedError;
}
- (void)testCameraCreateWithMediaSettings_shouldRejectNegativeIntNumbers {
- id errorOrNil =
+ FlutterError *error =
[self failingTestWithArguments:@{@"fps" : @(-1), @"resolutionPreset" : @"medium"}];
- XCTAssertEqualObjects([errorOrNil localizedDescription], @"fps should be a positive number",
+ XCTAssertEqualObjects(error.message, @"fps should be a positive number",
"should reject negative int number");
}
- (void)testCameraCreateWithMediaSettings_shouldRejectNegativeFloatingPointNumbers {
- id errorOrNil =
+ FlutterError *error =
[self failingTestWithArguments:@{@"fps" : @(-3.7), @"resolutionPreset" : @"medium"}];
- XCTAssertEqualObjects([errorOrNil localizedDescription], @"fps should be a positive number",
+ XCTAssertEqualObjects(error.message, @"fps should be a positive number",
"should reject negative floating point number");
}
- (void)testCameraCreateWithMediaSettings_nanShouldBeParsedAsNil {
- id errorOrNil =
+ FlutterError *error =
[self failingTestWithArguments:@{@"fps" : @(NAN), @"resolutionPreset" : @"medium"}];
- XCTAssertEqualObjects([errorOrNil localizedDescription], @"fps should not be a nan",
- "should reject NAN");
+ XCTAssertEqualObjects(error.message, @"fps should not be a nan", "should reject NAN");
}
- (void)testCameraCreateWithMediaSettings_shouldNotRejectNilArguments {
- id errorOrNil = [self goodTestWithArguments:@{@"resolutionPreset" : @"medium"}];
- XCTAssertNil(errorOrNil, "should accept nil");
+ [self goodTestWithArguments:@{@"resolutionPreset" : @"medium"}];
}
- (void)testCameraCreateWithMediaSettings_shouldAcceptNull {
- id errorOrNil =
- [self goodTestWithArguments:@{@"fps" : [NSNull null], @"resolutionPreset" : @"medium"}];
- XCTAssertNil(errorOrNil, "should accept [NSNull null]");
+ [self goodTestWithArguments:@{@"fps" : [NSNull null], @"resolutionPreset" : @"medium"}];
}
- (void)testCameraCreateWithMediaSettings_shouldAcceptPositiveDecimalNumbers {
- id errorOrNil = [self goodTestWithArguments:@{@"fps" : @(5), @"resolutionPreset" : @"medium"}];
- XCTAssertNil(errorOrNil, "should parse positive int number");
+ [self goodTestWithArguments:@{@"fps" : @(5), @"resolutionPreset" : @"medium"}];
}
- (void)testCameraCreateWithMediaSettings_shouldAcceptPositiveFloatingPointNumbers {
- id errorOrNil = [self goodTestWithArguments:@{@"fps" : @(3.7), @"resolutionPreset" : @"medium"}];
- XCTAssertNil(errorOrNil, "should accept positive floating point number");
+ [self goodTestWithArguments:@{@"fps" : @(3.7), @"resolutionPreset" : @"medium"}];
}
- (void)testCameraCreateWithMediaSettings_shouldRejectWrongVideoBitrate {
- id errorOrNil =
+ FlutterError *error =
[self failingTestWithArguments:@{@"videoBitrate" : @(-1), @"resolutionPreset" : @"medium"}];
- XCTAssertEqualObjects([errorOrNil localizedDescription],
- @"videoBitrate should be a positive number",
+ XCTAssertEqualObjects(error.message, @"videoBitrate should be a positive number",
"should reject wrong video bitrate");
}
- (void)testCameraCreateWithMediaSettings_shouldRejectWrongAudioBitrate {
- id errorOrNil =
+ FlutterError *error =
[self failingTestWithArguments:@{@"audioBitrate" : @(-1), @"resolutionPreset" : @"medium"}];
- XCTAssertEqualObjects([errorOrNil localizedDescription],
- @"audioBitrate should be a positive number",
+ XCTAssertEqualObjects(error.message, @"audioBitrate should be a positive number",
"should reject wrong audio bitrate");
}
- (void)testCameraCreateWithMediaSettings_shouldAcceptGoodVideoBitrate {
- id errorOrNil =
- [self goodTestWithArguments:@{@"videoBitrate" : @(200000), @"resolutionPreset" : @"medium"}];
- XCTAssertNil(errorOrNil, "should accept good video bitrate");
+ [self goodTestWithArguments:@{@"videoBitrate" : @(200000), @"resolutionPreset" : @"medium"}];
}
- (void)testCameraCreateWithMediaSettings_shouldAcceptGoodAudioBitrate {
- id errorOrNil =
- [self goodTestWithArguments:@{@"audioBitrate" : @(32000), @"resolutionPreset" : @"medium"}];
- XCTAssertNil(errorOrNil, "should accept good audio bitrate");
+ [self goodTestWithArguments:@{@"audioBitrate" : @(32000), @"resolutionPreset" : @"medium"}];
}
@end
@@ -298,11 +275,9 @@
timeout:1
enforceOrder:YES];
- FLTThreadSafeFlutterResult *result =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:^(id result){
- }];
+ [camera startVideoRecordingWithResult:^(id _Nullable result){
- [camera startVideoRecordingWithResult:result];
+ }];
[self waitForExpectations:@[
injectedWrapper.audioSettingsExpectation, injectedWrapper.videoSettingsExpectation
@@ -324,9 +299,6 @@
OCMStub([avCaptureSessionMock alloc]).andReturn(avCaptureSessionMock);
OCMStub([avCaptureSessionMock canSetSessionPreset:[OCMArg any]]).andReturn(YES);
- MockFLTThreadSafeFlutterResult *resultObject =
- [[MockFLTThreadSafeFlutterResult alloc] initWithExpectation:expectation];
-
// Set up method call
FlutterMethodCall *call =
[FlutterMethodCall methodCallWithMethodName:@"create"
@@ -338,11 +310,16 @@
@"audioBitrate" : @(gTestAudioBitrate)
}];
- [camera createCameraOnSessionQueueWithCreateMethodCall:call result:resultObject];
+ __block id resultValue;
+ [camera createCameraOnSessionQueueWithCreateMethodCall:call
+ result:^(id _Nullable result) {
+ resultValue = result;
+ [expectation fulfill];
+ }];
[self waitForExpectationsWithTimeout:1 handler:nil];
// Verify the result
- NSDictionary *dictionaryResult = (NSDictionary *)resultObject.receivedResult;
+ NSDictionary *dictionaryResult = (NSDictionary *)resultValue;
XCTAssertNotNil(dictionaryResult);
XCTAssert([[dictionaryResult allKeys] containsObject:@"cameraId"]);
}
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h
index 1982be7..57c47ac 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/CameraTestUtils.h
@@ -3,6 +3,7 @@
// found in the LICENSE file.
@import camera_avfoundation;
+@import camera_avfoundation.Test;
NS_ASSUME_NONNULL_BEGIN
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamPhotoCaptureTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamPhotoCaptureTests.m
index f7204f2..00c583d 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamPhotoCaptureTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamPhotoCaptureTests.m
@@ -30,10 +30,6 @@
OCMStub([mockSettings photoSettings]).andReturn(settings);
NSError *error = [NSError errorWithDomain:@"test" code:0 userInfo:nil];
- id mockResult = OCMClassMock([FLTThreadSafeFlutterResult class]);
- OCMStub([mockResult sendError:error]).andDo(^(NSInvocation *invocation) {
- [errorExpectation fulfill];
- });
id mockOutput = OCMClassMock([AVCapturePhotoOutput class]);
OCMStub([mockOutput capturePhotoWithSettings:OCMOCK_ANY delegate:OCMOCK_ANY])
@@ -49,7 +45,10 @@
// `FLTCam::captureToFile` runs on capture session queue.
dispatch_async(captureSessionQueue, ^{
- [cam captureToFile:mockResult];
+ [cam captureToFile:^(id _Nullable result) {
+ XCTAssertTrue([result isKindOfClass:[FlutterError class]]);
+ [errorExpectation fulfill];
+ }];
});
[self waitForExpectationsWithTimeout:1 handler:nil];
@@ -70,10 +69,6 @@
OCMStub([mockSettings photoSettings]).andReturn(settings);
NSString *filePath = @"test";
- id mockResult = OCMClassMock([FLTThreadSafeFlutterResult class]);
- OCMStub([mockResult sendSuccessWithData:filePath]).andDo(^(NSInvocation *invocation) {
- [pathExpectation fulfill];
- });
id mockOutput = OCMClassMock([AVCapturePhotoOutput class]);
OCMStub([mockOutput capturePhotoWithSettings:OCMOCK_ANY delegate:OCMOCK_ANY])
@@ -89,7 +84,10 @@
// `FLTCam::captureToFile` runs on capture session queue.
dispatch_async(captureSessionQueue, ^{
- [cam captureToFile:mockResult];
+ [cam captureToFile:^(id _Nullable result) {
+ XCTAssertEqual(result, filePath);
+ [pathExpectation fulfill];
+ }];
});
[self waitForExpectationsWithTimeout:1 handler:nil];
}
@@ -110,14 +108,6 @@
id mockSettings = OCMClassMock([AVCapturePhotoSettings class]);
OCMStub([mockSettings photoSettingsWithFormat:OCMOCK_ANY]).andReturn(settings);
- id mockResult = OCMClassMock([FLTThreadSafeFlutterResult class]);
- OCMStub([mockResult sendSuccessWithData:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) {
- NSString *filePath;
- [invocation getArgument:&filePath atIndex:2];
- XCTAssertEqualObjects([filePath pathExtension], @"heif");
- [expectation fulfill];
- });
-
id mockOutput = OCMClassMock([AVCapturePhotoOutput class]);
// Set availablePhotoCodecTypes to HEVC
NSArray *codecTypes = @[ AVVideoCodecTypeHEVC ];
@@ -135,7 +125,11 @@
cam.capturePhotoOutput = mockOutput;
// `FLTCam::captureToFile` runs on capture session queue.
dispatch_async(captureSessionQueue, ^{
- [cam captureToFile:mockResult];
+ [cam captureToFile:^(id _Nullable result) {
+ NSString *filePath = (NSString *)result;
+ XCTAssertEqualObjects([filePath pathExtension], @"heif");
+ [expectation fulfill];
+ }];
});
[self waitForExpectationsWithTimeout:1 handler:nil];
}
@@ -154,14 +148,6 @@
id mockSettings = OCMClassMock([AVCapturePhotoSettings class]);
OCMStub([mockSettings photoSettings]).andReturn(settings);
- id mockResult = OCMClassMock([FLTThreadSafeFlutterResult class]);
- OCMStub([mockResult sendSuccessWithData:OCMOCK_ANY]).andDo(^(NSInvocation *invocation) {
- NSString *filePath;
- [invocation getArgument:&filePath atIndex:2];
- XCTAssertEqualObjects([filePath pathExtension], @"jpg");
- [expectation fulfill];
- });
-
id mockOutput = OCMClassMock([AVCapturePhotoOutput class]);
OCMStub([mockOutput capturePhotoWithSettings:OCMOCK_ANY delegate:OCMOCK_ANY])
@@ -176,7 +162,11 @@
cam.capturePhotoOutput = mockOutput;
// `FLTCam::captureToFile` runs on capture session queue.
dispatch_async(captureSessionQueue, ^{
- [cam captureToFile:mockResult];
+ [cam captureToFile:^(id _Nullable result) {
+ NSString *filePath = (NSString *)result;
+ XCTAssertEqualObjects([filePath pathExtension], @"jpg");
+ [expectation fulfill];
+ }];
});
[self waitForExpectationsWithTimeout:1 handler:nil];
}
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m
index 24e3544..9c036ad 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/FLTCamSampleBufferTests.m
@@ -54,15 +54,13 @@
[invocation setReturnValue:&status];
});
- FLTThreadSafeFlutterResult *result =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:^(id result){
- // no-op
- }];
-
// Pause then resume the recording.
- [cam startVideoRecordingWithResult:result];
- [cam pauseVideoRecordingWithResult:result];
- [cam resumeVideoRecordingWithResult:result];
+ [cam startVideoRecordingWithResult:^(id _Nullable result){
+ }];
+ [cam pauseVideoRecordingWithResult:^(id _Nullable result){
+ }];
+ [cam resumeVideoRecordingWithResult:^(id _Nullable result){
+ }];
[cam captureOutput:cam.captureVideoOutput
didOutputSampleBuffer:sampleBuffer
@@ -113,10 +111,8 @@
writtenSamples = [writtenSamples arrayByAddingObject:@"audio"];
});
- FLTThreadSafeFlutterResult *result =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:^(id result){
- }];
- [cam startVideoRecordingWithResult:result];
+ [cam startVideoRecordingWithResult:^(id _Nullable result){
+ }];
[cam captureOutput:nil didOutputSampleBuffer:audioSample fromConnection:connectionMock];
[cam captureOutput:nil didOutputSampleBuffer:audioSample fromConnection:connectionMock];
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/MockFLTThreadSafeFlutterResult.h b/packages/camera/camera_avfoundation/example/ios/RunnerTests/MockFLTThreadSafeFlutterResult.h
deleted file mode 100644
index 8685f3f..0000000
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/MockFLTThreadSafeFlutterResult.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MockFLTThreadSafeFlutterResult_h
-#define MockFLTThreadSafeFlutterResult_h
-
-/**
- * Extends FLTThreadSafeFlutterResult to give tests the ability to wait on the result and
- * read the received result.
- */
-@interface MockFLTThreadSafeFlutterResult : FLTThreadSafeFlutterResult
-@property(readonly, nonatomic, nonnull) XCTestExpectation *expectation;
-@property(nonatomic, nullable) id receivedResult;
-
-/**
- * Initializes the MockFLTThreadSafeFlutterResult with an expectation.
- *
- * The expectation is fullfilled when a result is called allowing tests to await the result in an
- * asynchronous manner.
- */
-- (nonnull instancetype)initWithExpectation:(nonnull XCTestExpectation *)expectation;
-@end
-
-#endif /* MockFLTThreadSafeFlutterResult_h */
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/MockFLTThreadSafeFlutterResult.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/MockFLTThreadSafeFlutterResult.m
deleted file mode 100644
index d3d7b6a..0000000
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/MockFLTThreadSafeFlutterResult.m
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-@import camera_avfoundation;
-@import XCTest;
-
-#import "MockFLTThreadSafeFlutterResult.h"
-
-@implementation MockFLTThreadSafeFlutterResult
-
-- (instancetype)initWithExpectation:(XCTestExpectation *)expectation {
- self = [super init];
- _expectation = expectation;
- return self;
-}
-
-- (void)sendSuccessWithData:(id)data {
- self.receivedResult = data;
- [self.expectation fulfill];
-}
-
-- (void)sendSuccess {
- self.receivedResult = nil;
- [self.expectation fulfill];
-}
-@end
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueUtilsTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueUtilsTests.m
index a9fc739..128b47b 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueUtilsTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/QueueUtilsTests.m
@@ -3,6 +3,7 @@
// found in the LICENSE file.
@import camera_avfoundation;
+@import camera_avfoundation.Test;
@import XCTest;
@interface QueueUtilsTests : XCTestCase
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeEventChannelTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeEventChannelTests.m
index 2aad7e3..e445697 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeEventChannelTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeEventChannelTests.m
@@ -3,6 +3,7 @@
// found in the LICENSE file.
@import camera_avfoundation;
+@import camera_avfoundation.Test;
@import XCTest;
#import <OCMock/OCMock.h>
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeFlutterResultTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeFlutterResultTests.m
deleted file mode 100644
index b8de19c..0000000
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeFlutterResultTests.m
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-@import camera_avfoundation;
-@import XCTest;
-
-@interface ThreadSafeFlutterResultTests : XCTestCase
-@end
-
-@implementation ThreadSafeFlutterResultTests
-- (void)testAsyncSendSuccess_ShouldCallResultOnMainThread {
- XCTestExpectation *expectation = [self expectationWithDescription:@"Result finished"];
-
- FLTThreadSafeFlutterResult *threadSafeFlutterResult =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:^(id _Nullable result) {
- XCTAssert(NSThread.isMainThread);
- [expectation fulfill];
- }];
- dispatch_queue_t dispatchQueue = dispatch_queue_create("test dispatchqueue", NULL);
- dispatch_async(dispatchQueue, ^{
- [threadSafeFlutterResult sendSuccess];
- });
-
- [self waitForExpectationsWithTimeout:1 handler:nil];
-}
-
-- (void)testSyncSendSuccess_ShouldCallResultOnMainThread {
- XCTestExpectation *expectation = [self expectationWithDescription:@"Result finished"];
-
- FLTThreadSafeFlutterResult *threadSafeFlutterResult =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:^(id _Nullable result) {
- XCTAssert(NSThread.isMainThread);
- [expectation fulfill];
- }];
- [threadSafeFlutterResult sendSuccess];
- [self waitForExpectationsWithTimeout:1 handler:nil];
-}
-
-- (void)testSendNotImplemented_ShouldSendNotImplementedToFlutterResult {
- XCTestExpectation *expectation = [self expectationWithDescription:@"Result finished"];
-
- FLTThreadSafeFlutterResult *threadSafeFlutterResult =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:^(id _Nullable result) {
- XCTAssert([result isKindOfClass:FlutterMethodNotImplemented.class]);
- [expectation fulfill];
- }];
- dispatch_queue_t dispatchQueue = dispatch_queue_create("test dispatchqueue", NULL);
- dispatch_async(dispatchQueue, ^{
- [threadSafeFlutterResult sendNotImplemented];
- });
-
- [self waitForExpectationsWithTimeout:1 handler:nil];
-}
-
-- (void)testSendErrorDetails_ShouldSendErrorToFlutterResult {
- NSString *errorCode = @"errorCode";
- NSString *errorMessage = @"message";
- NSString *errorDetails = @"error details";
- XCTestExpectation *expectation = [self expectationWithDescription:@"Result finished"];
-
- FLTThreadSafeFlutterResult *threadSafeFlutterResult =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:^(id _Nullable result) {
- XCTAssert([result isKindOfClass:FlutterError.class]);
- FlutterError *error = (FlutterError *)result;
- XCTAssertEqualObjects(error.code, errorCode);
- XCTAssertEqualObjects(error.message, errorMessage);
- XCTAssertEqualObjects(error.details, errorDetails);
- [expectation fulfill];
- }];
- dispatch_queue_t dispatchQueue = dispatch_queue_create("test dispatchqueue", NULL);
- dispatch_async(dispatchQueue, ^{
- [threadSafeFlutterResult sendErrorWithCode:errorCode message:errorMessage details:errorDetails];
- });
-
- [self waitForExpectationsWithTimeout:1 handler:nil];
-}
-
-- (void)testSendNSError_ShouldSendErrorToFlutterResult {
- NSError *originalError = [[NSError alloc] initWithDomain:NSURLErrorDomain code:404 userInfo:nil];
- XCTestExpectation *expectation = [self expectationWithDescription:@"Result finished"];
-
- FLTThreadSafeFlutterResult *threadSafeFlutterResult =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:^(id _Nullable result) {
- XCTAssert([result isKindOfClass:FlutterError.class]);
- FlutterError *error = (FlutterError *)result;
- NSString *constructedErrorCode =
- [NSString stringWithFormat:@"Error %d", (int)originalError.code];
- XCTAssertEqualObjects(error.code, constructedErrorCode);
- [expectation fulfill];
- }];
- dispatch_queue_t dispatchQueue = dispatch_queue_create("test dispatchqueue", NULL);
- dispatch_async(dispatchQueue, ^{
- [threadSafeFlutterResult sendError:originalError];
- });
-
- [self waitForExpectationsWithTimeout:1 handler:nil];
-}
-
-- (void)testSendResult_ShouldSendResultToFlutterResult {
- NSString *resultData = @"resultData";
- XCTestExpectation *expectation = [self expectationWithDescription:@"Result finished"];
-
- FLTThreadSafeFlutterResult *threadSafeFlutterResult =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:^(id _Nullable result) {
- XCTAssertEqualObjects(result, resultData);
- [expectation fulfill];
- }];
- dispatch_queue_t dispatchQueue = dispatch_queue_create("test dispatchqueue", NULL);
- dispatch_async(dispatchQueue, ^{
- [threadSafeFlutterResult sendSuccessWithData:resultData];
- });
-
- [self waitForExpectationsWithTimeout:1 handler:nil];
-}
-@end
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeMethodChannelTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeMethodChannelTests.m
index ce1b641..36e87db 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeMethodChannelTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeMethodChannelTests.m
@@ -3,6 +3,7 @@
// found in the LICENSE file.
@import camera_avfoundation;
+@import camera_avfoundation.Test;
@import XCTest;
#import <OCMock/OCMock.h>
diff --git a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeTextureRegistryTests.m b/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeTextureRegistryTests.m
index 31f196f..f91896b 100644
--- a/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeTextureRegistryTests.m
+++ b/packages/camera/camera_avfoundation/example/ios/RunnerTests/ThreadSafeTextureRegistryTests.m
@@ -3,6 +3,7 @@
// found in the LICENSE file.
@import camera_avfoundation;
+@import camera_avfoundation.Test;
@import XCTest;
#import <OCMock/OCMock.h>
diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.m b/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.m
index 243d727..ba29dbe 100644
--- a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.m
+++ b/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.m
@@ -11,11 +11,16 @@
#import "CameraProperties.h"
#import "FLTCam.h"
#import "FLTThreadSafeEventChannel.h"
-#import "FLTThreadSafeFlutterResult.h"
#import "FLTThreadSafeMethodChannel.h"
#import "FLTThreadSafeTextureRegistry.h"
#import "QueueUtils.h"
+static FlutterError *FlutterErrorFromNSError(NSError *error) {
+ return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %d", (int)error.code]
+ message:error.localizedDescription
+ details:error.domain];
+}
+
@interface CameraPlugin ()
@property(readonly, nonatomic) FLTThreadSafeTextureRegistry *registry;
@property(readonly, nonatomic) NSObject<FlutterBinaryMessenger> *messenger;
@@ -95,14 +100,11 @@
// Invoke the plugin on another dispatch queue to avoid blocking the UI.
__weak typeof(self) weakSelf = self;
dispatch_async(self.captureSessionQueue, ^{
- FLTThreadSafeFlutterResult *threadSafeResult =
- [[FLTThreadSafeFlutterResult alloc] initWithResult:result];
- [weakSelf handleMethodCallAsync:call result:threadSafeResult];
+ [weakSelf handleMethodCallAsync:call result:result];
});
}
-- (void)handleMethodCallAsync:(FlutterMethodCall *)call
- result:(FLTThreadSafeFlutterResult *)result {
+- (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)result {
if ([@"availableCameras" isEqualToString:call.method]) {
NSMutableArray *discoveryDevices =
[@[ AVCaptureDeviceTypeBuiltInWideAngleCamera, AVCaptureDeviceTypeBuiltInTelephotoCamera ]
@@ -136,18 +138,18 @@
@"sensorOrientation" : @90,
}];
}
- [result sendSuccessWithData:reply];
+ result(reply);
} else if ([@"create" isEqualToString:call.method]) {
[self handleCreateMethodCall:call result:result];
} else if ([@"startImageStream" isEqualToString:call.method]) {
[_camera startImageStreamWithMessenger:_messenger];
- [result sendSuccess];
+ result(nil);
} else if ([@"stopImageStream" isEqualToString:call.method]) {
[_camera stopImageStream];
- [result sendSuccess];
+ result(nil);
} else if ([@"receivedImageStreamData" isEqualToString:call.method]) {
[_camera receivedImageStreamData];
- [result sendSuccess];
+ result(nil);
} else {
NSDictionary *argsMap = call.arguments;
NSUInteger cameraId = ((NSNumber *)argsMap[@"cameraId"]).unsignedIntegerValue;
@@ -183,16 +185,16 @@
}];
[self sendDeviceOrientation:[UIDevice currentDevice].orientation];
[_camera start];
- [result sendSuccess];
+ result(nil);
} else if ([@"takePicture" isEqualToString:call.method]) {
[_camera captureToFile:result];
} else if ([@"dispose" isEqualToString:call.method]) {
[_registry unregisterTexture:cameraId];
[_camera close];
- [result sendSuccess];
+ result(nil);
} else if ([@"prepareForVideoRecording" isEqualToString:call.method]) {
[self.camera setUpCaptureSessionForAudio];
- [result sendSuccess];
+ result(nil);
} else if ([@"startVideoRecording" isEqualToString:call.method]) {
BOOL enableStream = [call.arguments[@"enableStream"] boolValue];
if (enableStream) {
@@ -227,11 +229,11 @@
}
[_camera setExposurePointWithResult:result x:x y:y];
} else if ([@"getMinExposureOffset" isEqualToString:call.method]) {
- [result sendSuccessWithData:@(_camera.captureDevice.minExposureTargetBias)];
+ result(@(_camera.captureDevice.minExposureTargetBias));
} else if ([@"getMaxExposureOffset" isEqualToString:call.method]) {
- [result sendSuccessWithData:@(_camera.captureDevice.maxExposureTargetBias)];
+ result(@(_camera.captureDevice.maxExposureTargetBias));
} else if ([@"getExposureOffsetStepSize" isEqualToString:call.method]) {
- [result sendSuccessWithData:@(0.0)];
+ result(@(0.0));
} else if ([@"setExposureOffset" isEqualToString:call.method]) {
[_camera setExposureOffsetWithResult:result
offset:((NSNumber *)call.arguments[@"offset"]).doubleValue];
@@ -260,13 +262,12 @@
NSString *fileFormat = call.arguments[@"fileFormat"];
[_camera setImageFileFormat:FCPGetFileFormatFromString(fileFormat)];
} else {
- [result sendNotImplemented];
+ result(FlutterMethodNotImplemented);
}
}
}
-- (void)handleCreateMethodCall:(FlutterMethodCall *)call
- result:(FLTThreadSafeFlutterResult *)result {
+- (void)handleCreateMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
// Create FLTCam only if granted camera access (and audio access if audio is enabled)
__weak typeof(self) weakSelf = self;
FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
@@ -274,7 +275,7 @@
if (!strongSelf) return;
if (error) {
- [result sendFlutterError:error];
+ result(error);
} else {
// Request audio permission on `create` call with `enableAudio` argument instead of the
// `prepareForVideoRecording` call. This is because `prepareForVideoRecording` call is
@@ -287,7 +288,7 @@
typeof(self) strongSelf = weakSelf;
if (!strongSelf) return;
if (error) {
- [result sendFlutterError:error];
+ result(error);
} else {
[strongSelf createCameraOnSessionQueueWithCreateMethodCall:call result:result];
}
@@ -353,7 +354,7 @@
}
- (void)createCameraOnSessionQueueWithCreateMethodCall:(FlutterMethodCall *)createMethodCall
- result:(FLTThreadSafeFlutterResult *)result {
+ result:(FlutterResult)result {
__weak typeof(self) weakSelf = self;
dispatch_async(self.captureSessionQueue, ^{
typeof(self) strongSelf = weakSelf;
@@ -367,7 +368,7 @@
fromMethod:createMethodCall
error:&error];
if (error) {
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
return;
}
@@ -375,7 +376,7 @@
fromMethod:createMethodCall
error:&error];
if (error) {
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
return;
}
@@ -383,7 +384,7 @@
fromMethod:createMethodCall
error:&error];
if (error) {
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
return;
}
@@ -406,7 +407,7 @@
error:&error];
if (error) {
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
} else {
if (strongSelf.camera) {
[strongSelf.camera close];
@@ -414,9 +415,9 @@
strongSelf.camera = cam;
[strongSelf.registry registerTexture:cam
completion:^(int64_t textureId) {
- [result sendSuccessWithData:@{
+ result(@{
@"cameraId" : @(textureId),
- }];
+ });
}];
}
});
diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.modulemap b/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.modulemap
index abdad1a..8de3cde 100644
--- a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.modulemap
+++ b/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin.modulemap
@@ -12,7 +12,6 @@
header "FLTCam_Test.h"
header "FLTSavePhotoDelegate_Test.h"
header "FLTThreadSafeEventChannel.h"
- header "FLTThreadSafeFlutterResult.h"
header "FLTThreadSafeMethodChannel.h"
header "FLTThreadSafeTextureRegistry.h"
header "QueueUtils.h"
diff --git a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin_Test.h b/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin_Test.h
index 230648f..97ccd48 100644
--- a/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin_Test.h
+++ b/packages/camera/camera_avfoundation/ios/Classes/CameraPlugin_Test.h
@@ -6,7 +6,6 @@
#import "CameraPlugin.h"
#import "FLTCam.h"
-#import "FLTThreadSafeFlutterResult.h"
/// APIs exposed for unit testing.
@interface CameraPlugin ()
@@ -34,7 +33,7 @@
/// @param call The method call command object.
/// @param result A wrapper around the `FlutterResult` callback which ensures the callback is called
/// on the main dispatch queue.
-- (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FLTThreadSafeFlutterResult *)result;
+- (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)result;
/// Called by the @c NSNotificationManager each time the device's orientation is changed.
///
@@ -46,5 +45,5 @@
/// @param createMethodCall the create method call
/// @param result a thread safe flutter result wrapper object to report creation result.
- (void)createCameraOnSessionQueueWithCreateMethodCall:(FlutterMethodCall *)createMethodCall
- result:(FLTThreadSafeFlutterResult *)result;
+ result:(FlutterResult)result;
@end
diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTCam.h b/packages/camera/camera_avfoundation/ios/Classes/FLTCam.h
index e1216fd..281ff14 100644
--- a/packages/camera/camera_avfoundation/ios/Classes/FLTCam.h
+++ b/packages/camera/camera_avfoundation/ios/Classes/FLTCam.h
@@ -10,7 +10,6 @@
#import "FLTCamMediaSettings.h"
#import "FLTCamMediaSettingsAVWrapper.h"
#import "FLTThreadSafeEventChannel.h"
-#import "FLTThreadSafeFlutterResult.h"
#import "FLTThreadSafeMethodChannel.h"
#import "FLTThreadSafeTextureRegistry.h"
@@ -52,26 +51,26 @@
- (void)start;
- (void)stop;
- (void)setDeviceOrientation:(UIDeviceOrientation)orientation;
-- (void)captureToFile:(FLTThreadSafeFlutterResult *)result;
+- (void)captureToFile:(FlutterResult)result;
- (void)close;
-- (void)startVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result;
+- (void)startVideoRecordingWithResult:(FlutterResult)result;
- (void)setImageFileFormat:(FCPFileFormat)fileFormat;
/// Starts recording a video with an optional streaming messenger.
/// If the messenger is non-null then it will be called for each
/// captured frame, allowing streaming concurrently with recording.
///
/// @param messenger Nullable messenger for capturing each frame.
-- (void)startVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result
+- (void)startVideoRecordingWithResult:(FlutterResult)result
messengerForStreaming:(nullable NSObject<FlutterBinaryMessenger> *)messenger;
-- (void)stopVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result;
-- (void)pauseVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result;
-- (void)resumeVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result;
-- (void)lockCaptureOrientationWithResult:(FLTThreadSafeFlutterResult *)result
+- (void)stopVideoRecordingWithResult:(FlutterResult)result;
+- (void)pauseVideoRecordingWithResult:(FlutterResult)result;
+- (void)resumeVideoRecordingWithResult:(FlutterResult)result;
+- (void)lockCaptureOrientationWithResult:(FlutterResult)result
orientation:(NSString *)orientationStr;
-- (void)unlockCaptureOrientationWithResult:(FLTThreadSafeFlutterResult *)result;
-- (void)setFlashModeWithResult:(FLTThreadSafeFlutterResult *)result mode:(NSString *)modeStr;
-- (void)setExposureModeWithResult:(FLTThreadSafeFlutterResult *)result mode:(NSString *)modeStr;
-- (void)setFocusModeWithResult:(FLTThreadSafeFlutterResult *)result mode:(NSString *)modeStr;
+- (void)unlockCaptureOrientationWithResult:(FlutterResult)result;
+- (void)setFlashModeWithResult:(FlutterResult)result mode:(NSString *)modeStr;
+- (void)setExposureModeWithResult:(FlutterResult)result mode:(NSString *)modeStr;
+- (void)setFocusModeWithResult:(FlutterResult)result mode:(NSString *)modeStr;
- (void)applyFocusMode;
/// Acknowledges the receipt of one image stream frame.
@@ -93,18 +92,17 @@
/// @param focusMode The focus mode that should be applied to the @captureDevice instance.
/// @param captureDevice The AVCaptureDevice to which the @focusMode will be applied.
- (void)applyFocusMode:(FLTFocusMode)focusMode onDevice:(AVCaptureDevice *)captureDevice;
-- (void)pausePreviewWithResult:(FLTThreadSafeFlutterResult *)result;
-- (void)resumePreviewWithResult:(FLTThreadSafeFlutterResult *)result;
-- (void)setDescriptionWhileRecording:(NSString *)cameraName
- result:(FLTThreadSafeFlutterResult *)result;
-- (void)setExposurePointWithResult:(FLTThreadSafeFlutterResult *)result x:(double)x y:(double)y;
-- (void)setFocusPointWithResult:(FLTThreadSafeFlutterResult *)result x:(double)x y:(double)y;
-- (void)setExposureOffsetWithResult:(FLTThreadSafeFlutterResult *)result offset:(double)offset;
+- (void)pausePreviewWithResult:(FlutterResult)result;
+- (void)resumePreviewWithResult:(FlutterResult)result;
+- (void)setDescriptionWhileRecording:(NSString *)cameraName result:(FlutterResult)result;
+- (void)setExposurePointWithResult:(FlutterResult)result x:(double)x y:(double)y;
+- (void)setFocusPointWithResult:(FlutterResult)result x:(double)x y:(double)y;
+- (void)setExposureOffsetWithResult:(FlutterResult)result offset:(double)offset;
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger;
- (void)stopImageStream;
-- (void)getMaxZoomLevelWithResult:(FLTThreadSafeFlutterResult *)result;
-- (void)getMinZoomLevelWithResult:(FLTThreadSafeFlutterResult *)result;
-- (void)setZoomLevel:(CGFloat)zoom Result:(FLTThreadSafeFlutterResult *)result;
+- (void)getMaxZoomLevelWithResult:(FlutterResult)result;
+- (void)getMinZoomLevelWithResult:(FlutterResult)result;
+- (void)setZoomLevel:(CGFloat)zoom Result:(FlutterResult)result;
- (void)setUpCaptureSessionForAudio;
@end
diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m b/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m
index b2f09e9..9544dbc 100644
--- a/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m
+++ b/packages/camera/camera_avfoundation/ios/Classes/FLTCam.m
@@ -10,6 +10,12 @@
@import CoreMotion;
#import <libkern/OSAtomic.h>
+static FlutterError *FlutterErrorFromNSError(NSError *error) {
+ return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %d", (int)error.code]
+ message:error.localizedDescription
+ details:error.domain];
+}
+
@implementation FLTImageStreamHandler
- (instancetype)initWithCaptureSessionQueue:(dispatch_queue_t)captureSessionQueue {
@@ -336,7 +342,7 @@
}
}
-- (void)captureToFile:(FLTThreadSafeFlutterResult *)result {
+- (void)captureToFile:(FlutterResult)result {
AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings];
if (_resolutionPreset == FLTResolutionPresetMax) {
@@ -366,7 +372,7 @@
prefix:@"CAP_"
error:error];
if (error) {
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
return;
}
@@ -385,10 +391,10 @@
});
if (error) {
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
} else {
NSAssert(path, @"Path must not be nil if no error.");
- [result sendSuccessWithData:path];
+ result(path);
}
}];
@@ -793,11 +799,11 @@
return pixelBuffer;
}
-- (void)startVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result {
+- (void)startVideoRecordingWithResult:(FlutterResult)result {
[self startVideoRecordingWithResult:result messengerForStreaming:nil];
}
-- (void)startVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result
+- (void)startVideoRecordingWithResult:(FlutterResult)result
messengerForStreaming:(nullable NSObject<FlutterBinaryMessenger> *)messenger {
if (!_isRecording) {
if (messenger != nil) {
@@ -810,11 +816,11 @@
prefix:@"REC_"
error:error];
if (error) {
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
return;
}
if (![self setupWriterForPath:_videoRecordingPath]) {
- [result sendErrorWithCode:@"IOError" message:@"Setup Writer Failed" details:nil];
+ result([FlutterError errorWithCode:@"IOError" message:@"Setup Writer Failed" details:nil]);
return;
}
_isRecording = YES;
@@ -823,13 +829,13 @@
_audioTimeOffset = CMTimeMake(0, 1);
_videoIsDisconnected = NO;
_audioIsDisconnected = NO;
- [result sendSuccess];
+ result(nil);
} else {
- [result sendErrorWithCode:@"Error" message:@"Video is already recording" details:nil];
+ result([FlutterError errorWithCode:@"Error" message:@"Video is already recording" details:nil]);
}
}
-- (void)stopVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result {
+- (void)stopVideoRecordingWithResult:(FlutterResult)result {
if (_isRecording) {
_isRecording = NO;
@@ -837,12 +843,12 @@
[_videoWriter finishWritingWithCompletionHandler:^{
if (self->_videoWriter.status == AVAssetWriterStatusCompleted) {
[self updateOrientation];
- [result sendSuccessWithData:self->_videoRecordingPath];
+ result(self->_videoRecordingPath);
self->_videoRecordingPath = nil;
} else {
- [result sendErrorWithCode:@"IOError"
- message:@"AVAssetWriter could not finish writing!"
- details:nil];
+ result([FlutterError errorWithCode:@"IOError"
+ message:@"AVAssetWriter could not finish writing!"
+ details:nil]);
}
}];
}
@@ -851,35 +857,35 @@
[NSError errorWithDomain:NSCocoaErrorDomain
code:NSURLErrorResourceUnavailable
userInfo:@{NSLocalizedDescriptionKey : @"Video is not recording!"}];
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
}
}
-- (void)pauseVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result {
+- (void)pauseVideoRecordingWithResult:(FlutterResult)result {
_isRecordingPaused = YES;
_videoIsDisconnected = YES;
_audioIsDisconnected = YES;
- [result sendSuccess];
+ result(nil);
}
-- (void)resumeVideoRecordingWithResult:(FLTThreadSafeFlutterResult *)result {
+- (void)resumeVideoRecordingWithResult:(FlutterResult)result {
_isRecordingPaused = NO;
- [result sendSuccess];
+ result(nil);
}
-- (void)lockCaptureOrientationWithResult:(FLTThreadSafeFlutterResult *)result
+- (void)lockCaptureOrientationWithResult:(FlutterResult)result
orientation:(NSString *)orientationStr {
UIDeviceOrientation orientation = FLTGetUIDeviceOrientationForString(orientationStr);
// "Unknown" should never be sent, so is used to represent an unexpected
// value.
if (orientation == UIDeviceOrientationUnknown) {
- [result sendError:[NSError errorWithDomain:NSCocoaErrorDomain
- code:NSURLErrorUnknown
- userInfo:@{
- NSLocalizedDescriptionKey : [NSString
- stringWithFormat:@"Unknown device orientation %@",
- orientationStr]
- }]];
+ result(FlutterErrorFromNSError([NSError
+ errorWithDomain:NSCocoaErrorDomain
+ code:NSURLErrorUnknown
+ userInfo:@{
+ NSLocalizedDescriptionKey :
+ [NSString stringWithFormat:@"Unknown device orientation %@", orientationStr]
+ }]));
return;
}
@@ -888,37 +894,38 @@
[self updateOrientation];
}
- [result sendSuccess];
+ result(nil);
}
-- (void)unlockCaptureOrientationWithResult:(FLTThreadSafeFlutterResult *)result {
+- (void)unlockCaptureOrientationWithResult:(FlutterResult)result {
_lockedCaptureOrientation = UIDeviceOrientationUnknown;
[self updateOrientation];
- [result sendSuccess];
+ result(nil);
}
-- (void)setFlashModeWithResult:(FLTThreadSafeFlutterResult *)result mode:(NSString *)modeStr {
+- (void)setFlashModeWithResult:(FlutterResult)result mode:(NSString *)modeStr {
FLTFlashMode mode = FLTGetFLTFlashModeForString(modeStr);
if (mode == FLTFlashModeInvalid) {
- [result sendError:[NSError errorWithDomain:NSCocoaErrorDomain
- code:NSURLErrorUnknown
- userInfo:@{
- NSLocalizedDescriptionKey : [NSString
- stringWithFormat:@"Unknown flash mode %@", modeStr]
- }]];
+ result(FlutterErrorFromNSError([NSError
+ errorWithDomain:NSCocoaErrorDomain
+ code:NSURLErrorUnknown
+ userInfo:@{
+ NSLocalizedDescriptionKey :
+ [NSString stringWithFormat:@"Unknown flash mode %@", modeStr]
+ }]));
return;
}
if (mode == FLTFlashModeTorch) {
if (!_captureDevice.hasTorch) {
- [result sendErrorWithCode:@"setFlashModeFailed"
- message:@"Device does not support torch mode"
- details:nil];
+ result([FlutterError errorWithCode:@"setFlashModeFailed"
+ message:@"Device does not support torch mode"
+ details:nil]);
return;
}
if (!_captureDevice.isTorchAvailable) {
- [result sendErrorWithCode:@"setFlashModeFailed"
- message:@"Torch mode is currently not available"
- details:nil];
+ result([FlutterError errorWithCode:@"setFlashModeFailed"
+ message:@"Torch mode is currently not available"
+ details:nil]);
return;
}
if (_captureDevice.torchMode != AVCaptureTorchModeOn) {
@@ -928,17 +935,17 @@
}
} else {
if (!_captureDevice.hasFlash) {
- [result sendErrorWithCode:@"setFlashModeFailed"
- message:@"Device does not have flash capabilities"
- details:nil];
+ result([FlutterError errorWithCode:@"setFlashModeFailed"
+ message:@"Device does not have flash capabilities"
+ details:nil]);
return;
}
AVCaptureFlashMode avFlashMode = FLTGetAVCaptureFlashModeForFLTFlashMode(mode);
if (![_capturePhotoOutput.supportedFlashModes
containsObject:[NSNumber numberWithInt:((int)avFlashMode)]]) {
- [result sendErrorWithCode:@"setFlashModeFailed"
- message:@"Device does not support this specific flash mode"
- details:nil];
+ result([FlutterError errorWithCode:@"setFlashModeFailed"
+ message:@"Device does not support this specific flash mode"
+ details:nil]);
return;
}
if (_captureDevice.torchMode != AVCaptureTorchModeOff) {
@@ -948,23 +955,24 @@
}
}
_flashMode = mode;
- [result sendSuccess];
+ result(nil);
}
-- (void)setExposureModeWithResult:(FLTThreadSafeFlutterResult *)result mode:(NSString *)modeStr {
+- (void)setExposureModeWithResult:(FlutterResult)result mode:(NSString *)modeStr {
FLTExposureMode mode = FLTGetFLTExposureModeForString(modeStr);
if (mode == FLTExposureModeInvalid) {
- [result sendError:[NSError errorWithDomain:NSCocoaErrorDomain
- code:NSURLErrorUnknown
- userInfo:@{
- NSLocalizedDescriptionKey : [NSString
- stringWithFormat:@"Unknown exposure mode %@", modeStr]
- }]];
+ result(FlutterErrorFromNSError([NSError
+ errorWithDomain:NSCocoaErrorDomain
+ code:NSURLErrorUnknown
+ userInfo:@{
+ NSLocalizedDescriptionKey :
+ [NSString stringWithFormat:@"Unknown exposure mode %@", modeStr]
+ }]));
return;
}
_exposureMode = mode;
[self applyExposureMode];
- [result sendSuccess];
+ result(nil);
}
- (void)applyExposureMode {
@@ -989,20 +997,21 @@
[_captureDevice unlockForConfiguration];
}
-- (void)setFocusModeWithResult:(FLTThreadSafeFlutterResult *)result mode:(NSString *)modeStr {
+- (void)setFocusModeWithResult:(FlutterResult)result mode:(NSString *)modeStr {
FLTFocusMode mode = FLTGetFLTFocusModeForString(modeStr);
if (mode == FLTFocusModeInvalid) {
- [result sendError:[NSError errorWithDomain:NSCocoaErrorDomain
- code:NSURLErrorUnknown
- userInfo:@{
- NSLocalizedDescriptionKey : [NSString
- stringWithFormat:@"Unknown focus mode %@", modeStr]
- }]];
+ result(FlutterErrorFromNSError([NSError
+ errorWithDomain:NSCocoaErrorDomain
+ code:NSURLErrorUnknown
+ userInfo:@{
+ NSLocalizedDescriptionKey :
+ [NSString stringWithFormat:@"Unknown focus mode %@", modeStr]
+ }]));
return;
}
_focusMode = mode;
[self applyFocusMode];
- [result sendSuccess];
+ result(nil);
}
- (void)applyFocusMode {
@@ -1033,22 +1042,21 @@
[captureDevice unlockForConfiguration];
}
-- (void)pausePreviewWithResult:(FLTThreadSafeFlutterResult *)result {
+- (void)pausePreviewWithResult:(FlutterResult)result {
_isPreviewPaused = true;
- [result sendSuccess];
+ result(nil);
}
-- (void)resumePreviewWithResult:(FLTThreadSafeFlutterResult *)result {
+- (void)resumePreviewWithResult:(FlutterResult)result {
_isPreviewPaused = false;
- [result sendSuccess];
+ result(nil);
}
-- (void)setDescriptionWhileRecording:(NSString *)cameraName
- result:(FLTThreadSafeFlutterResult *)result {
+- (void)setDescriptionWhileRecording:(NSString *)cameraName result:(FlutterResult)result {
if (!_isRecording) {
- [result sendErrorWithCode:@"setDescriptionWhileRecordingFailed"
- message:@"Device was not recording"
- details:nil];
+ result([FlutterError errorWithCode:@"setDescriptionWhileRecordingFailed"
+ message:@"Device was not recording"
+ details:nil]);
return;
}
@@ -1068,7 +1076,7 @@
NSError *error = nil;
AVCaptureConnection *newConnection = [self createConnection:&error];
if (error) {
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
return;
}
@@ -1079,17 +1087,23 @@
// Add the new connections to the session.
if (![_videoCaptureSession canAddInput:_captureVideoInput])
- [result sendErrorWithCode:@"VideoError" message:@"Unable switch video input" details:nil];
+ result([FlutterError errorWithCode:@"VideoError"
+ message:@"Unable switch video input"
+ details:nil]);
[_videoCaptureSession addInputWithNoConnections:_captureVideoInput];
if (![_videoCaptureSession canAddOutput:_captureVideoOutput])
- [result sendErrorWithCode:@"VideoError" message:@"Unable switch video output" details:nil];
+ result([FlutterError errorWithCode:@"VideoError"
+ message:@"Unable switch video output"
+ details:nil]);
[_videoCaptureSession addOutputWithNoConnections:_captureVideoOutput];
if (![_videoCaptureSession canAddConnection:newConnection])
- [result sendErrorWithCode:@"VideoError" message:@"Unable switch video connection" details:nil];
+ result([FlutterError errorWithCode:@"VideoError"
+ message:@"Unable switch video connection"
+ details:nil]);
[_videoCaptureSession addConnection:newConnection];
[_videoCaptureSession commitConfiguration];
- [result sendSuccess];
+ result(nil);
}
- (CGPoint)getCGPointForCoordsWithOrientation:(UIDeviceOrientation)orientation
@@ -1117,11 +1131,11 @@
return CGPointMake(x, y);
}
-- (void)setExposurePointWithResult:(FLTThreadSafeFlutterResult *)result x:(double)x y:(double)y {
+- (void)setExposurePointWithResult:(FlutterResult)result x:(double)x y:(double)y {
if (!_captureDevice.isExposurePointOfInterestSupported) {
- [result sendErrorWithCode:@"setExposurePointFailed"
- message:@"Device does not have exposure point capabilities"
- details:nil];
+ result([FlutterError errorWithCode:@"setExposurePointFailed"
+ message:@"Device does not have exposure point capabilities"
+ details:nil]);
return;
}
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
@@ -1132,14 +1146,14 @@
[_captureDevice unlockForConfiguration];
// Retrigger auto exposure
[self applyExposureMode];
- [result sendSuccess];
+ result(nil);
}
-- (void)setFocusPointWithResult:(FLTThreadSafeFlutterResult *)result x:(double)x y:(double)y {
+- (void)setFocusPointWithResult:(FlutterResult)result x:(double)x y:(double)y {
if (!_captureDevice.isFocusPointOfInterestSupported) {
- [result sendErrorWithCode:@"setFocusPointFailed"
- message:@"Device does not have focus point capabilities"
- details:nil];
+ result([FlutterError errorWithCode:@"setFocusPointFailed"
+ message:@"Device does not have focus point capabilities"
+ details:nil]);
return;
}
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
@@ -1151,14 +1165,14 @@
[_captureDevice unlockForConfiguration];
// Retrigger auto focus
[self applyFocusMode];
- [result sendSuccess];
+ result(nil);
}
-- (void)setExposureOffsetWithResult:(FLTThreadSafeFlutterResult *)result offset:(double)offset {
+- (void)setExposureOffsetWithResult:(FlutterResult)result offset:(double)offset {
[_captureDevice lockForConfiguration:nil];
[_captureDevice setExposureTargetBias:offset completionHandler:nil];
[_captureDevice unlockForConfiguration];
- [result sendSuccessWithData:@(offset)];
+ result(@(offset));
}
- (void)startImageStreamWithMessenger:(NSObject<FlutterBinaryMessenger> *)messenger {
@@ -1211,18 +1225,18 @@
self.streamingPendingFramesCount--;
}
-- (void)getMaxZoomLevelWithResult:(FLTThreadSafeFlutterResult *)result {
+- (void)getMaxZoomLevelWithResult:(FlutterResult)result {
CGFloat maxZoomFactor = [self getMaxAvailableZoomFactor];
- [result sendSuccessWithData:[NSNumber numberWithFloat:maxZoomFactor]];
+ result([NSNumber numberWithFloat:maxZoomFactor]);
}
-- (void)getMinZoomLevelWithResult:(FLTThreadSafeFlutterResult *)result {
+- (void)getMinZoomLevelWithResult:(FlutterResult)result {
CGFloat minZoomFactor = [self getMinAvailableZoomFactor];
- [result sendSuccessWithData:[NSNumber numberWithFloat:minZoomFactor]];
+ result([NSNumber numberWithFloat:minZoomFactor]);
}
-- (void)setZoomLevel:(CGFloat)zoom Result:(FLTThreadSafeFlutterResult *)result {
+- (void)setZoomLevel:(CGFloat)zoom Result:(FlutterResult)result {
CGFloat maxAvailableZoomFactor = [self getMaxAvailableZoomFactor];
CGFloat minAvailableZoomFactor = [self getMinAvailableZoomFactor];
@@ -1231,19 +1245,19 @@
stringWithFormat:@"Zoom level out of bounds (zoom level should be between %f and %f).",
minAvailableZoomFactor, maxAvailableZoomFactor];
- [result sendErrorWithCode:@"ZOOM_ERROR" message:errorMessage details:nil];
+ result([FlutterError errorWithCode:@"ZOOM_ERROR" message:errorMessage details:nil]);
return;
}
NSError *error = nil;
if (![_captureDevice lockForConfiguration:&error]) {
- [result sendError:error];
+ result(FlutterErrorFromNSError(error));
return;
}
_captureDevice.videoZoomFactor = zoom;
[_captureDevice unlockForConfiguration];
- [result sendSuccess];
+ result(nil);
}
- (CGFloat)getMinAvailableZoomFactor {
diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate.h b/packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate.h
index cec35d2..1b3cbca 100644
--- a/packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate.h
+++ b/packages/camera/camera_avfoundation/ios/Classes/FLTSavePhotoDelegate.h
@@ -3,10 +3,9 @@
// found in the LICENSE file.
@import AVFoundation;
+@import Flutter;
@import Foundation;
-#import "FLTThreadSafeFlutterResult.h"
-
NS_ASSUME_NONNULL_BEGIN
/// The completion handler block for save photo operations.
diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeFlutterResult.h b/packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeFlutterResult.h
deleted file mode 100644
index 09c4f43..0000000
--- a/packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeFlutterResult.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Flutter/Flutter.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-/// A thread safe wrapper for FlutterResult that can be called from any thread, by dispatching its
-/// underlying engine calls to the main thread.
-@interface FLTThreadSafeFlutterResult : NSObject
-
-/// Gets the original FlutterResult object wrapped by this FLTThreadSafeFlutterResult instance.
-@property(readonly, nonatomic) FlutterResult flutterResult;
-
-/// Initializes with a FlutterResult object.
-/// @param result The FlutterResult object that the result will be given to.
-- (instancetype)initWithResult:(FlutterResult)result;
-
-/// Sends a successful result on the main thread without any data.
-- (void)sendSuccess;
-
-/// Sends a successful result on the main thread with data.
-/// @param data Result data that is send to the Flutter Dart side.
-- (void)sendSuccessWithData:(id)data;
-
-/// Sends an NSError as result on the main thread.
-/// @param error Error that will be send as FlutterError.
-- (void)sendError:(NSError *)error;
-
-/// Sends a FlutterError as result on the main thread.
-/// @param flutterError FlutterError that will be sent to the Flutter Dart side.
-- (void)sendFlutterError:(FlutterError *)flutterError;
-
-/// Sends a FlutterError as result on the main thread.
-- (void)sendErrorWithCode:(NSString *)code
- message:(nullable NSString *)message
- details:(nullable id)details;
-
-/// Sends FlutterMethodNotImplemented as result on the main thread.
-- (void)sendNotImplemented;
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeFlutterResult.m b/packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeFlutterResult.m
deleted file mode 100644
index ee636cd..0000000
--- a/packages/camera/camera_avfoundation/ios/Classes/FLTThreadSafeFlutterResult.m
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2013 The Flutter Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "FLTThreadSafeFlutterResult.h"
-#import <Foundation/Foundation.h>
-#import "QueueUtils.h"
-
-@implementation FLTThreadSafeFlutterResult {
-}
-
-- (id)initWithResult:(FlutterResult)result {
- self = [super init];
- if (!self) {
- return nil;
- }
- _flutterResult = result;
- return self;
-}
-
-- (void)sendSuccess {
- [self send:nil];
-}
-
-- (void)sendSuccessWithData:(id)data {
- [self send:data];
-}
-
-- (void)sendError:(NSError *)error {
- [self sendErrorWithCode:[NSString stringWithFormat:@"Error %d", (int)error.code]
- message:error.localizedDescription
- details:error.domain];
-}
-
-- (void)sendErrorWithCode:(NSString *)code
- message:(NSString *_Nullable)message
- details:(id _Nullable)details {
- FlutterError *flutterError = [FlutterError errorWithCode:code message:message details:details];
- [self send:flutterError];
-}
-
-- (void)sendFlutterError:(FlutterError *)flutterError {
- [self send:flutterError];
-}
-
-- (void)sendNotImplemented {
- [self send:FlutterMethodNotImplemented];
-}
-
-/// Sends result to flutterResult on the main thread.
-- (void)send:(id _Nullable)result {
- FLTEnsureToRunOnMainQueue(^{
- // WARNING: Should not use weak self, because `FlutterResult`s are passed as arguments
- // (retained within call stack, but not in the heap). FLTEnsureToRunOnMainQueue may trigger a
- // context switch (when calling from background thread), in which case using weak self will
- // always result in a nil self. Alternative to using strong self, we can also create a local
- // strong variable to be captured by this block.
- self.flutterResult(result);
- });
-}
-
-@end
diff --git a/packages/camera/camera_avfoundation/pubspec.yaml b/packages/camera/camera_avfoundation/pubspec.yaml
index 1757aaf..82b804b 100644
--- a/packages/camera/camera_avfoundation/pubspec.yaml
+++ b/packages/camera/camera_avfoundation/pubspec.yaml
@@ -2,7 +2,7 @@
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.15
+version: 0.9.15+1
environment:
sdk: ^3.2.3