From 1bd5fbbc94148e8ac0e9b26d046694742b83968e Mon Sep 17 00:00:00 2001
From: sunnylqm <sunnylqm@gmail.com>
Date: Thu, 17 Dec 2020 00:12:30 +0800
Subject: [PATCH] Refactor ios rollback

---
 ios/RCTPushy/RCTPushy.m | 50 ++++++++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/ios/RCTPushy/RCTPushy.m b/ios/RCTPushy/RCTPushy.m
index 39ba3d9..fcb0447 100644
--- a/ios/RCTPushy/RCTPushy.m
+++ b/ios/RCTPushy/RCTPushy.m
@@ -84,7 +84,6 @@ RCT_EXPORT_MODULE(RCTPushy);
         }
         else {
             NSString *curVersion = pushyInfo[paramCurrentVersion];
-            NSString *lastVersion = pushyInfo[paramLastVersion];
             
             BOOL isFirstTime = [pushyInfo[paramIsFirstTime] boolValue];
             BOOL isFirstLoadOK = [pushyInfo[paramIsFirstLoadOk] boolValue];
@@ -92,23 +91,7 @@ RCT_EXPORT_MODULE(RCTPushy);
             NSString *loadVersion = curVersion;
             BOOL needRollback = (!ignoreRollback && isFirstTime == NO && isFirstLoadOK == NO) || loadVersion.length<=0;
             if (needRollback) {
-                loadVersion = lastVersion;
-                
-                if (lastVersion.length) {
-                    // roll back to last version
-                    [defaults setObject:@{paramCurrentVersion:lastVersion,
-                                          paramIsFirstTime:@(NO),
-                                          paramIsFirstLoadOk:@(YES),
-                                          paramPackageVersion:curPackageVersion}
-                                 forKey:keyPushyInfo];
-                }
-                else {
-                    // roll back to bundle
-                    [defaults setObject:nil forKey:keyPushyInfo];
-                }
-                [defaults setObject:@(YES) forKey:keyRolledBackMarked];
-                [defaults synchronize];
-                // ...need clear files later
+                loadVersion = [self rollback];
             }
             else if (isFirstTime && !ignoreRollback){
                 // bundleURL may be called many times, ignore rollbacks before process restarted again.
@@ -121,13 +104,15 @@ RCT_EXPORT_MODULE(RCTPushy);
                 [defaults synchronize];
             }
             
-            if (loadVersion.length) {
-                NSString *downloadDir = [RCTPushy downloadDir];
-                
+            NSString *downloadDir = [RCTPushy downloadDir];
+            while (loadVersion.length) {
                 NSString *bundlePath = [[downloadDir stringByAppendingPathComponent:loadVersion] stringByAppendingPathComponent:BUNDLE_FILE_NAME];
                 if ([[NSFileManager defaultManager] fileExistsAtPath:bundlePath isDirectory:NULL]) {
                     NSURL *bundleURL = [NSURL fileURLWithPath:bundlePath];
                     return bundleURL;
+                } else {
+                    RCTLogError(@"RCTPushy -- bundle version %@ not found", loadVersion);
+                    loadVersion = [self rollback];
                 }
             }
         }
@@ -136,6 +121,29 @@ RCT_EXPORT_MODULE(RCTPushy);
     return [RCTPushy binaryBundleURL];
 }
 
++ (NSString *) rollback {
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    
+    NSDictionary *pushyInfo = [defaults dictionaryForKey:keyPushyInfo];
+    NSString *lastVersion = pushyInfo[paramLastVersion];
+    NSString *curPackageVersion = [RCTPushy packageVersion];
+    if (lastVersion.length) {
+        // roll back to last version
+        [defaults setObject:@{paramCurrentVersion:lastVersion,
+                              paramIsFirstTime:@(NO),
+                              paramIsFirstLoadOk:@(YES),
+                              paramPackageVersion:curPackageVersion}
+                     forKey:keyPushyInfo];
+    }
+    else {
+        // roll back to bundle
+        [defaults setObject:nil forKey:keyPushyInfo];
+    }
+    [defaults setObject:@(YES) forKey:keyRolledBackMarked];
+    [defaults synchronize];
+    return lastVersion;
+}
+
 + (BOOL)requiresMainQueueSetup {
     // only set to YES if your module initialization relies on calling UIKit!
 	return NO;