react-native-notify-kit 10.3.1 → 10.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/dist/templates/templates/NotificationService.swift.tmpl +33 -6
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/ios/NotifeeCore/NotifeeCore+NSURLSession.m +20 -3
- package/ios/NotifeeCore/NotifeeCore.m +2 -1
- package/ios/NotifeeCore/NotifeeCoreExtensionHelper.h +2 -2
- package/ios/NotifeeCore/NotifeeCoreExtensionHelper.m +138 -32
- package/ios/NotifeeCore/NotifeeCoreUtil.m +13 -5
- package/package.json +1 -1
- package/src/version.ts +1 -1
|
@@ -23,13 +23,21 @@ private func requestedAttachmentURLs(from userInfo: [AnyHashable: Any]) -> [Stri
|
|
|
23
23
|
class NotificationService: UNNotificationServiceExtension {
|
|
24
24
|
var contentHandler: ((UNNotificationContent) -> Void)?
|
|
25
25
|
var bestAttemptContent: UNMutableNotificationContent?
|
|
26
|
+
private let deliveryLock = NSLock()
|
|
27
|
+
private var didDeliver = false
|
|
26
28
|
|
|
27
29
|
override func didReceive(
|
|
28
30
|
_ request: UNNotificationRequest,
|
|
29
31
|
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
|
|
30
32
|
) {
|
|
33
|
+
let mutableContent = request.content.mutableCopy() as? UNMutableNotificationContent
|
|
34
|
+
|
|
35
|
+
deliveryLock.lock()
|
|
36
|
+
didDeliver = false
|
|
31
37
|
self.contentHandler = contentHandler
|
|
32
|
-
self.bestAttemptContent =
|
|
38
|
+
self.bestAttemptContent = mutableContent
|
|
39
|
+
deliveryLock.unlock()
|
|
40
|
+
|
|
33
41
|
let requestedAttachmentUrls = requestedAttachmentURLs(from: request.content.userInfo)
|
|
34
42
|
|
|
35
43
|
nseLog(
|
|
@@ -39,9 +47,9 @@ class NotificationService: UNNotificationServiceExtension {
|
|
|
39
47
|
"urls=\(requestedAttachmentUrls.joined(separator: ","))"
|
|
40
48
|
)
|
|
41
49
|
|
|
42
|
-
guard let bestAttemptContent =
|
|
50
|
+
guard let bestAttemptContent = mutableContent else {
|
|
43
51
|
nseLog("mutableCopy failed for id=\(request.identifier); delivering original content")
|
|
44
|
-
|
|
52
|
+
deliverOnce(request.content)
|
|
45
53
|
return
|
|
46
54
|
}
|
|
47
55
|
|
|
@@ -55,19 +63,38 @@ class NotificationService: UNNotificationServiceExtension {
|
|
|
55
63
|
"deliveredAttachments=\(content.attachments.count) " +
|
|
56
64
|
"identifiers=\(deliveredAttachmentIds)"
|
|
57
65
|
)
|
|
58
|
-
self?.
|
|
66
|
+
self?.deliverOnce(content)
|
|
59
67
|
}
|
|
60
68
|
)
|
|
61
69
|
}
|
|
62
70
|
|
|
71
|
+
private func deliverOnce(_ content: UNNotificationContent) {
|
|
72
|
+
var handler: ((UNNotificationContent) -> Void)?
|
|
73
|
+
|
|
74
|
+
deliveryLock.lock()
|
|
75
|
+
if !didDeliver {
|
|
76
|
+
didDeliver = true
|
|
77
|
+
handler = contentHandler
|
|
78
|
+
contentHandler = nil
|
|
79
|
+
bestAttemptContent = nil
|
|
80
|
+
}
|
|
81
|
+
deliveryLock.unlock()
|
|
82
|
+
|
|
83
|
+
handler?(content)
|
|
84
|
+
}
|
|
85
|
+
|
|
63
86
|
override func serviceExtensionTimeWillExpire() {
|
|
64
|
-
|
|
87
|
+
deliveryLock.lock()
|
|
88
|
+
let content = bestAttemptContent
|
|
89
|
+
deliveryLock.unlock()
|
|
90
|
+
|
|
91
|
+
if let bestAttemptContent = content {
|
|
65
92
|
nseLog(
|
|
66
93
|
"serviceExtensionTimeWillExpire id=\(bestAttemptContent.userInfo["gcm.message_id"] ?? "n/a") " +
|
|
67
94
|
"title=\(bestAttemptContent.title) " +
|
|
68
95
|
"deliveredAttachments=\(bestAttemptContent.attachments.count)"
|
|
69
96
|
)
|
|
70
|
-
|
|
97
|
+
deliverOnce(bestAttemptContent)
|
|
71
98
|
}
|
|
72
99
|
}
|
|
73
100
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "10.3.
|
|
1
|
+
export declare const version = "10.3.2";
|
package/dist/version.js
CHANGED
|
@@ -18,18 +18,35 @@
|
|
|
18
18
|
#import "NotifeeCore+NSURLSession.h"
|
|
19
19
|
#import "NotifeeCoreDownloadDelegate.h"
|
|
20
20
|
|
|
21
|
+
static NSTimeInterval const kNotifeeAttachmentDownloadTimeoutInterval = 25.0;
|
|
22
|
+
|
|
21
23
|
@implementation NotifeeCoreNSURLSession
|
|
22
24
|
|
|
25
|
+
+ (NSURLSessionConfiguration *)attachmentDownloadSessionConfiguration {
|
|
26
|
+
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
|
|
27
|
+
config.timeoutIntervalForRequest = kNotifeeAttachmentDownloadTimeoutInterval;
|
|
28
|
+
config.timeoutIntervalForResource = kNotifeeAttachmentDownloadTimeoutInterval;
|
|
29
|
+
return config;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
+ (nullable NSString *)fileExtensionFromSuggestedFilename:(nullable NSString *)suggestedFilename {
|
|
33
|
+
NSString *suggestedPathExtension = [suggestedFilename pathExtension];
|
|
34
|
+
if (suggestedPathExtension.length == 0) {
|
|
35
|
+
return nil;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return [NSString stringWithFormat:@".%@", suggestedPathExtension];
|
|
39
|
+
}
|
|
40
|
+
|
|
23
41
|
+ (NSString *)downloadItemAtURL:(NSURL *)url toFile:(NSString *)localPath error:(NSError **)error {
|
|
24
42
|
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
|
|
43
|
+
request.timeoutInterval = kNotifeeAttachmentDownloadTimeoutInterval;
|
|
25
44
|
|
|
26
45
|
NotifeeCoreDownloadDelegate *delegate =
|
|
27
46
|
[[NotifeeCoreDownloadDelegate alloc] initWithFilePath:localPath];
|
|
28
47
|
|
|
29
|
-
// The session is created with the defaultSessionConfiguration
|
|
30
|
-
// default timeoutIntervalForRequest is 60 seconds.
|
|
31
48
|
NSURLSession *session =
|
|
32
|
-
[NSURLSession sessionWithConfiguration:[
|
|
49
|
+
[NSURLSession sessionWithConfiguration:[self attachmentDownloadSessionConfiguration]
|
|
33
50
|
delegate:delegate
|
|
34
51
|
delegateQueue:nil];
|
|
35
52
|
|
|
@@ -1191,7 +1191,8 @@ typedef NS_ENUM(NSInteger, NotifeeCoreRollingErrorCode) {
|
|
|
1191
1191
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
1192
1192
|
BOOL isApplicationActive = NO;
|
|
1193
1193
|
if (![NotifeeCoreUtil isAppExtension]) {
|
|
1194
|
-
UIApplication *application =
|
|
1194
|
+
UIApplication *application =
|
|
1195
|
+
(UIApplication *)[NotifeeCoreUtil notifeeUIApplication];
|
|
1195
1196
|
if (application != nil) {
|
|
1196
1197
|
isApplicationActive =
|
|
1197
1198
|
application.applicationState == UIApplicationStateActive;
|
|
@@ -24,8 +24,8 @@ static NSString *const kPayloadOptionsName = @"notifee_options";
|
|
|
24
24
|
static NSString *const kPayloadOptionsImageURLName = @"image";
|
|
25
25
|
|
|
26
26
|
@interface NotifeeCoreExtensionHelper : NSObject
|
|
27
|
-
@property(nonatomic,
|
|
28
|
-
@property(nonatomic, strong) UNMutableNotificationContent *modifiedContent;
|
|
27
|
+
@property(nonatomic, copy, nullable) void (^contentHandler)(UNNotificationContent *c);
|
|
28
|
+
@property(nonatomic, strong, nullable) UNMutableNotificationContent *modifiedContent;
|
|
29
29
|
|
|
30
30
|
+ (NotifeeCoreExtensionHelper *)instance NS_SWIFT_NAME(serviceExtension());
|
|
31
31
|
|
|
@@ -23,30 +23,56 @@
|
|
|
23
23
|
static NSString *const kNoExtension = @"";
|
|
24
24
|
static NSString *const kImagePathPrefix = @"image/";
|
|
25
25
|
|
|
26
|
-
@
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
instance = [[self alloc] init];
|
|
32
|
-
});
|
|
26
|
+
@interface NotifeeCoreExtensionHelper ()
|
|
27
|
+
- (NSMutableDictionary *)parseNotifeeOptions:(id)payload;
|
|
28
|
+
- (void)loadAttachment:(NSDictionary *)attachmentDict
|
|
29
|
+
completionHandler:(void (^)(UNNotificationAttachment *))completionHandler;
|
|
30
|
+
@end
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
@interface NotifeeCoreExtensionRequestContext : NSObject
|
|
33
|
+
@property(nonatomic, strong) NotifeeCoreExtensionHelper *helper;
|
|
34
|
+
@property(nonatomic, copy) void (^contentHandler)(UNNotificationContent *content);
|
|
35
|
+
@property(nonatomic, strong) UNMutableNotificationContent *modifiedContent;
|
|
36
|
+
@property(nonatomic, assign) BOOL notificationDelivered;
|
|
36
37
|
|
|
37
|
-
- (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
- (instancetype)initWithHelper:(NotifeeCoreExtensionHelper *)helper
|
|
39
|
+
content:(UNMutableNotificationContent *)content
|
|
40
|
+
contentHandler:(void (^)(UNNotificationContent *content))contentHandler;
|
|
41
|
+
- (void)populateNotificationContentWithRequest:(UNNotificationRequest *_Nullable)request;
|
|
42
|
+
- (void)processCommunicationData:(NSMutableDictionary *)options;
|
|
43
|
+
- (void)handleAttachmentsAndDeliverNotificaiton:(NSMutableDictionary *)options;
|
|
44
|
+
- (void)deliverNotification;
|
|
45
|
+
@end
|
|
46
|
+
|
|
47
|
+
@implementation NotifeeCoreExtensionRequestContext
|
|
48
|
+
|
|
49
|
+
- (instancetype)initWithHelper:(NotifeeCoreExtensionHelper *)helper
|
|
50
|
+
content:(UNMutableNotificationContent *)content
|
|
51
|
+
contentHandler:(void (^)(UNNotificationContent *content))contentHandler {
|
|
52
|
+
self = [super init];
|
|
53
|
+
if (self != nil) {
|
|
54
|
+
self.helper = helper;
|
|
55
|
+
self.contentHandler = [contentHandler copy];
|
|
56
|
+
self.modifiedContent = content;
|
|
57
|
+
self.notificationDelivered = NO;
|
|
58
|
+
}
|
|
42
59
|
|
|
43
|
-
|
|
60
|
+
return self;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
- (void)populateNotificationContentWithRequest:(UNNotificationRequest *_Nullable)request {
|
|
64
|
+
id notifeeOptionsPayload = self.modifiedContent.userInfo[kPayloadOptionsName];
|
|
65
|
+
if (!notifeeOptionsPayload) {
|
|
44
66
|
[self deliverNotification];
|
|
45
67
|
return;
|
|
46
68
|
}
|
|
47
69
|
|
|
48
|
-
// fcm: apns: { payload: {notifee_options: {} } }
|
|
49
|
-
NSMutableDictionary *options = [self.
|
|
70
|
+
// fcm: apns: { payload: {notifee_options: "{}" } }
|
|
71
|
+
NSMutableDictionary *options = [self.helper parseNotifeeOptions:notifeeOptionsPayload];
|
|
72
|
+
if (options == nil) {
|
|
73
|
+
[self deliverNotification];
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
50
76
|
|
|
51
77
|
options[@"remote"] = @YES;
|
|
52
78
|
|
|
@@ -60,7 +86,7 @@ static NSString *const kImagePathPrefix = @"image/";
|
|
|
60
86
|
options[@"id"] = request.identifier;
|
|
61
87
|
}
|
|
62
88
|
|
|
63
|
-
if (options[@"title"] == nil &&
|
|
89
|
+
if (options[@"title"] == nil && self.modifiedContent.title != nil) {
|
|
64
90
|
options[@"title"] = self.modifiedContent.title;
|
|
65
91
|
}
|
|
66
92
|
|
|
@@ -135,14 +161,100 @@ static NSString *const kImagePathPrefix = @"image/";
|
|
|
135
161
|
}
|
|
136
162
|
|
|
137
163
|
// Attempt to download attachment
|
|
138
|
-
[self loadAttachment:attachmentDict
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
164
|
+
[self.helper loadAttachment:attachmentDict
|
|
165
|
+
completionHandler:^(UNNotificationAttachment *attachment) {
|
|
166
|
+
if (attachment != nil) {
|
|
167
|
+
@synchronized(self) {
|
|
168
|
+
if (!self.notificationDelivered && self.modifiedContent != nil) {
|
|
169
|
+
self.modifiedContent.attachments = @[ attachment ];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
[self deliverNotification];
|
|
175
|
+
}];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
- (void)deliverNotification {
|
|
179
|
+
void (^contentHandler)(UNNotificationContent *) = nil;
|
|
180
|
+
UNNotificationContent *modifiedContent = nil;
|
|
181
|
+
|
|
182
|
+
@synchronized(self) {
|
|
183
|
+
if (self.notificationDelivered || self.contentHandler == nil) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
contentHandler = [self.contentHandler copy];
|
|
188
|
+
modifiedContent = self.modifiedContent;
|
|
189
|
+
self.notificationDelivered = YES;
|
|
190
|
+
self.contentHandler = nil;
|
|
191
|
+
self.modifiedContent = nil;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (contentHandler != nil && modifiedContent != nil) {
|
|
195
|
+
contentHandler(modifiedContent);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@end
|
|
200
|
+
|
|
201
|
+
@implementation NotifeeCoreExtensionHelper
|
|
202
|
+
+ (NotifeeCoreExtensionHelper *)instance {
|
|
203
|
+
static dispatch_once_t once;
|
|
204
|
+
static NotifeeCoreExtensionHelper *instance;
|
|
205
|
+
dispatch_once(&once, ^{
|
|
206
|
+
instance = [[self alloc] init];
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return instance;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
- (NSMutableDictionary *)parseNotifeeOptions:(id)payload {
|
|
213
|
+
if ([payload isKindOfClass:[NSDictionary class]]) {
|
|
214
|
+
return [payload mutableCopy];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if ([payload isKindOfClass:[NSString class]]) {
|
|
218
|
+
NSData *optionsData = [payload dataUsingEncoding:NSUTF8StringEncoding];
|
|
219
|
+
if (optionsData == nil) {
|
|
220
|
+
NSLog(@"NotifeeCoreExtensionHelper: Could not decode notifee_options string as UTF-8");
|
|
221
|
+
return nil;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
NSError *error = nil;
|
|
225
|
+
id jsonObject = [NSJSONSerialization JSONObjectWithData:optionsData
|
|
226
|
+
options:NSJSONReadingFragmentsAllowed
|
|
227
|
+
error:&error];
|
|
228
|
+
|
|
229
|
+
if (error != nil) {
|
|
230
|
+
NSLog(@"NotifeeCoreExtensionHelper: Could not parse notifee_options JSON: %@", error);
|
|
231
|
+
return nil;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (![jsonObject isKindOfClass:[NSDictionary class]]) {
|
|
235
|
+
NSLog(@"NotifeeCoreExtensionHelper: Ignoring notifee_options JSON because it is not a "
|
|
236
|
+
@"dictionary: %@",
|
|
237
|
+
NSStringFromClass([jsonObject class]));
|
|
238
|
+
return nil;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return [jsonObject mutableCopy];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
NSLog(@"NotifeeCoreExtensionHelper: Ignoring notifee_options because it is not a dictionary "
|
|
245
|
+
@"or JSON string: %@",
|
|
246
|
+
NSStringFromClass([payload class]));
|
|
247
|
+
return nil;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
- (void)populateNotificationContent:(UNNotificationRequest *_Nullable)request
|
|
251
|
+
withContent:(UNMutableNotificationContent *)content
|
|
252
|
+
withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler {
|
|
253
|
+
NotifeeCoreExtensionRequestContext *context =
|
|
254
|
+
[[NotifeeCoreExtensionRequestContext alloc] initWithHelper:self
|
|
255
|
+
content:content
|
|
256
|
+
contentHandler:contentHandler];
|
|
257
|
+
[context populateNotificationContentWithRequest:request];
|
|
146
258
|
}
|
|
147
259
|
|
|
148
260
|
- (NSString *)fileExtensionForResponse:(NSURLResponse *)response {
|
|
@@ -220,10 +332,4 @@ static NSString *const kImagePathPrefix = @"image/";
|
|
|
220
332
|
}
|
|
221
333
|
}
|
|
222
334
|
|
|
223
|
-
- (void)deliverNotification {
|
|
224
|
-
if (self.contentHandler) {
|
|
225
|
-
self.contentHandler(self.modifiedContent);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
335
|
@end
|
|
@@ -23,6 +23,12 @@
|
|
|
23
23
|
#include <math.h>
|
|
24
24
|
#import "NotifeeCore+NSURLSession.h"
|
|
25
25
|
|
|
26
|
+
@interface NotifeeCoreNSURLSession (NotifeeCoreUtil)
|
|
27
|
+
|
|
28
|
+
+ (nullable NSString *)fileExtensionFromSuggestedFilename:(nullable NSString *)suggestedFilename;
|
|
29
|
+
|
|
30
|
+
@end
|
|
31
|
+
|
|
26
32
|
static NSString *const kNotifeeRollingTimestampTriggersStorageKey =
|
|
27
33
|
@"app.notifee.core.rollingTimestampTriggers.v1";
|
|
28
34
|
static NSString *const kNotifeeRollingInternalIdPrefix = @"__notifee_rolling__";
|
|
@@ -83,7 +89,7 @@ static NSInteger const kNotifeeRollingTargetPerTrigger = 32;
|
|
|
83
89
|
notificationActionDict[@"authenticationRequired"] =
|
|
84
90
|
@(((notificationAction.options & UNNotificationActionOptionAuthenticationRequired) != 0));
|
|
85
91
|
|
|
86
|
-
if ([
|
|
92
|
+
if ([notificationAction isKindOfClass:[UNTextInputNotificationAction class]]) {
|
|
87
93
|
UNTextInputNotificationAction *notificationInputAction =
|
|
88
94
|
(UNTextInputNotificationAction *)notificationAction;
|
|
89
95
|
if ([notificationInputAction textInputButtonTitle] == nil &&
|
|
@@ -266,12 +272,14 @@ static NSInteger const kNotifeeRollingTargetPerTrigger = 32;
|
|
|
266
272
|
// Rename the recently downloaded file to include its file extension
|
|
267
273
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
268
274
|
|
|
269
|
-
NSString *fileExtension =
|
|
275
|
+
NSString *fileExtension =
|
|
276
|
+
[NotifeeCoreNSURLSession fileExtensionFromSuggestedFilename:suggestedFilename];
|
|
270
277
|
|
|
271
|
-
if (
|
|
278
|
+
if (fileExtension.length == 0) {
|
|
272
279
|
NSLog(@"NotifeeCore: Failed to determine file extension for attachment "
|
|
273
|
-
@"with URL
|
|
274
|
-
urlString,
|
|
280
|
+
@"with URL %@ and suggested filename %@",
|
|
281
|
+
urlString, suggestedFilename);
|
|
282
|
+
[fileManager removeItemAtPath:tempDestination error:nil];
|
|
275
283
|
return nil;
|
|
276
284
|
}
|
|
277
285
|
|
package/package.json
CHANGED
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '10.3.
|
|
2
|
+
export const version = '10.3.2';
|