Skip to content

Commit e1c5ca3

Browse files
committed
Support multiple attachments
This change adds support for multiple attachments, allowing callers to create share extensions that can select more than one item to share.
1 parent 66d3a72 commit e1c5ca3

2 files changed

Lines changed: 83 additions & 57 deletions

File tree

ios/ReactNativeShareExtension.m

Lines changed: 82 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -39,69 +39,94 @@ - (void)viewDidLoad {
3939
completionHandler:nil];
4040
}
4141

42-
43-
4442
RCT_REMAP_METHOD(data,
4543
resolver:(RCTPromiseResolveBlock)resolve
4644
rejecter:(RCTPromiseRejectBlock)reject)
4745
{
48-
[self extractDataFromContext: extensionContext withCallback:^(NSURL* url,NSString* contentType ,NSException* err) {
49-
NSDictionary *inventory = @{
50-
@"type": contentType,
51-
@"value": [url absoluteString]
52-
};
53-
54-
resolve(inventory);
55-
}];
46+
[self extractDataFromContext: extensionContext withCallback:^(NSArray* items ,NSException* err) {
47+
if (items == nil) {
48+
resolve(nil);
49+
return;
50+
}
51+
resolve(items[0]);
52+
}];
5653
}
5754

58-
- (void)extractDataFromContext:(NSExtensionContext *)context withCallback:(void(^)(NSURL *url, NSString* contentType ,NSException *exception))callback {
59-
@try {
60-
NSExtensionItem *item = [context.inputItems firstObject];
61-
NSArray *attachments = item.attachments;
62-
__block NSItemProvider *urlProvider = nil;
63-
__block NSItemProvider *imageProvider = nil;
64-
[attachments enumerateObjectsUsingBlock:^(NSItemProvider *provider, NSUInteger idx, BOOL *stop) {
65-
if([provider hasItemConformingToTypeIdentifier:ITEM_IDENTIFIER]) {
66-
urlProvider = provider;
67-
*stop = YES;
68-
}else if ([provider hasItemConformingToTypeIdentifier:IMAGE_IDENTIFIER]){
69-
imageProvider = provider;
70-
*stop = YES;
71-
72-
}
73-
}];
74-
75-
if(urlProvider) {
76-
[urlProvider loadItemForTypeIdentifier:ITEM_IDENTIFIER options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
77-
NSURL *url = (NSURL *)item;
78-
79-
if(callback) {
80-
callback(url,@"text/plain" ,nil);
81-
}
82-
}];
83-
}else if (imageProvider){
84-
[imageProvider loadItemForTypeIdentifier:IMAGE_IDENTIFIER options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
85-
NSURL *url = (NSURL *)item;
86-
87-
if(callback) {
88-
callback(url,[[[url absoluteString] pathExtension] lowercaseString] ,nil);
89-
}
90-
}];
91-
92-
93-
}
94-
else {
95-
if(callback) {
96-
callback(nil, nil,[NSException exceptionWithName:@"Error" reason:@"couldn't find provider" userInfo:nil]);
97-
}
98-
}
99-
}
100-
@catch (NSException *exception) {
101-
if(callback) {
102-
callback(nil,nil ,exception);
103-
}
104-
}
55+
RCT_REMAP_METHOD(dataMulti,
56+
resolverMulti:(RCTPromiseResolveBlock)resolve
57+
rejecterMulti:(RCTPromiseRejectBlock)reject)
58+
{
59+
[self extractDataFromContext: extensionContext withCallback:^(NSArray* items ,NSException* err) {
60+
resolve(items);
61+
}];
62+
}
63+
64+
typedef void (^ProviderCallback)(NSURL *url, NSString *contentType, NSException *exception);
65+
66+
- (void)extractDataFromContext:(NSExtensionContext *)context withCallback:(void(^)(NSArray *items ,NSException *exception))callback {
67+
@try {
68+
NSExtensionItem *item = [context.inputItems firstObject];
69+
NSArray *attachments = item.attachments;
70+
NSMutableArray *items = [[NSMutableArray alloc] init];
71+
72+
__block int attachmentIdx = 0;
73+
__block ProviderCallback providerCb = nil;
74+
providerCb = ^ void (NSURL *url, NSString *contentType, NSException *exception) {
75+
if (exception) {
76+
callback(nil, exception);
77+
return;
78+
}
79+
80+
[items addObject:@{
81+
@"type": contentType,
82+
@"value": [url absoluteString]
83+
}];
84+
85+
++attachmentIdx;
86+
if (attachmentIdx == [attachments count]) {
87+
callback(items, nil);
88+
} else {
89+
[self extractDataFromProvider:attachments[attachmentIdx] withCallback: providerCb];
90+
}
91+
};
92+
[self extractDataFromProvider:attachments[0] withCallback: providerCb];
93+
}
94+
@catch (NSException *exception) {
95+
callback(nil,exception);
96+
}
97+
}
98+
99+
- (void)extractDataFromProvider:(NSItemProvider *)provider withCallback:(void(^)(NSURL* url, NSString* contentType ,NSException *exception))callback {
100+
NSItemProvider *urlProvider = nil;
101+
NSItemProvider *imageProvider = nil;
102+
103+
if([provider hasItemConformingToTypeIdentifier:ITEM_IDENTIFIER]) {
104+
urlProvider = provider;
105+
}else if ([provider hasItemConformingToTypeIdentifier:IMAGE_IDENTIFIER]){
106+
imageProvider = provider;
107+
}
108+
109+
if(urlProvider) {
110+
[urlProvider loadItemForTypeIdentifier:ITEM_IDENTIFIER options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
111+
NSURL *url = (NSURL *)item;
112+
113+
if(callback) {
114+
callback(url,@"text/plain" ,nil);
115+
}
116+
}];
117+
}else if (imageProvider){
118+
[imageProvider loadItemForTypeIdentifier:IMAGE_IDENTIFIER options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
119+
NSURL *url = (NSURL *)item;
120+
121+
if(callback) {
122+
callback(url,[[[url absoluteString] pathExtension] lowercaseString] ,nil);
123+
}
124+
}];
125+
} else {
126+
if(callback) {
127+
callback(nil, nil,[NSException exceptionWithName:@"Error" reason:@"couldn't find provider" userInfo:nil]);
128+
}
129+
}
105130
}
106131

107132
@end

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ import { NativeModules } from 'react-native'
55
// NativeModules.ShareExtension.close()
66
export default {
77
data: () => NativeModules.ReactNativeShareExtension.data(),
8+
dataMulti: () => NativeModules.ReactNativeShareExtension.dataMulti(),
89
close: () => NativeModules.ReactNativeShareExtension.close()
910
}

0 commit comments

Comments
 (0)