mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add Search Web to selection controls on iOS (flutter/engine#43324)
In native iOS, users are able to select text and initiate a web search on the selected text. Specifically, this will launch a search using the users selected default search engine. Apple provides a custom url scheme in the form of "x-web-search://?[term]" which will automatically launch a search using the user's preferred browser in Safari. Additionally, this also correctly handles the country code top level domain eg. a user with a selected region in the UK with a preferred Google search engine will automatically have the .co.uk domain appended to the end of the search. This PR is the engine portion of the changes that will allow Search Web to be implemented This PR addresses https://github.com/flutter/flutter/issues/82907 More details are available in this [design doc](https://github.com/flutter/engine/pull/flutter.dev/go/add-missing-features-to-selection-controls)
This commit is contained in:
parent
64028157f8
commit
7ee4615b80
@ -16,6 +16,7 @@ namespace {
|
||||
|
||||
constexpr char kTextPlainFormat[] = "text/plain";
|
||||
const UInt32 kKeyPressClickSoundId = 1306;
|
||||
const NSString* searchURLPrefix = @"x-web-search://?";
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -115,6 +116,9 @@ using namespace flutter;
|
||||
result([self clipboardHasStrings]);
|
||||
} else if ([method isEqualToString:@"LiveText.isLiveTextInputAvailable"]) {
|
||||
result(@([self isLiveTextInputAvailable]));
|
||||
} else if ([method isEqualToString:@"SearchWeb.invoke"]) {
|
||||
[self searchWeb:args];
|
||||
result(nil);
|
||||
} else if ([method isEqualToString:@"LookUp.invoke"]) {
|
||||
[self showLookUpViewController:args];
|
||||
result(nil);
|
||||
@ -123,6 +127,17 @@ using namespace flutter;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)searchWeb:(NSString*)searchTerm {
|
||||
NSString* escapedText = [searchTerm
|
||||
stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet
|
||||
URLHostAllowedCharacterSet]];
|
||||
NSString* searchURL = [NSString stringWithFormat:@"%@%@", searchURLPrefix, escapedText];
|
||||
|
||||
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:searchURL]
|
||||
options:@{}
|
||||
completionHandler:nil];
|
||||
}
|
||||
|
||||
- (void)playSystemSound:(NSString*)soundType {
|
||||
if ([soundType isEqualToString:@"SystemSoundType.click"]) {
|
||||
// All feedback types are specific to Android and are treated as equal on
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
@interface FlutterPlatformPlugin ()
|
||||
- (BOOL)isLiveTextInputAvailable;
|
||||
- (void)searchWeb:(NSString*)searchTerm;
|
||||
- (void)showLookUpViewController:(NSString*)term;
|
||||
@end
|
||||
|
||||
@ -27,6 +28,30 @@
|
||||
@end
|
||||
|
||||
@implementation FlutterPlatformPluginTest
|
||||
- (void)testSearchWebInvoked {
|
||||
FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
|
||||
std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
|
||||
std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
|
||||
[engine runWithEntrypoint:nil];
|
||||
|
||||
XCTestExpectation* invokeExpectation =
|
||||
[self expectationWithDescription:@"Web search launched with search term"];
|
||||
|
||||
FlutterPlatformPlugin* plugin =
|
||||
[[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
|
||||
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
|
||||
|
||||
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"SearchWeb.invoke"
|
||||
arguments:@"Test"];
|
||||
|
||||
FlutterResult result = ^(id result) {
|
||||
OCMVerify([mockPlugin searchWeb:@"Test"]);
|
||||
[invokeExpectation fulfill];
|
||||
};
|
||||
|
||||
[mockPlugin handleMethodCall:methodCall result:result];
|
||||
[self waitForExpectationsWithTimeout:1 handler:nil];
|
||||
}
|
||||
|
||||
- (void)testLookUpCallInitiated {
|
||||
FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user