resolve iOS assets from embedded bundle path for iOS platform

Reviewed By: zahanm

Differential Revision: D6193907

fbshipit-source-id: 09c76a5c3d6a7777a9a823c21bfcc0fe344bc83e
This commit is contained in:
Yujie Liu 2017-11-09 18:48:11 -08:00 committed by Facebook Github Bot
parent 45185947ee
commit a329e968fc
2 changed files with 48 additions and 15 deletions

View File

@ -52,12 +52,19 @@ class AssetSourceResolver {
serverUrl: ?string;
// where the jsbundle is being run from
jsbundleUrl: ?string;
// where the embedded bundle in the app is stored
embeddedBundleUrl: ?string;
// the asset to resolve
asset: PackagerAsset;
constructor(serverUrl: ?string, jsbundleUrl: ?string, asset: PackagerAsset) {
constructor(serverUrl: ?string,
jsbundleUrl: ?string,
embeddedBundleUrl: ?string,
asset: PackagerAsset
) {
this.serverUrl = serverUrl;
this.jsbundleUrl = jsbundleUrl;
this.embeddedBundleUrl = embeddedBundleUrl;
this.asset = asset;
}
@ -69,6 +76,10 @@ class AssetSourceResolver {
return !!this.jsbundleUrl;
}
canLoadFromEmbeddedBundledLocation(): boolean {
return !!this.embeddedBundleUrl;
}
defaultAsset(): ResolvedAssetSource {
if (this.isLoadedFromServer()) {
return this.assetServerURL();
@ -112,6 +123,15 @@ class AssetSourceResolver {
return this.fromSource(path + getScaledAssetPath(this.asset));
}
/**
* Resolves to the asset that was bundled with the app, with a scaled asset filename
* E.g. 'file:///sdcard/bundle/assets/AwesomeModule/icon@2x.png'
*/
scaledAssetURLInEmbeddedBundleUrl(): ResolvedAssetSource {
const path = this.embeddedBundleUrl || 'file://';
return this.fromSource(path + getScaledAssetPath(this.asset));
}
/**
* The default location of assets bundled with the app, located by
* resource identifier

View File

@ -19,7 +19,7 @@ const NativeModules = require('NativeModules');
import type { ResolvedAssetSource } from 'AssetSourceResolver';
let _customSourceTransformer, _serverURL, _scriptURL;
let _customSourceTransformer, _serverURL, _scriptURL, _embeddedBundleURL;
function getDevServerURL(): ?string {
if (_serverURL === undefined) {
@ -36,30 +36,38 @@ function getDevServerURL(): ?string {
return _serverURL;
}
function getScriptURL(): ?string {
if (_scriptURL === undefined) {
const scriptURL = NativeModules.SourceCode.scriptURL;
if (!scriptURL) {
// scriptURL is falsy, we have nothing to go on here
_scriptURL = null;
return _scriptURL;
}
function _coerceLocalScriptURL(scriptURL: ?string): ?string {
if (scriptURL) {
if (scriptURL.startsWith('assets://')) {
// android: running from within assets, no offline path to use
_scriptURL = null;
return _scriptURL;
return null;
}
_scriptURL = scriptURL.substring(0, scriptURL.lastIndexOf('/') + 1);
scriptURL = scriptURL.substring(0, scriptURL.lastIndexOf('/') + 1);
if (!scriptURL.startsWith('file://')) {
// Add file protocol in case we have an absolute file path and not a URL.
// This shouldn't really be necessary. scriptURL should be a URL.
_scriptURL = 'file://' + _scriptURL;
scriptURL = 'file://' + scriptURL;
}
}
return scriptURL;
}
function getScriptURL(): ?string {
if (_scriptURL === undefined) {
const scriptURL = NativeModules.SourceCode.scriptURL;
_scriptURL = _coerceLocalScriptURL(scriptURL);
}
return _scriptURL;
}
function getEmbeddedBundledURL(): ?string {
if (_embeddedBundleURL === undefined) {
const scriptURL = NativeModules.SourceCode.embeddedBundleURL;
_embeddedBundleURL = _coerceLocalScriptURL(scriptURL);
}
return _embeddedBundleURL;
}
function setCustomSourceTransformer(
transformer: (resolver: AssetSourceResolver) => ResolvedAssetSource,
): void {
@ -80,7 +88,12 @@ function resolveAssetSource(source: any): ?ResolvedAssetSource {
return null;
}
const resolver = new AssetSourceResolver(getDevServerURL(), getScriptURL(), asset);
const resolver = new AssetSourceResolver(
getDevServerURL(),
getScriptURL(),
getEmbeddedBundledURL(),
asset,
);
if (_customSourceTransformer) {
return _customSourceTransformer(resolver);
}