mirror of
https://github.com/zhigang1992/react-native-code-push.git
synced 2026-05-19 19:39:54 +08:00
Merge pull request #334 from Microsoft/retry-report-status
Retry Report Status if failed
This commit is contained in:
39
CodePush.js
39
CodePush.js
@@ -1,7 +1,7 @@
|
||||
import { AcquisitionManager as Sdk } from "code-push/script/acquisition-sdk";
|
||||
import { Alert } from "./AlertAdapter";
|
||||
import requestFetchAdapter from "./request-fetch-adapter";
|
||||
import { Platform } from "react-native";
|
||||
import { AppState, Platform } from "react-native";
|
||||
|
||||
let NativeCodePush = require("react-native").NativeModules.CodePush;
|
||||
const PackageMixins = require("./package-mixins")(NativeCodePush);
|
||||
@@ -174,19 +174,42 @@ const notifyApplicationReady = (() => {
|
||||
|
||||
async function notifyApplicationReadyInternal() {
|
||||
await NativeCodePush.notifyApplicationReady();
|
||||
tryReportStatus();
|
||||
}
|
||||
|
||||
async function tryReportStatus(resumeListener) {
|
||||
const statusReport = await NativeCodePush.getNewStatusReport();
|
||||
if (statusReport) {
|
||||
const config = await getConfiguration();
|
||||
const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion;
|
||||
const previousDeploymentKey = statusReport.previousDeploymentKey || config.deploymentKey;
|
||||
if (statusReport.appVersion) {
|
||||
const sdk = getPromisifiedSdk(requestFetchAdapter, config);
|
||||
sdk.reportStatusDeploy(/* deployedPackage */ null, /* status */ null, previousLabelOrAppVersion, previousDeploymentKey);
|
||||
} else {
|
||||
config.deploymentKey = statusReport.package.deploymentKey;
|
||||
const sdk = getPromisifiedSdk(requestFetchAdapter, config);
|
||||
sdk.reportStatusDeploy(statusReport.package, statusReport.status, previousLabelOrAppVersion, previousDeploymentKey);
|
||||
try {
|
||||
if (statusReport.appVersion) {
|
||||
const sdk = getPromisifiedSdk(requestFetchAdapter, config);
|
||||
await sdk.reportStatusDeploy(/* deployedPackage */ null, /* status */ null, previousLabelOrAppVersion, previousDeploymentKey);
|
||||
} else {
|
||||
config.deploymentKey = statusReport.package.deploymentKey;
|
||||
const sdk = getPromisifiedSdk(requestFetchAdapter, config);
|
||||
await sdk.reportStatusDeploy(statusReport.package, statusReport.status, previousLabelOrAppVersion, previousDeploymentKey);
|
||||
}
|
||||
|
||||
log(`Reported status: ${JSON.stringify(statusReport)}`);
|
||||
NativeCodePush.recordStatusReported(statusReport);
|
||||
resumeListener && AppState.removeEventListener("change", resumeListener);
|
||||
} catch (e) {
|
||||
log(`Report status failed: ${JSON.stringify(statusReport)}`);
|
||||
NativeCodePush.saveStatusReportForRetry(statusReport);
|
||||
// Try again when the app resumes
|
||||
if (!resumeListener) {
|
||||
resumeListener = (newState) => {
|
||||
newState === "active" && tryReportStatus(resumeListener);
|
||||
};
|
||||
|
||||
AppState.addEventListener("change", resumeListener);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resumeListener && AppState.removeEventListener("change", resumeListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -626,6 +626,12 @@ public class CodePush implements ReactPackage {
|
||||
promise.resolve(newAppVersionStatusReport);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
WritableMap retryStatusReport = codePushTelemetryManager.getRetryStatusReport();
|
||||
if (retryStatusReport != null) {
|
||||
promise.resolve(retryStatusReport);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
promise.resolve("");
|
||||
@@ -720,6 +726,11 @@ public class CodePush implements ReactPackage {
|
||||
promise.resolve("");
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void recordStatusReported(ReadableMap statusReport) {
|
||||
codePushTelemetryManager.recordStatusReported(statusReport);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void restartApp(boolean onlyIfUpdateIsPending) {
|
||||
// If this is an unconditional restart request, or there
|
||||
@@ -729,6 +740,11 @@ public class CodePush implements ReactPackage {
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void saveStatusReportForRetry(ReadableMap statusReport) {
|
||||
codePushTelemetryManager.saveStatusReportForRetry(statusReport);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
// Replaces the current bundle with the one downloaded from removeBundleUrl.
|
||||
// It is only to be used during tests. No-ops if the test configuration flag is not set.
|
||||
|
||||
@@ -3,18 +3,28 @@ package com.microsoft.codepush.react;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class CodePushTelemetryManager {
|
||||
|
||||
private Context applicationContext;
|
||||
private final String APP_VERSION_KEY = "appVersion";
|
||||
private final String CODE_PUSH_PREFERENCES;
|
||||
private final String DEPLOYMENT_FAILED_STATUS = "DeploymentFailed";
|
||||
private final String DEPLOYMENT_KEY_KEY = "deploymentKey";
|
||||
private final String DEPLOYMENT_SUCCEEDED_STATUS = "DeploymentSucceeded";
|
||||
private final String LABEL_KEY = "label";
|
||||
private final String LAST_DEPLOYMENT_REPORT_KEY = "CODE_PUSH_LAST_DEPLOYMENT_REPORT";
|
||||
private final String PACKAGE_KEY = "package";
|
||||
private final String PREVIOUS_DEPLOYMENT_KEY_KEY = "previousDeploymentKey";
|
||||
private final String PREVIOUS_LABEL_OR_APP_VERSION_KEY = "previousLabelOrAppVersion";
|
||||
private final String RETRY_DEPLOYMENT_REPORT_KEY = "CODE_PUSH_RETRY_DEPLOYMENT_REPORT";
|
||||
private final String STATUS_KEY = "status";
|
||||
|
||||
public CodePushTelemetryManager(Context applicationContext, String codePushPreferencesKey) {
|
||||
this.applicationContext = applicationContext;
|
||||
@@ -23,26 +33,41 @@ public class CodePushTelemetryManager {
|
||||
|
||||
public WritableMap getBinaryUpdateReport(String appVersion) {
|
||||
String previousStatusReportIdentifier = this.getPreviousStatusReportIdentifier();
|
||||
WritableNativeMap reportMap = null;
|
||||
if (previousStatusReportIdentifier == null) {
|
||||
this.recordDeploymentStatusReported(appVersion);
|
||||
WritableNativeMap reportMap = new WritableNativeMap();
|
||||
reportMap.putString("appVersion", appVersion);
|
||||
return reportMap;
|
||||
this.clearRetryStatusReport();
|
||||
reportMap = new WritableNativeMap();
|
||||
reportMap.putString(APP_VERSION_KEY, appVersion);
|
||||
} else if (!previousStatusReportIdentifier.equals(appVersion)) {
|
||||
this.recordDeploymentStatusReported(appVersion);
|
||||
WritableNativeMap reportMap = new WritableNativeMap();
|
||||
this.clearRetryStatusReport();
|
||||
reportMap = new WritableNativeMap();
|
||||
if (this.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) {
|
||||
String previousDeploymentKey = this.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier);
|
||||
String previousLabel = this.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier);
|
||||
reportMap.putString("appVersion", appVersion);
|
||||
reportMap.putString("previousDeploymentKey", previousDeploymentKey);
|
||||
reportMap.putString("previousLabelOrAppVersion", previousLabel);
|
||||
reportMap.putString(APP_VERSION_KEY, appVersion);
|
||||
reportMap.putString(PREVIOUS_DEPLOYMENT_KEY_KEY, previousDeploymentKey);
|
||||
reportMap.putString(PREVIOUS_LABEL_OR_APP_VERSION_KEY, previousLabel);
|
||||
} else {
|
||||
// Previous status report was with a binary app version.
|
||||
reportMap.putString("appVersion", appVersion);
|
||||
reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier);
|
||||
reportMap.putString(APP_VERSION_KEY, appVersion);
|
||||
reportMap.putString(PREVIOUS_LABEL_OR_APP_VERSION_KEY, previousStatusReportIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
return reportMap;
|
||||
}
|
||||
|
||||
public WritableMap getRetryStatusReport() {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
String retryStatusReportString = settings.getString(RETRY_DEPLOYMENT_REPORT_KEY, null);
|
||||
if (retryStatusReportString != null) {
|
||||
clearRetryStatusReport();
|
||||
try {
|
||||
JSONObject retryStatusReport = new JSONObject(retryStatusReportString);
|
||||
return CodePushUtils.convertJsonObjectToWritable(retryStatusReport);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return reportMap;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -50,44 +75,61 @@ public class CodePushTelemetryManager {
|
||||
|
||||
public WritableMap getRollbackReport(WritableMap lastFailedPackage) {
|
||||
WritableNativeMap reportMap = new WritableNativeMap();
|
||||
reportMap.putMap("package", lastFailedPackage);
|
||||
reportMap.putString("status", DEPLOYMENT_FAILED_STATUS);
|
||||
reportMap.putMap(PACKAGE_KEY, lastFailedPackage);
|
||||
reportMap.putString(STATUS_KEY, DEPLOYMENT_FAILED_STATUS);
|
||||
return reportMap;
|
||||
}
|
||||
|
||||
public WritableMap getUpdateReport(WritableMap currentPackage) {
|
||||
String currentPackageIdentifier = this.getPackageStatusReportIdentifier(currentPackage);
|
||||
String previousStatusReportIdentifier = this.getPreviousStatusReportIdentifier();
|
||||
WritableNativeMap reportMap = null;
|
||||
if (currentPackageIdentifier != null) {
|
||||
if (previousStatusReportIdentifier == null) {
|
||||
this.recordDeploymentStatusReported(currentPackageIdentifier);
|
||||
WritableNativeMap reportMap = new WritableNativeMap();
|
||||
reportMap.putMap("package", currentPackage);
|
||||
reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS);
|
||||
return reportMap;
|
||||
this.clearRetryStatusReport();
|
||||
reportMap = new WritableNativeMap();
|
||||
reportMap.putMap(PACKAGE_KEY, currentPackage);
|
||||
reportMap.putString(STATUS_KEY, DEPLOYMENT_SUCCEEDED_STATUS);
|
||||
} else if (!previousStatusReportIdentifier.equals(currentPackageIdentifier)) {
|
||||
this.recordDeploymentStatusReported(currentPackageIdentifier);
|
||||
this.clearRetryStatusReport();
|
||||
reportMap = new WritableNativeMap();
|
||||
if (this.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) {
|
||||
String previousDeploymentKey = this.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier);
|
||||
String previousLabel = this.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier);
|
||||
WritableNativeMap reportMap = new WritableNativeMap();
|
||||
reportMap.putMap("package", currentPackage);
|
||||
reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS);
|
||||
reportMap.putString("previousDeploymentKey", previousDeploymentKey);
|
||||
reportMap.putString("previousLabelOrAppVersion", previousLabel);
|
||||
return reportMap;
|
||||
reportMap.putMap(PACKAGE_KEY, currentPackage);
|
||||
reportMap.putString(STATUS_KEY, DEPLOYMENT_SUCCEEDED_STATUS);
|
||||
reportMap.putString(PREVIOUS_DEPLOYMENT_KEY_KEY, previousDeploymentKey);
|
||||
reportMap.putString(PREVIOUS_LABEL_OR_APP_VERSION_KEY, previousLabel);
|
||||
} else {
|
||||
// Previous status report was with a binary app version.
|
||||
WritableNativeMap reportMap = new WritableNativeMap();
|
||||
reportMap.putMap("package", currentPackage);
|
||||
reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS);
|
||||
reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier);
|
||||
return reportMap;
|
||||
reportMap.putMap(PACKAGE_KEY, currentPackage);
|
||||
reportMap.putString(STATUS_KEY, DEPLOYMENT_SUCCEEDED_STATUS);
|
||||
reportMap.putString(PREVIOUS_LABEL_OR_APP_VERSION_KEY, previousStatusReportIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return reportMap;
|
||||
}
|
||||
|
||||
public void recordStatusReported(ReadableMap statusReport) {
|
||||
if (statusReport.hasKey(APP_VERSION_KEY)) {
|
||||
saveStatusReportedForIdentifier(statusReport.getString(APP_VERSION_KEY));
|
||||
} else if (statusReport.hasKey(PACKAGE_KEY)) {
|
||||
String packageIdentifier = getPackageStatusReportIdentifier(statusReport.getMap(PACKAGE_KEY));
|
||||
saveStatusReportedForIdentifier(packageIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveStatusReportForRetry(ReadableMap statusReport) {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
JSONObject statusReportJSON = CodePushUtils.convertReadableToJsonObject(statusReport);
|
||||
settings.edit().putString(RETRY_DEPLOYMENT_REPORT_KEY, statusReportJSON.toString()).commit();
|
||||
}
|
||||
|
||||
private void clearRetryStatusReport() {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
settings.edit().remove(RETRY_DEPLOYMENT_REPORT_KEY).commit();
|
||||
}
|
||||
|
||||
private String getDeploymentKeyFromStatusReportIdentifier(String statusReportIdentifier) {
|
||||
@@ -99,7 +141,7 @@ public class CodePushTelemetryManager {
|
||||
}
|
||||
}
|
||||
|
||||
private String getPackageStatusReportIdentifier(WritableMap updatePackage) {
|
||||
private String getPackageStatusReportIdentifier(ReadableMap updatePackage) {
|
||||
// Because deploymentKeys can be dynamically switched, we use a
|
||||
// combination of the deploymentKey and label as the packageIdentifier.
|
||||
String deploymentKey = CodePushUtils.tryGetString(updatePackage, DEPLOYMENT_KEY_KEY);
|
||||
@@ -129,7 +171,7 @@ public class CodePushTelemetryManager {
|
||||
return statusReportIdentifier != null && statusReportIdentifier.contains(":");
|
||||
}
|
||||
|
||||
private void recordDeploymentStatusReported(String appVersionOrPackageIdentifier) {
|
||||
private void saveStatusReportedForIdentifier(String appVersionOrPackageIdentifier) {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
settings.edit().putString(LAST_DEPLOYMENT_REPORT_KEY, appVersionOrPackageIdentifier).commit();
|
||||
}
|
||||
|
||||
@@ -112,8 +112,11 @@ failCallback:(void (^)(NSError *err))failCallback;
|
||||
@interface CodePushTelemetryManager : NSObject
|
||||
|
||||
+ (NSDictionary *)getBinaryUpdateReport:(NSString *)appVersion;
|
||||
+ (NSDictionary *)getRetryStatusReport;
|
||||
+ (NSDictionary *)getRollbackReport:(NSDictionary *)lastFailedPackage;
|
||||
+ (NSDictionary *)getUpdateReport:(NSDictionary *)currentPackage;
|
||||
+ (void)recordStatusReported:(NSDictionary *)statusReport;
|
||||
+ (void)saveStatusReportForRetry:(NSDictionary *)statusReport;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
BOOL _isFirstRunAfterUpdate;
|
||||
int _minimumBackgroundDuration;
|
||||
NSDate *_lastResignedDate;
|
||||
|
||||
|
||||
// Used to coordinate the dispatching of download progress events to JS.
|
||||
long long _latestExpectedContentLength;
|
||||
long long _latestReceivedConentLength;
|
||||
@@ -507,14 +507,14 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage
|
||||
[mutableUpdatePackage setValue:[CodePushUpdateUtils modifiedDateStringOfFileAtURL:binaryBundleURL]
|
||||
forKey:BinaryBundleDateKey];
|
||||
}
|
||||
|
||||
|
||||
if (notifyProgress) {
|
||||
// Set up and unpause the frame observer so that it can emit
|
||||
// progress events every frame if the progress is updated.
|
||||
_didUpdateProgress = NO;
|
||||
_paused = NO;
|
||||
}
|
||||
|
||||
|
||||
[CodePushPackage
|
||||
downloadPackage:mutableUpdatePackage
|
||||
expectedBundleFileName:[bundleResourceName stringByAppendingPathExtension:bundleResourceExtension]
|
||||
@@ -525,7 +525,7 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage
|
||||
_latestExpectedContentLength = expectedContentLength;
|
||||
_latestReceivedConentLength = receivedContentLength;
|
||||
_didUpdateProgress = YES;
|
||||
|
||||
|
||||
// If the download is completed, stop observing frame
|
||||
// updates and synchronously send the last event.
|
||||
if (expectedContentLength == receivedContentLength) {
|
||||
@@ -549,7 +549,7 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage
|
||||
if ([CodePushErrorUtils isCodePushError:err]) {
|
||||
[self saveFailedUpdate:mutableUpdatePackage];
|
||||
}
|
||||
|
||||
|
||||
// Stop observing frame updates if the download fails.
|
||||
_didUpdateProgress = NO;
|
||||
_paused = YES;
|
||||
@@ -783,11 +783,27 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve
|
||||
NSString *appVersion = [[CodePushConfig current] appVersion];
|
||||
resolve([CodePushTelemetryManager getBinaryUpdateReport:appVersion]);
|
||||
return;
|
||||
} else {
|
||||
NSDictionary *retryStatusReport = [CodePushTelemetryManager getRetryStatusReport];
|
||||
if (retryStatusReport) {
|
||||
resolve(retryStatusReport);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
resolve(nil);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(recordStatusReported:(NSDictionary *)statusReport)
|
||||
{
|
||||
[CodePushTelemetryManager recordStatusReported:statusReport];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(saveStatusReportForRetry:(NSDictionary *)statusReport)
|
||||
{
|
||||
[CodePushTelemetryManager saveStatusReportForRetry:statusReport];
|
||||
}
|
||||
|
||||
#pragma mark - RCTFrameUpdateObserver Methods
|
||||
|
||||
- (void)didUpdateFrame:(RCTFrameUpdate *)update
|
||||
@@ -795,7 +811,7 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve
|
||||
if (!_didUpdateProgress) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self dispatchDownloadProgressEvent];
|
||||
_didUpdateProgress = NO;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ failCallback:(void (^)(NSError *err))failCallback {
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)download:(NSString*)url {
|
||||
- (void)download:(NSString*)url {
|
||||
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
|
||||
cachePolicy:NSURLRequestUseProtocolCachePolicy
|
||||
timeoutInterval:60.0];
|
||||
@@ -47,12 +47,12 @@ failCallback:(void (^)(NSError *err))failCallback {
|
||||
return nil;
|
||||
}
|
||||
|
||||
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
||||
self.expectedContentLength = response.expectedContentLength;
|
||||
[self.outputFileStream open];
|
||||
}
|
||||
|
||||
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
if (self.receivedContentLength < 4) {
|
||||
for (int i = 0; i < [data length]; i++) {
|
||||
int headerOffset = (int)self.receivedContentLength + i;
|
||||
@@ -97,7 +97,7 @@ failCallback:(void (^)(NSError *err))failCallback {
|
||||
self.failCallback(error);
|
||||
}
|
||||
|
||||
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
// expectedContentLength might be -1 when NSURLConnection don't know the length(e.g. response encode with gzip)
|
||||
if (self.expectedContentLength > 0) {
|
||||
// We should have received all of the bytes if this is called.
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
#import "CodePush.h"
|
||||
|
||||
static NSString *const AppVersionKey = @"appVersion";
|
||||
static NSString *const DeploymentFailed = @"DeploymentFailed";
|
||||
static NSString *const DeploymentKeyKey = @"deploymentKey";
|
||||
static NSString *const DeploymentSucceeded = @"DeploymentSucceeded";
|
||||
static NSString *const LabelKey = @"label";
|
||||
static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REPORT";
|
||||
static NSString *const PackageKey = @"package";
|
||||
static NSString *const PreviousDeploymentKeyKey = @"previousDeploymentKey";
|
||||
static NSString *const PreviousLabelOrAppVersionKey = @"previousLabelOrAppVersion";
|
||||
static NSString *const RetryDeploymentReportKey = @"CODE_PUSH_RETRY_DEPLOYMENT_REPORT";
|
||||
static NSString *const StatusKey = @"status";
|
||||
|
||||
@implementation CodePushTelemetryManager
|
||||
|
||||
@@ -12,35 +18,48 @@ static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REP
|
||||
{
|
||||
NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier];
|
||||
if (previousStatusReportIdentifier == nil) {
|
||||
[self recordDeploymentStatusReported:appVersion];
|
||||
return @{ @"appVersion": appVersion };
|
||||
[self clearRetryStatusReport];
|
||||
return @{ AppVersionKey: appVersion };
|
||||
} else if (![previousStatusReportIdentifier isEqualToString:appVersion]) {
|
||||
[self recordDeploymentStatusReported:appVersion];
|
||||
if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) {
|
||||
NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier];
|
||||
NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier];
|
||||
[self clearRetryStatusReport];
|
||||
return @{
|
||||
@"appVersion": appVersion,
|
||||
@"previousDeploymentKey": previousDeploymentKey,
|
||||
@"previousLabelOrAppVersion": previousLabel
|
||||
AppVersionKey: appVersion,
|
||||
PreviousDeploymentKeyKey: previousDeploymentKey,
|
||||
PreviousLabelOrAppVersionKey: previousLabel
|
||||
};
|
||||
} else {
|
||||
[self clearRetryStatusReport];
|
||||
// Previous status report was with a binary app version.
|
||||
return @{
|
||||
@"appVersion": appVersion,
|
||||
@"previousLabelOrAppVersion": previousStatusReportIdentifier
|
||||
AppVersionKey: appVersion,
|
||||
PreviousLabelOrAppVersionKey: previousStatusReportIdentifier
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)getRetryStatusReport
|
||||
{
|
||||
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
||||
NSDictionary *retryStatusReport = [preferences objectForKey:RetryDeploymentReportKey];
|
||||
if (retryStatusReport) {
|
||||
[self clearRetryStatusReport];
|
||||
return retryStatusReport;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSDictionary *)getRollbackReport:(NSDictionary *)lastFailedPackage
|
||||
{
|
||||
return @{
|
||||
@"package": lastFailedPackage,
|
||||
@"status": DeploymentFailed
|
||||
PackageKey: lastFailedPackage,
|
||||
StatusKey: DeploymentFailed
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,38 +69,62 @@ static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REP
|
||||
NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier];
|
||||
if (currentPackageIdentifier) {
|
||||
if (previousStatusReportIdentifier == nil) {
|
||||
[self recordDeploymentStatusReported:currentPackageIdentifier];
|
||||
[self clearRetryStatusReport];
|
||||
return @{
|
||||
@"package": currentPackage,
|
||||
@"status": DeploymentSucceeded
|
||||
PackageKey: currentPackage,
|
||||
StatusKey: DeploymentSucceeded
|
||||
};
|
||||
} else if (![previousStatusReportIdentifier isEqualToString:currentPackageIdentifier]) {
|
||||
[self recordDeploymentStatusReported:currentPackageIdentifier];
|
||||
[self clearRetryStatusReport];
|
||||
if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) {
|
||||
NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier];
|
||||
NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier];
|
||||
return @{
|
||||
@"package": currentPackage,
|
||||
@"status": DeploymentSucceeded,
|
||||
@"previousDeploymentKey": previousDeploymentKey,
|
||||
@"previousLabelOrAppVersion": previousLabel
|
||||
PackageKey: currentPackage,
|
||||
StatusKey: DeploymentSucceeded,
|
||||
PreviousDeploymentKeyKey: previousDeploymentKey,
|
||||
PreviousLabelOrAppVersionKey: previousLabel
|
||||
};
|
||||
} else {
|
||||
// Previous status report was with a binary app version.
|
||||
return @{
|
||||
@"package": currentPackage,
|
||||
@"status": DeploymentSucceeded,
|
||||
@"previousLabelOrAppVersion": previousStatusReportIdentifier
|
||||
PackageKey: currentPackage,
|
||||
StatusKey: DeploymentSucceeded,
|
||||
PreviousLabelOrAppVersionKey: previousStatusReportIdentifier
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (void)recordStatusReported:(NSDictionary *)statusReport
|
||||
{
|
||||
if (statusReport[AppVersionKey]) {
|
||||
[self saveStatusReportedForIdentifier:statusReport[AppVersionKey]];
|
||||
} else if (statusReport[PackageKey]) {
|
||||
NSString *packageIdentifier = [self getPackageStatusReportIdentifier:statusReport[PackageKey]];
|
||||
[self saveStatusReportedForIdentifier:packageIdentifier];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)saveStatusReportForRetry:(NSDictionary *)statusReport
|
||||
{
|
||||
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
||||
[preferences setValue:statusReport forKey:RetryDeploymentReportKey];
|
||||
[preferences synchronize];
|
||||
}
|
||||
|
||||
#pragma mark - private methods
|
||||
|
||||
+ (void)clearRetryStatusReport
|
||||
{
|
||||
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
||||
[preferences setValue:nil forKey:RetryDeploymentReportKey];
|
||||
[preferences synchronize];
|
||||
}
|
||||
|
||||
+ (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier
|
||||
{
|
||||
return [[statusReportIdentifier componentsSeparatedByString:@":"] firstObject];
|
||||
@@ -117,11 +160,11 @@ static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REP
|
||||
return statusReportIdentifier != nil && [statusReportIdentifier rangeOfString:@":"].location != NSNotFound;
|
||||
}
|
||||
|
||||
+ (void)recordDeploymentStatusReported:(NSString *)appVersionOrPackageIdentifier
|
||||
+ (void)saveStatusReportedForIdentifier:(NSString *)appVersionOrPackageIdentifier
|
||||
{
|
||||
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
|
||||
[preferences setValue:appVersionOrPackageIdentifier forKey:LastDeploymentReportKey];
|
||||
[preferences synchronize];
|
||||
}
|
||||
|
||||
@end
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user