Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 9fae689

Browse files
authored
Add share to selection controls (#44554)
In native iOS, users are able to select text and initiate a share menu, which provides several standard services, such as copy, sharing to social media, direct ability to send to various contacts through messaging apps, etc. https://github.com/flutter/engine/assets/36148254/d0af7034-31fd-412e-8636-a06bbff54765 This PR is the engine portion of the changes that will allow Share to be implemented This PR addresses flutter/flutter#107578 More details are available in this [design doc](https://github.com/flutter/engine/pull/flutter.dev/go/add-missing-features-to-selection-controls)
1 parent bf175fd commit 9fae689

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,23 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
123123
} else if ([method isEqualToString:@"LookUp.invoke"]) {
124124
[self showLookUpViewController:args];
125125
result(nil);
126+
} else if ([method isEqualToString:@"Share.invoke"]) {
127+
[self showShareViewController:args];
128+
result(nil);
126129
} else {
127130
result(FlutterMethodNotImplemented);
128131
}
129132
}
130133

134+
- (void)showShareViewController:(NSString*)content {
135+
UIViewController* engineViewController = [_engine.get() viewController];
136+
NSArray* itemsToShare = @[ content ];
137+
UIActivityViewController* activityViewController =
138+
[[[UIActivityViewController alloc] initWithActivityItems:itemsToShare
139+
applicationActivities:nil] autorelease];
140+
[engineViewController presentViewController:activityViewController animated:YES completion:nil];
141+
}
142+
131143
- (void)searchWeb:(NSString*)searchTerm {
132144
NSString* escapedText = [searchTerm
133145
stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet
@@ -338,7 +350,6 @@ - (BOOL)isLiveTextInputAvailable {
338350

339351
- (void)showLookUpViewController:(NSString*)term {
340352
UIViewController* engineViewController = [_engine.get() viewController];
341-
FML_DCHECK(![engineViewController presentingViewController]);
342353
UIReferenceLibraryViewController* referenceLibraryViewController =
343354
[[[UIReferenceLibraryViewController alloc] initWithTerm:term] autorelease];
344355
[engineViewController presentViewController:referenceLibraryViewController

shell/platform/darwin/ios/framework/Source/FlutterPlatformPluginTest.mm

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ @interface FlutterPlatformPlugin ()
1919
- (BOOL)isLiveTextInputAvailable;
2020
- (void)searchWeb:(NSString*)searchTerm;
2121
- (void)showLookUpViewController:(NSString*)term;
22+
- (void)showShareViewController:(NSString*)content;
2223
@end
2324

2425
@interface UIViewController ()
@@ -122,6 +123,36 @@ - (void)testLookUpCallInitiated {
122123
[self waitForExpectationsWithTimeout:2 handler:nil];
123124
}
124125

126+
- (void)testShareScreenInvoked {
127+
FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];
128+
[engine runWithEntrypoint:nil];
129+
std::unique_ptr<fml::WeakPtrFactory<FlutterEngine>> _weakFactory =
130+
std::make_unique<fml::WeakPtrFactory<FlutterEngine>>(engine);
131+
132+
XCTestExpectation* presentExpectation =
133+
[self expectationWithDescription:@"Share view controller presented"];
134+
135+
FlutterViewController* engineViewController =
136+
[[[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil] autorelease];
137+
FlutterViewController* mockEngineViewController = OCMPartialMock(engineViewController);
138+
139+
FlutterPlatformPlugin* plugin =
140+
[[[FlutterPlatformPlugin alloc] initWithEngine:_weakFactory->GetWeakPtr()] autorelease];
141+
FlutterPlatformPlugin* mockPlugin = OCMPartialMock(plugin);
142+
143+
FlutterMethodCall* methodCall = [FlutterMethodCall methodCallWithMethodName:@"Share.invoke"
144+
arguments:@"Test"];
145+
FlutterResult result = ^(id result) {
146+
OCMVerify([mockEngineViewController
147+
presentViewController:[OCMArg isKindOfClass:[UIActivityViewController class]]
148+
animated:YES
149+
completion:nil]);
150+
[presentExpectation fulfill];
151+
};
152+
[mockPlugin handleMethodCall:methodCall result:result];
153+
[self waitForExpectationsWithTimeout:1 handler:nil];
154+
}
155+
125156
- (void)testClipboardHasCorrectStrings {
126157
[UIPasteboard generalPasteboard].string = nil;
127158
FlutterEngine* engine = [[[FlutterEngine alloc] initWithName:@"test" project:nil] autorelease];

0 commit comments

Comments
 (0)