diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm index 257cb4420c776..23264b5cf61c6 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm @@ -267,8 +267,9 @@ - (NSDictionary*)getClipboardData:(NSString*)format { - (void)setClipboardData:(NSDictionary*)data { UIPasteboard* pasteboard = [UIPasteboard generalPasteboard]; - if (data[@"text"]) { - pasteboard.string = data[@"text"]; + id copyText = data[@"text"]; + if ([copyText isKindOfClass:[NSString class]]) { + pasteboard.string = copyText; } else { pasteboard.string = @"null"; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm index 23c7d2f942aee..f5fbdf33524a6 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm @@ -16,37 +16,71 @@ @interface FlutterPlatformPluginTest : XCTestCase @implementation FlutterPlatformPluginTest -- (void)testHasStrings { +- (void)testClipboardHasCorrectStrings { + [UIPasteboard generalPasteboard].string = nil; FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; std::unique_ptr> _weakFactory = std::make_unique>(engine); FlutterPlatformPlugin* plugin = [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()]; - // Set some string to the pasteboard. - __block bool calledSet = false; + XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setString"]; FlutterResult resultSet = ^(id result) { - calledSet = true; + [setStringExpectation fulfill]; }; FlutterMethodCall* methodCallSet = - [FlutterMethodCall methodCallWithMethodName:@"Clipboard.setClipboardData" + [FlutterMethodCall methodCallWithMethodName:@"Clipboard.setData" arguments:@{@"text" : @"some string"}]; [plugin handleMethodCall:methodCallSet result:resultSet]; - XCTAssertEqual(calledSet, true); + [self waitForExpectationsWithTimeout:1 handler:nil]; - // Call hasStrings and expect it to be true. - __block bool called = false; - __block bool value; + XCTestExpectation* hasStringsExpectation = [self expectationWithDescription:@"hasStrings"]; FlutterResult result = ^(id result) { - called = true; - value = result[@"value"]; + XCTAssertTrue([result[@"value"] boolValue]); + [hasStringsExpectation fulfill]; }; FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil]; [plugin handleMethodCall:methodCall result:result]; + [self waitForExpectationsWithTimeout:1 handler:nil]; + + XCTestExpectation* getDataExpectation = [self expectationWithDescription:@"getData"]; + FlutterResult getDataResult = ^(id result) { + XCTAssertEqualObjects(result[@"text"], @"some string"); + [getDataExpectation fulfill]; + }; + FlutterMethodCall* methodCallGetData = + [FlutterMethodCall methodCallWithMethodName:@"Clipboard.getData" arguments:@"text/plain"]; + [plugin handleMethodCall:methodCallGetData result:getDataResult]; + [self waitForExpectationsWithTimeout:1 handler:nil]; +} + +- (void)testClipboardSetDataToNullDoNotCrash { + [UIPasteboard generalPasteboard].string = nil; + FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil]; + std::unique_ptr> _weakFactory = + std::make_unique>(engine); + FlutterPlatformPlugin* plugin = + [[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()]; - XCTAssertEqual(called, true); - XCTAssertEqual(value, true); + XCTestExpectation* setStringExpectation = [self expectationWithDescription:@"setData"]; + FlutterResult resultSet = ^(id result) { + [setStringExpectation fulfill]; + }; + FlutterMethodCall* methodCallSet = + [FlutterMethodCall methodCallWithMethodName:@"Clipboard.setData" + arguments:@{@"text" : [NSNull null]}]; + [plugin handleMethodCall:methodCallSet result:resultSet]; + + XCTestExpectation* getDataExpectation = [self expectationWithDescription:@"getData"]; + FlutterResult result = ^(id result) { + XCTAssertEqualObjects(result[@"text"], @"null"); + [getDataExpectation fulfill]; + }; + FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Clipboard.getData" + arguments:@"text/plain"]; + [plugin handleMethodCall:methodCall result:result]; + [self waitForExpectationsWithTimeout:1 handler:nil]; } - (void)testPopSystemNavigator { @@ -66,14 +100,14 @@ - (void)testPopSystemNavigator { id navigationControllerMock = OCMPartialMock(navigationController); OCMStub([navigationControllerMock popViewControllerAnimated:YES]); // Set some string to the pasteboard. - __block bool calledSet = false; + XCTestExpectation* navigationPopCalled = [self expectationWithDescription:@"SystemNavigator.pop"]; FlutterResult resultSet = ^(id result) { - calledSet = true; + [navigationPopCalled fulfill]; }; FlutterMethodCall* methodCallSet = [FlutterMethodCall methodCallWithMethodName:@"SystemNavigator.pop" arguments:@(YES)]; [plugin handleMethodCall:methodCallSet result:resultSet]; - XCTAssertEqual(calledSet, true); + [self waitForExpectationsWithTimeout:1 handler:nil]; OCMVerify([navigationControllerMock popViewControllerAnimated:YES]); }