-
Notifications
You must be signed in to change notification settings - Fork 397
Expand file tree
/
Copy pathReactNativeShareExtension.m
More file actions
142 lines (113 loc) · 5.12 KB
/
ReactNativeShareExtension.m
File metadata and controls
142 lines (113 loc) · 5.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#import "ReactNativeShareExtension.h"
#import "React/RCTRootView.h"
#import <MobileCoreServices/MobileCoreServices.h>
#define URL_IDENTIFIER @"public.url"
#define IMAGE_IDENTIFIER @"public.image"
#define TEXT_IDENTIFIER (NSString *)kUTTypePlainText
NSExtensionContext* extensionContext;
@implementation ReactNativeShareExtension {
NSTimer *autoTimer;
NSString* type;
NSString* value;
}
- (UIView*) shareView {
return nil;
}
RCT_EXPORT_MODULE();
- (void)viewDidLoad {
[super viewDidLoad];
//object variable for extension doesn't work for react-native. It must be assign to gloabl
//variable extensionContext. in this way, both exported method can touch extensionContext
extensionContext = self.extensionContext;
UIView *rootView = [self shareView];
if (rootView.backgroundColor == nil) {
rootView.backgroundColor = [[UIColor alloc] initWithRed:1 green:1 blue:1 alpha:0.1];
}
self.view = rootView;
}
RCT_EXPORT_METHOD(close) {
[extensionContext completeRequestReturningItems:nil
completionHandler:nil];
}
RCT_REMAP_METHOD(data,
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
[self extractDataFromContext: extensionContext withCallback:^(NSString* val, NSString* contentType, NSException* err) {
if(err) {
reject(@"error", err.description, nil);
} else {
resolve(@{
@"type": contentType,
@"value": val
});
}
}];
}
- (void)extractDataFromContext:(NSExtensionContext *)context withCallback:(void(^)(NSString *value, NSString* contentType, NSException *exception))callback {
@try {
NSExtensionItem *item = [context.inputItems firstObject];
NSArray *attachments = item.attachments;
__block NSItemProvider *urlProvider = nil;
__block NSItemProvider *imageProvider = nil;
__block NSItemProvider *textProvider = nil;
[attachments enumerateObjectsUsingBlock:^(NSItemProvider *provider, NSUInteger idx, BOOL *stop) {
if([provider hasItemConformingToTypeIdentifier:URL_IDENTIFIER]) {
urlProvider = provider;
} else if ([provider hasItemConformingToTypeIdentifier:TEXT_IDENTIFIER]){
textProvider = provider;
} else if ([provider hasItemConformingToTypeIdentifier:IMAGE_IDENTIFIER]){
imageProvider = provider;
}
}];
if(urlProvider) {
[urlProvider loadItemForTypeIdentifier:URL_IDENTIFIER options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
NSURL *url = (NSURL *)item;
if(callback) {
callback([url absoluteString], @"text/plain", nil);
}
}];
} else if (imageProvider) {
[imageProvider loadItemForTypeIdentifier:IMAGE_IDENTIFIER options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
/**
* Save the image to NSTemporaryDirectory(), which cleans itself tri-daily.
* This is necessary as the iOS 11 screenshot editor gives us a UIImage, while
* sharing from Photos and similar apps gives us a URL
* Therefore the solution is to save a UIImage, either way, and return the local path to that temp UIImage
* This path will be sent to React Native and can be processed and accessed RN side.
**/
UIImage *sharedImage;
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"RNSE_TEMP_IMG"];
NSString *fullPath = [filePath stringByAppendingPathExtension:@"png"];
if ([(NSObject *)item isKindOfClass:[UIImage class]]){
sharedImage = (UIImage *)item;
}else if ([(NSObject *)item isKindOfClass:[NSURL class]]){
NSURL* url = (NSURL *)item;
NSData *data = [NSData dataWithContentsOfURL:url];
sharedImage = [UIImage imageWithData:data];
}
[UIImagePNGRepresentation(sharedImage) writeToFile:fullPath atomically:YES];
if(callback) {
callback(fullPath, [fullPath pathExtension], nil);
}
}];
} else if (textProvider) {
[textProvider loadItemForTypeIdentifier:TEXT_IDENTIFIER options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
NSString *text = (NSString *)item;
if(callback) {
callback(text, @"text/plain", nil);
}
}];
} else {
if(callback) {
callback(nil, nil, [NSException exceptionWithName:@"Error" reason:@"couldn't find provider" userInfo:nil]);
}
}
}
@catch (NSException *exception) {
if(callback) {
callback(nil, nil, exception);
}
}
}
@end