@@ -13,9 +13,9 @@ @implementation CodePush {
13
13
14
14
RCT_EXPORT_MODULE ()
15
15
16
- static NSTimer *_timer;
17
16
static BOOL usingTestFolder = NO;
18
17
18
+ // These keys represent the names we use to store data in NSUserDefaults
19
19
static NSString *const FailedUpdatesKey = @" CODE_PUSH_FAILED_UPDATES" ;
20
20
static NSString *const PendingUpdateKey = @" CODE_PUSH_PENDING_UPDATE" ;
21
21
@@ -24,6 +24,11 @@ @implementation CodePush {
24
24
static NSString *const PendingUpdateHashKey = @" hash" ;
25
25
static NSString *const PendingUpdateIsLoadingKey = @" isLoading" ;
26
26
27
+ // These keys are used to inspect/augment the metadata
28
+ // that is associated with an update's package.
29
+ static NSString *const PackageHashKey = @" packageHash" ;
30
+ static NSString *const PackageIsPendingKey = @" isPending" ;
31
+
27
32
@synthesize bridge = _bridge;
28
33
29
34
// Public Obj-C API (see header for method comments)
@@ -141,6 +146,25 @@ - (BOOL)isFailedHash:(NSString*)packageHash
141
146
return (failedUpdates != nil && [failedUpdates containsObject: packageHash]);
142
147
}
143
148
149
+ /*
150
+ * This method checks to see whether a specific package hash
151
+ * represents a downloaded and installed update, that hasn't
152
+ * been applied yet via an app restart.
153
+ */
154
+ - (BOOL )isPendingUpdate : (NSString *)packageHash
155
+ {
156
+ NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults ];
157
+ NSDictionary *pendingUpdate = [preferences objectForKey: PendingUpdateKey];
158
+
159
+ // If there is a pending update, whose hash is equal to the one
160
+ // specified, and its "state" isn't loading, then we consider it "pending".
161
+ BOOL updateIsPending = pendingUpdate &&
162
+ [pendingUpdate[PendingUpdateIsLoadingKey] boolValue ] == NO &&
163
+ [pendingUpdate[PendingUpdateHashKey] isEqualToString: packageHash];
164
+
165
+ return updateIsPending;
166
+ }
167
+
144
168
/*
145
169
* This method updates the React Native bridge's bundle URL
146
170
* to point at the latest CodePush update, and then restarts
@@ -259,7 +283,7 @@ - (void)savePendingUpdate:(NSString *)packageHash
259
283
// The download completed
260
284
doneCallback: ^{
261
285
NSError *err;
262
- NSDictionary *newPackage = [CodePushPackage getPackage: updatePackage[@" packageHash " ] error: &err];
286
+ NSDictionary *newPackage = [CodePushPackage getPackage: updatePackage[PackageHashKey ] error: &err];
263
287
264
288
if (err) {
265
289
return reject (err);
@@ -293,12 +317,18 @@ - (void)savePendingUpdate:(NSString *)packageHash
293
317
{
294
318
dispatch_async (dispatch_get_main_queue (), ^{
295
319
NSError *error;
296
- NSDictionary *package = [CodePushPackage getCurrentPackage: &error];
320
+ NSMutableDictionary *package = [[CodePushPackage getCurrentPackage: &error] mutableCopy ];
321
+
297
322
if (error) {
298
323
reject (error);
299
- } else {
300
- resolve (package);
301
324
}
325
+
326
+ // Add the "isPending" virtual property to the package at this point, so that
327
+ // the script-side doesn't need to immediately call back into native to populate it.
328
+ BOOL isPendingUpdate = [self isPendingUpdate: [package objectForKey: PackageHashKey]];
329
+ [package setObject: @(isPendingUpdate) forKey: PackageIsPendingKey];
330
+
331
+ resolve (package);
302
332
});
303
333
}
304
334
@@ -318,7 +348,7 @@ - (void)savePendingUpdate:(NSString *)packageHash
318
348
if (error) {
319
349
reject (error);
320
350
} else {
321
- [self savePendingUpdate: updatePackage[@" packageHash " ]
351
+ [self savePendingUpdate: updatePackage[PackageHashKey ]
322
352
isLoading: NO ];
323
353
324
354
if (installMode == CodePushInstallModeImmediate) {
@@ -393,4 +423,4 @@ - (void)savePendingUpdate:(NSString *)packageHash
393
423
usingTestFolder = shouldUseTestFolder;
394
424
}
395
425
396
- @end
426
+ @end
0 commit comments