@@ -11,7 +11,8 @@ @implementation CodePush
11
11
BOOL usingTestFolder = NO ;
12
12
BOOL didUpdate = NO ;
13
13
14
- NSString * const FailedUpdatesKey = @" FAILED_UPDATES" ;
14
+ NSString * const FailedUpdatesKey = @" CODE_PUSH_FAILED_UPDATES" ;
15
+ NSString * const PendingUpdateKey = @" CODE_PUSH_PENDING_UPDATE" ;
15
16
NSString * const UpdateBundleFileName = @" app.jsbundle" ;
16
17
17
18
@synthesize bridge = _bridge;
@@ -57,6 +58,51 @@ - (void)cancelRollbackTimer
57
58
});
58
59
}
59
60
61
+ - (CodePush *)init
62
+ {
63
+ self = [super init ];
64
+
65
+ if (self) {
66
+ NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults ];
67
+ NSDictionary *pendingUpdate = [preferences objectForKey: PendingUpdateKey];
68
+
69
+ if (pendingUpdate)
70
+ {
71
+ NSError *error;
72
+ NSString * pendingHash = pendingUpdate[@" hash" ];
73
+ NSString * currentHash = [CodePushPackage getCurrentPackageHash: &error];
74
+
75
+ // If the current hash is equivalent to the pending hash, then the app
76
+ // restart "picked up" the new update, but we need to kick off the
77
+ // rollback timer and ensure that the neccessaey state is setup.
78
+ if ([pendingHash isEqualToString: currentHash]) {
79
+ int rollbackTimeout = [pendingUpdate[@" rollbackTimeout" ] intValue ];
80
+ [self initializeUpdateWithRollbackTimeout: rollbackTimeout needsRestart: NO ];
81
+
82
+ // Clear the pending update and sync
83
+ [preferences removeObjectForKey: PendingUpdateKey];
84
+ [preferences synchronize ];
85
+ }
86
+ }
87
+ }
88
+
89
+ return self;
90
+ }
91
+
92
+ - (void )initializeUpdateWithRollbackTimeout : (int )rollbackTimeout needsRestart : (BOOL )needsRestart {
93
+ didUpdate = YES ;
94
+
95
+ if (needsRestart) {
96
+ [self loadBundle ];
97
+ }
98
+
99
+ if (0 != rollbackTimeout) {
100
+ dispatch_async (dispatch_get_main_queue (), ^{
101
+ [self startRollbackTimer: rollbackTimeout];
102
+ });
103
+ }
104
+ }
105
+
60
106
- (BOOL )isFailedHash : (NSString *)packageHash {
61
107
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults ];
62
108
NSMutableArray *failedUpdates = [preferences objectForKey: FailedUpdatesKey];
@@ -101,6 +147,19 @@ - (void)saveFailedUpdate:(NSString *)packageHash {
101
147
[preferences synchronize ];
102
148
}
103
149
150
+ - (void )savePendingUpdate : (NSString *)packageHash
151
+ rollbackTimeout : (int )rollbackTimeout {
152
+ // Since we're not restarting, we need to store the fact that the update
153
+ // was applied, but hasn't yet become "active".
154
+ NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults ];
155
+ NSDictionary *pendingUpdate = [[NSDictionary alloc ] initWithObjectsAndKeys:
156
+ packageHash,@" hash" ,
157
+ rollbackTimeout,@" rollbackTimeout" , nil ];
158
+
159
+ [preferences setObject: pendingUpdate forKey: PendingUpdateKey];
160
+ [preferences synchronize ];
161
+ }
162
+
104
163
- (void )startRollbackTimer : (int )rollbackTimeout
105
164
{
106
165
double timeoutInSeconds = rollbackTimeout / 1000 ;
@@ -111,13 +170,14 @@ - (void)startRollbackTimer:(int)rollbackTimeout
111
170
repeats: NO ];
112
171
}
113
172
173
+ // JavaScript-exported module methods
114
174
// JavaScript-exported module methods
115
175
RCT_EXPORT_METHOD (applyUpdate:(NSDictionary *)updatePackage
116
- rollbackTimeout:(int )rollbackTimeout
117
- resolver:(RCTPromiseResolveBlock)resolve
118
- rejecter:(RCTPromiseRejectBlock)reject)
176
+ rollbackTimeout:(int )rollbackTimeout
177
+ restartImmediately:(BOOL )restartImmediately
178
+ resolver:(RCTPromiseResolveBlock)resolve
179
+ rejecter:(RCTPromiseRejectBlock)reject)
119
180
{
120
-
121
181
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
122
182
NSError *error;
123
183
[CodePushPackage applyPackage: updatePackage
@@ -126,14 +186,10 @@ - (void)startRollbackTimer:(int)rollbackTimeout
126
186
if (error) {
127
187
reject (error);
128
188
} else {
129
- didUpdate = YES ;
130
-
131
- [self loadBundle ];
132
-
133
- if (0 != rollbackTimeout) {
134
- dispatch_async (dispatch_get_main_queue (), ^{
135
- [self startRollbackTimer: rollbackTimeout];
136
- });
189
+ if (restartImmediately) {
190
+ [self initializeUpdateWithRollbackTimeout: rollbackTimeout needsRestart: YES ];
191
+ } else {
192
+ [self savePendingUpdate: updatePackage[@" packageHash" ] rollbackTimeout: rollbackTimeout];
137
193
}
138
194
}
139
195
});
0 commit comments