Skip to content

Commit 73186a2

Browse files
committed
iOS support excludedActivityTypes
thaks:fluttercommunity#3376
1 parent b269c56 commit 73186a2

File tree

7 files changed

+137
-13
lines changed

7 files changed

+137
-13
lines changed

packages/share_plus/share_plus/example/ios/Runner/AppDelegate.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import UIKit
22
import Flutter
33

4-
@UIApplicationMain
4+
@main
55
@objc class AppDelegate: FlutterAppDelegate {
66
override func application(
77
_ application: UIApplication,

packages/share_plus/share_plus/ios/share_plus/Sources/share_plus/FPPSharePlusPlugin.m

+74-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,59 @@
3939
return viewController;
4040
}
4141

42+
static NSDictionary *activityTypes;
43+
44+
static void initializeActivityTypeMapping(void) {
45+
static dispatch_once_t onceToken;
46+
dispatch_once(&onceToken, ^{
47+
NSMutableDictionary *originalTypes =
48+
[[NSMutableDictionary alloc] initWithDictionary:@{
49+
@"postToFacebook" : UIActivityTypePostToFacebook,
50+
@"postToTwitter" : UIActivityTypePostToTwitter,
51+
@"postToWeibo" : UIActivityTypePostToWeibo,
52+
@"message" : UIActivityTypeMessage,
53+
@"mail" : UIActivityTypeMail,
54+
@"print" : UIActivityTypePrint,
55+
@"copyToPasteboard" : UIActivityTypeCopyToPasteboard,
56+
@"assignToContact" : UIActivityTypeAssignToContact,
57+
@"saveToCameraRoll" : UIActivityTypeSaveToCameraRoll,
58+
@"addToReadingList" : UIActivityTypeAddToReadingList,
59+
@"postToFlickr" : UIActivityTypePostToFlickr,
60+
@"postToVimeo" : UIActivityTypePostToVimeo,
61+
@"postToTencentWeibo" : UIActivityTypePostToTencentWeibo,
62+
@"airDrop" : UIActivityTypeAirDrop,
63+
@"openInIBooks" : UIActivityTypeOpenInIBooks,
64+
@"markupAsPDF" : UIActivityTypeMarkupAsPDF,
65+
}];
66+
67+
if (@available(iOS 15.4, *)) {
68+
originalTypes[@"sharePlay"] = UIActivityTypeSharePlay;
69+
}
70+
71+
if (@available(iOS 16.0, *)) {
72+
originalTypes[@"collaborationInviteWithLink"] =
73+
UIActivityTypeCollaborationInviteWithLink;
74+
}
75+
76+
if (@available(iOS 16.0, *)) {
77+
originalTypes[@"collaborationCopyLink"] =
78+
UIActivityTypeCollaborationCopyLink;
79+
}
80+
if (@available(iOS 16.4, *)) {
81+
originalTypes[@"addToHomeScreen"] = UIActivityTypeAddToHomeScreen;
82+
}
83+
activityTypes = originalTypes;
84+
});
85+
}
86+
87+
static UIActivityType activityTypeForString(NSString *activityTypeString) {
88+
initializeActivityTypeMapping();
89+
if ([activityTypes.allKeys containsObject:activityTypeString]) {
90+
return activityTypes[activityTypeString];
91+
}
92+
return nil;
93+
}
94+
4295
// We need the companion to avoid ARC deadlock
4396
@interface UIActivityViewSuccessCompanion : NSObject
4497

@@ -254,7 +307,16 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
254307
NSNumber *originY = arguments[@"originY"];
255308
NSNumber *originWidth = arguments[@"originWidth"];
256309
NSNumber *originHeight = arguments[@"originHeight"];
257-
310+
NSArray *rawExcludedActivityTypes = arguments[@"excludedActivityTypes"];
311+
NSMutableArray *excludedActivityTypes = [[NSMutableArray alloc] init];
312+
if (rawExcludedActivityTypes && rawExcludedActivityTypes.count > 0) {
313+
for (NSString *type in rawExcludedActivityTypes) {
314+
UIActivityType activityType = activityTypeForString(type);
315+
if (activityType != nil) {
316+
[excludedActivityTypes addObject:activityType];
317+
}
318+
}
319+
}
258320
CGRect originRect = CGRectZero;
259321
if (originX && originY && originWidth && originHeight) {
260322
originRect =
@@ -285,6 +347,7 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
285347

286348
[self shareText:shareText
287349
subject:shareSubject
350+
excludedActivityTypes:excludedActivityTypes
288351
withController:topViewController
289352
atSource:originRect
290353
toResult:result];
@@ -323,6 +386,7 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
323386
withMimeType:mimeTypes
324387
withSubject:subject
325388
withText:text
389+
excludedActivityTypes:excludedActivityTypes
326390
withController:topViewController
327391
atSource:originRect
328392
toResult:result];
@@ -347,6 +411,7 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
347411
TopViewControllerForViewController(rootViewController);
348412

349413
[self shareUri:uri
414+
excludedActivityTypes:excludedActivityTypes
350415
withController:topViewController
351416
atSource:originRect
352417
toResult:result];
@@ -358,6 +423,7 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
358423

359424
+ (void)share:(NSArray *)shareItems
360425
withSubject:(NSString *)subject
426+
excludedActivityTypes:(NSMutableArray *)excludedActivityTypes
361427
withController:(UIViewController *)controller
362428
atSource:(CGRect)origin
363429
toResult:(FlutterResult)result {
@@ -369,6 +435,7 @@ + (void)share:(NSArray *)shareItems
369435
if (![subject isKindOfClass:[NSNull class]]) {
370436
[activityViewController setValue:subject forKey:@"subject"];
371437
}
438+
activityViewController.excludedActivityTypes = excludedActivityTypes;
372439

373440
activityViewController.popoverPresentationController.sourceView =
374441
controller.view;
@@ -413,26 +480,30 @@ + (void)share:(NSArray *)shareItems
413480
}
414481

415482
+ (void)shareUri:(NSString *)uri
483+
excludedActivityTypes:excludedActivityTypes
416484
withController:(UIViewController *)controller
417485
atSource:(CGRect)origin
418486
toResult:(FlutterResult)result {
419487
NSURL *data = [NSURL URLWithString:uri];
420488
[self share:@[ data ]
421489
withSubject:nil
490+
excludedActivityTypes:excludedActivityTypes
422491
withController:controller
423492
atSource:origin
424493
toResult:result];
425494
}
426495

427496
+ (void)shareText:(NSString *)shareText
428497
subject:(NSString *)subject
498+
excludedActivityTypes:excludedActivityTypes
429499
withController:(UIViewController *)controller
430500
atSource:(CGRect)origin
431501
toResult:(FlutterResult)result {
432502
NSObject *data = [[SharePlusData alloc] initWithSubject:subject
433503
text:shareText];
434504
[self share:@[ data ]
435505
withSubject:subject
506+
excludedActivityTypes:excludedActivityTypes
436507
withController:controller
437508
atSource:origin
438509
toResult:result];
@@ -442,6 +513,7 @@ + (void)shareFiles:(NSArray *)paths
442513
withMimeType:(NSArray *)mimeTypes
443514
withSubject:(NSString *)subject
444515
withText:(NSString *)text
516+
excludedActivityTypes:(NSMutableArray *)excludedActivityTypes
445517
withController:(UIViewController *)controller
446518
atSource:(CGRect)origin
447519
toResult:(FlutterResult)result {
@@ -461,6 +533,7 @@ + (void)shareFiles:(NSArray *)paths
461533

462534
[self share:items
463535
withSubject:subject
536+
excludedActivityTypes:excludedActivityTypes
464537
withController:controller
465538
atSource:origin
466539
toResult:result];

packages/share_plus/share_plus/lib/share_plus.dart

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export 'package:share_plus_platform_interface/share_plus_platform_interface.dart
1414
XFile,
1515
PlatformOptions,
1616
AndroidIntentOptions,
17+
CupertinoActivityType,
1718
AndroidIntentFlag;
1819

1920
export 'src/share_plus_linux.dart';

packages/share_plus/share_plus_platform_interface/lib/method_channel/method_channel_share.dart

+29-10
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class MethodChannelShare extends SharePlatform {
3333
final params = <String, dynamic>{'uri': uri.toString()};
3434

3535
_addSharePositionOriginParams(params, sharePositionOrigin);
36-
_addAndroidPlatformParams(params, platformOptions);
36+
_addPlatformParams(params, platformOptions);
3737

3838
final result = await channel.invokeMethod<String>('shareUri', params) ??
3939
'dev.fluttercommunity.plus/share/unavailable';
@@ -56,7 +56,7 @@ class MethodChannelShare extends SharePlatform {
5656
};
5757

5858
_addSharePositionOriginParams(params, sharePositionOrigin);
59-
_addAndroidPlatformParams(params, platformOptions);
59+
_addPlatformParams(params, platformOptions);
6060

6161
final result = await channel.invokeMethod<String>('share', params) ??
6262
'dev.fluttercommunity.plus/share/unavailable';
@@ -99,7 +99,7 @@ class MethodChannelShare extends SharePlatform {
9999
if (text != null) params['text'] = text;
100100

101101
_addSharePositionOriginParams(params, sharePositionOrigin);
102-
_addAndroidPlatformParams(params, platformOptions);
102+
_addPlatformParams(params, platformOptions);
103103

104104
final result = await channel.invokeMethod<String>('shareFiles', params) ??
105105
'dev.fluttercommunity.plus/share/unavailable';
@@ -185,6 +185,22 @@ class MethodChannelShare extends SharePlatform {
185185
}
186186
}
187187

188+
void _addSharePositionOriginParams(
189+
Map<String, dynamic> params, Rect? sharePositionOrigin) {
190+
if (sharePositionOrigin != null) {
191+
params['originX'] = sharePositionOrigin.left;
192+
params['originY'] = sharePositionOrigin.top;
193+
params['originWidth'] = sharePositionOrigin.width;
194+
params['originHeight'] = sharePositionOrigin.height;
195+
}
196+
}
197+
198+
void _addPlatformParams(
199+
Map<String, dynamic> params, PlatformOptions? platformOptions) {
200+
_addAndroidPlatformParams(params, platformOptions);
201+
_addCupertinoPlatformParams(params, platformOptions);
202+
}
203+
188204
void _addAndroidPlatformParams(
189205
Map<String, dynamic> params, PlatformOptions? platformOptions) {
190206
if (defaultTargetPlatform != TargetPlatform.android) {
@@ -198,13 +214,16 @@ class MethodChannelShare extends SharePlatform {
198214
}
199215
}
200216

201-
void _addSharePositionOriginParams(
202-
Map<String, dynamic> params, Rect? sharePositionOrigin) {
203-
if (sharePositionOrigin != null) {
204-
params['originX'] = sharePositionOrigin.left;
205-
params['originY'] = sharePositionOrigin.top;
206-
params['originWidth'] = sharePositionOrigin.width;
207-
params['originHeight'] = sharePositionOrigin.height;
217+
void _addCupertinoPlatformParams(
218+
Map<String, dynamic> params, PlatformOptions? platformOptions) {
219+
if (defaultTargetPlatform != TargetPlatform.iOS) {
220+
return;
221+
}
222+
final iosExcludedActivityTypes = platformOptions?.cupertinoExcludedActivityTypes;
223+
if (iosExcludedActivityTypes?.isNotEmpty != true) {
224+
return;
208225
}
226+
params['excludedActivityTypes'] =
227+
iosExcludedActivityTypes?.map((e) => e.name).toList();
209228
}
210229
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
/// An abstract class that you subclass to implement app-specific services
3+
/// for iOS and macOS.
4+
///
5+
/// https://developer.apple.com/documentation/uikit/uiactivity/activitytype
6+
enum CupertinoActivityType {
7+
postToFacebook,
8+
postToTwitter,
9+
postToWeibo,
10+
message,
11+
mail,
12+
print,
13+
copyToPasteboard,
14+
assignToContact,
15+
saveToCameraRoll,
16+
addToReadingList,
17+
postToFlickr,
18+
postToVimeo,
19+
postToTencentWeibo,
20+
airDrop,
21+
openInIBooks,
22+
markupAsPDF,
23+
sharePlay,
24+
collaborationInviteWithLink,
25+
collaborationCopyLink,
26+
addToHomeScreen,
27+
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import 'android_intent_options.dart';
2+
import 'cupertino_activity_type.dart';
23

34
class PlatformOptions {
45
AndroidIntentOptions? androidIntentOptions;
56

6-
PlatformOptions({this.androidIntentOptions});
7+
List<CupertinoActivityType>? cupertinoExcludedActivityTypes;
8+
9+
PlatformOptions({this.androidIntentOptions,this.cupertinoExcludedActivityTypes});
710
}

packages/share_plus/share_plus_platform_interface/lib/share_plus_platform_interface.dart

+1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ export 'package:cross_file/cross_file.dart';
66
export 'platform_interface/share_plus_platform.dart';
77
export 'package:share_plus_platform_interface/options/platform_options.dart';
88
export 'package:share_plus_platform_interface/options/android_intent_options.dart';
9+
export 'package:share_plus_platform_interface/options/cupertino_activity_type.dart';
910
export 'package:share_plus_platform_interface/options/android_intent_flag.dart';

0 commit comments

Comments
 (0)