Files
react-native-code-push/package-mixins.js
Richard Hua 392189fad0 Support React Native 0.35.0 (#562)
* Upgrade example app to RN 0.35.0
* Update supported versions in README
* Support RN 35 - make a copy of objects queued over the bridge if they are mutable

This line was added in React Native 0.35.0: https://github.com/facebook/react-native/blob/v0.35.0/Libraries/Utilities/MessageQueue.js#L194 (facebook/react-native@145109f). It essentially deep freezes (or makes immutable) any object sent from JS to Native over the bridge. This object is already pass-by-value to begin with, so I assume the purpose of this is to avoid any ambiguity or confusion that might occur if the object is modified while it is sitting in the message queue.

We do send a localPackage object over the bridge, which we modify afterwards. Because we only care about the value of this object at the moment that it is queued, the fix is to make a copy of it before sending it over the bridge.

This is relevant to issue #536 (RN version support).
2016-10-11 17:13:46 -07:00

59 lines
2.5 KiB
JavaScript

import { AcquisitionManager as Sdk } from "code-push/script/acquisition-sdk";
import { NativeEventEmitter } from "react-native";
import RestartManager from "./RestartManager";
// This function is used to augment remote and local
// package objects with additional functionality/properties
// beyond what is included in the metadata sent by the server.
module.exports = (NativeCodePush) => {
const remote = (reportStatusDownload) => {
return {
async download(downloadProgressCallback) {
if (!this.downloadUrl) {
throw new Error("Cannot download an update without a download url");
}
let downloadProgressSubscription;
if (downloadProgressCallback) {
const codePushEventEmitter = new NativeEventEmitter(NativeCodePush);
// Use event subscription to obtain download progress.
downloadProgressSubscription = codePushEventEmitter.addListener(
"CodePushDownloadProgress",
downloadProgressCallback
);
}
// Use the downloaded package info. Native code will save the package info
// so that the client knows what the current package version is.
try {
const downloadedPackage = await NativeCodePush.downloadUpdate(this, !!downloadProgressCallback);
reportStatusDownload && reportStatusDownload(this);
return { ...downloadedPackage, ...local };
} finally {
downloadProgressSubscription && downloadProgressSubscription.remove();
}
},
isPending: false // A remote package could never be in a pending state
};
};
const local = {
async install(installMode = NativeCodePush.codePushInstallModeOnNextRestart, minimumBackgroundDuration = 0, updateInstalledCallback) {
const localPackage = this;
const localPackageCopy = Object.assign({}, localPackage); // In dev mode, React Native deep freezes any object queued over the bridge
await NativeCodePush.installUpdate(localPackageCopy, installMode, minimumBackgroundDuration);
updateInstalledCallback && updateInstalledCallback();
if (installMode == NativeCodePush.codePushInstallModeImmediate) {
RestartManager.restartApp(false);
} else {
RestartManager.clearPendingRestart();
localPackage.isPending = true; // Mark the package as pending since it hasn't been applied yet
}
},
isPending: false // A local package wouldn't be pending until it was installed
};
return { local, remote };
};