Skip to content

Commit c1b39eb

Browse files
committed
fix ios later case
1 parent 61b5d6e commit c1b39eb

5 files changed

Lines changed: 64 additions & 8 deletions

File tree

Example/e2etest/e2e/local-merge.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ describe('Local Update Merge E2E', () => {
195195
? LOCAL_UPDATE_HASHES.packagePatch
196196
: LOCAL_UPDATE_HASHES.ppkPatch;
197197

198+
await relaunchAppPreservingData();
199+
await waitForReady();
200+
await waitForBundleLabel(finalLabel);
201+
await waitForHash(finalHash);
202+
198203
await tapCheckUpdate();
199204
await waitForCheckState('completed', 'upToDate');
200205
await waitForBundleLabel(finalLabel);

ios/RCTPushy/RCTPushy.mm

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ typedef NS_ENUM(NSInteger, PushyType) {
7171
return [NSUserDefaults standardUserDefaults];
7272
}
7373

74+
static void PushyPersistDefaults(NSUserDefaults *defaults) {
75+
(void)defaults;
76+
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
77+
}
78+
7479
static NSString *PushyFromStdString(const std::string &value) {
7580
if (value.empty()) {
7681
return nil;
@@ -180,6 +185,7 @@ static void PushyApplyStateToDefaults(NSUserDefaults *defaults, const pushy::sta
180185
defaults,
181186
keyRolledBackMarked,
182187
PushyFromStdString(state.rolled_back_version));
188+
PushyPersistDefaults(defaults);
183189
}
184190

185191
@interface RCTPushy ()
@@ -253,6 +259,7 @@ + (NSURL *)bundleURL
253259
// bundleURL may be called many times, ignore rollbacks before process restarted again.
254260
ignoreRollback = true;
255261
[defaults setObject:@(YES) forKey:keyFirstLoadMarked];
262+
PushyPersistDefaults(defaults);
256263
}
257264

258265
NSString *loadVersion = PushyFromStdString(decision.load_version);
@@ -317,7 +324,7 @@ - (NSDictionary *)constantsToExport
317324
[defaults removeObjectForKey:KeyPackageUpdatedMarked];
318325
[self clearInvalidFiles];
319326
}
320-
327+
PushyPersistDefaults(defaults);
321328

322329
return ret;
323330
}
@@ -341,6 +348,7 @@ - (instancetype)init
341348

342349
NSUserDefaults *defaults = PushyDefaults();
343350
[defaults setObject:uuid forKey:keyUuid];
351+
PushyPersistDefaults(defaults);
344352
resolve(@true);
345353
}
346354

@@ -359,6 +367,7 @@ - (instancetype)init
359367
if (object && [object isKindOfClass:[NSDictionary class]]) {
360368
NSUserDefaults *defaults = PushyDefaults();
361369
[defaults setObject:value forKey:PushyHashInfoKey(hash)];
370+
PushyPersistDefaults(defaults);
362371

363372
resolve(@true);
364373
} else {

src/__tests__/client.test.ts

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ const createJsonResponse = (payload: unknown) =>
1010
json: async () => payload,
1111
}) as Response;
1212

13-
const setupClientMocks = () => {
13+
const setupClientMocks = ({
14+
isFirstTime = false,
15+
markSuccess = mock(() => {}),
16+
}: {
17+
isFirstTime?: boolean;
18+
markSuccess?: ReturnType<typeof mock>;
19+
} = {}) => {
1420
(globalThis as any).__DEV__ = false;
1521

1622
mock.module('react-native', () => ({
@@ -29,7 +35,7 @@ const setupClientMocks = () => {
2935

3036
mock.module('../core', () => ({
3137
PushyModule: {
32-
markSuccess: mock(() => {}),
38+
markSuccess,
3339
reloadUpdate: mock(() => Promise.resolve()),
3440
setNeedUpdate: mock(() => Promise.resolve()),
3541
downloadPatchFromPpk: mock(() => Promise.resolve()),
@@ -47,7 +53,7 @@ const setupClientMocks = () => {
4753
},
4854
currentVersion: 'hash',
4955
currentVersionInfo: {},
50-
isFirstTime: false,
56+
isFirstTime,
5157
isRolledBack: false,
5258
packageVersion: '1.0.0',
5359
pushyNativeEventEmitter: {
@@ -199,4 +205,40 @@ describe('Pushy server config', () => {
199205
error: fetchError,
200206
});
201207
});
208+
209+
test('waits for native markSuccess before logging success', async () => {
210+
let resolveNativeMarkSuccess = () => {};
211+
const nativeMarkSuccess = mock(
212+
() =>
213+
new Promise<void>(resolve => {
214+
resolveNativeMarkSuccess = resolve;
215+
}),
216+
);
217+
const logger = mock(() => {});
218+
setupClientMocks({
219+
isFirstTime: true,
220+
markSuccess: nativeMarkSuccess,
221+
});
222+
223+
const { Pushy, sharedState } = await importFreshClient('mark-success-awaits-native');
224+
const client = new Pushy({
225+
appKey: 'demo-app',
226+
logger,
227+
});
228+
229+
const markPromise = client.markSuccess();
230+
expect(nativeMarkSuccess).toHaveBeenCalledTimes(1);
231+
expect(sharedState.marked).toBe(false);
232+
expect(logger).not.toHaveBeenCalled();
233+
234+
resolveNativeMarkSuccess();
235+
await markPromise;
236+
237+
expect(sharedState.marked).toBe(true);
238+
expect(logger).toHaveBeenCalledWith(
239+
expect.objectContaining({
240+
type: 'markSuccess',
241+
}),
242+
);
243+
});
202244
});

src/client.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,13 +310,13 @@ export class Pushy {
310310
}
311311
return true;
312312
};
313-
markSuccess = () => {
313+
markSuccess = async () => {
314314
if (sharedState.marked || __DEV__ || !isFirstTime) {
315315
return;
316316
}
317+
await Promise.resolve(PushyModule.markSuccess());
317318
sharedState.marked = true;
318-
PushyModule.markSuccess();
319-
this.report({ type: 'markSuccess' });
319+
await this.report({ type: 'markSuccess' });
320320
};
321321
switchVersion = async (hash: string) => {
322322
if (!this.assertDebug('switchVersion()')) {

src/provider.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ export const UpdateProvider = ({
293293
const { checkStrategy, dismissErrorAfter, autoMarkSuccess } = options;
294294
if (autoMarkSuccess) {
295295
setTimeout(() => {
296-
markSuccess();
296+
void markSuccess();
297297
}, 1000);
298298
}
299299
if (checkStrategy === 'both' || checkStrategy === 'onAppResume') {

0 commit comments

Comments
 (0)