Split JS spec for image loader module
Summary: It turns out the ImageLoader native module has different method signatures on iOS than on Android, so the JS spec we currently have won't work for ANdroid. In this diff I'm splitting up the spec for NativeImageLoader into an Android & iOS versions (similar to PlatformConstants), and updating the Android spec to match the native implementation. I'm also changing `RCTImageLoader` to use the new generated spec, and updating the JS callers (`Image.android.js` and `Image.ios.js`) to use the right one for the platform (instead of importing the untyped `ImageLoader` native module from `react-native`, like we were on Android :-/). This will be a breaking change for anyone who's directly using `NativeImageLoader.js`, but I think most callsites should be using the `Image` component instead. Changelog: [General] [Changed] Split NativeImageLoader into NativeImageLoaderAndroid and NativeImageLoaderIOS Reviewed By: RSNara Differential Revision: D18439538 fbshipit-source-id: 94c796d3fd27800ea17053e963bee51aca921718
This commit is contained in:
Родитель
390546f6ed
Коммит
d37baa78f1
|
@ -1325,36 +1325,84 @@ namespace facebook {
|
|||
namespace react {
|
||||
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderSpecJSI_getSize(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderAndroidSpecJSI_abortRequest(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "abortRequest", @selector(abortRequest:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderAndroidSpecJSI_getSize(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "getSize", @selector(getSize:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderSpecJSI_getSizeWithHeaders(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderAndroidSpecJSI_getSizeWithHeaders(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "getSizeWithHeaders", @selector(getSizeWithHeaders:headers:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderSpecJSI_prefetchImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "prefetchImage", @selector(prefetchImage:resolve:reject:), args, count);
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderAndroidSpecJSI_prefetchImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "prefetchImage", @selector(prefetchImage:requestId:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderSpecJSI_queryCache(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderAndroidSpecJSI_queryCache(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "queryCache", @selector(queryCache:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
|
||||
NativeImageLoaderSpecJSI::NativeImageLoaderSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: ObjCTurboModule("ImageLoader", instance, jsInvoker) {
|
||||
NativeImageLoaderAndroidSpecJSI::NativeImageLoaderAndroidSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: ObjCTurboModule("ImageLoaderAndroid", instance, jsInvoker) {
|
||||
|
||||
methodMap_["getSize"] = MethodMetadata {1, __hostFunction_NativeImageLoaderSpecJSI_getSize};
|
||||
methodMap_["abortRequest"] = MethodMetadata {1, __hostFunction_NativeImageLoaderAndroidSpecJSI_abortRequest};
|
||||
|
||||
|
||||
methodMap_["getSizeWithHeaders"] = MethodMetadata {2, __hostFunction_NativeImageLoaderSpecJSI_getSizeWithHeaders};
|
||||
methodMap_["getSize"] = MethodMetadata {1, __hostFunction_NativeImageLoaderAndroidSpecJSI_getSize};
|
||||
|
||||
|
||||
methodMap_["prefetchImage"] = MethodMetadata {1, __hostFunction_NativeImageLoaderSpecJSI_prefetchImage};
|
||||
methodMap_["getSizeWithHeaders"] = MethodMetadata {2, __hostFunction_NativeImageLoaderAndroidSpecJSI_getSizeWithHeaders};
|
||||
|
||||
|
||||
methodMap_["queryCache"] = MethodMetadata {1, __hostFunction_NativeImageLoaderSpecJSI_queryCache};
|
||||
methodMap_["prefetchImage"] = MethodMetadata {2, __hostFunction_NativeImageLoaderAndroidSpecJSI_prefetchImage};
|
||||
|
||||
|
||||
methodMap_["queryCache"] = MethodMetadata {1, __hostFunction_NativeImageLoaderAndroidSpecJSI_queryCache};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderIOSSpecJSI_getSize(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "getSize", @selector(getSize:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderIOSSpecJSI_getSizeWithHeaders(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "getSizeWithHeaders", @selector(getSizeWithHeaders:headers:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderIOSSpecJSI_prefetchImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "prefetchImage", @selector(prefetchImage:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativeImageLoaderIOSSpecJSI_queryCache(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "queryCache", @selector(queryCache:resolve:reject:), args, count);
|
||||
}
|
||||
|
||||
|
||||
NativeImageLoaderIOSSpecJSI::NativeImageLoaderIOSSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<CallInvoker> jsInvoker)
|
||||
: ObjCTurboModule("ImageLoaderIOS", instance, jsInvoker) {
|
||||
|
||||
methodMap_["getSize"] = MethodMetadata {1, __hostFunction_NativeImageLoaderIOSSpecJSI_getSize};
|
||||
|
||||
|
||||
methodMap_["getSizeWithHeaders"] = MethodMetadata {2, __hostFunction_NativeImageLoaderIOSSpecJSI_getSizeWithHeaders};
|
||||
|
||||
|
||||
methodMap_["prefetchImage"] = MethodMetadata {1, __hostFunction_NativeImageLoaderIOSSpecJSI_prefetchImage};
|
||||
|
||||
|
||||
methodMap_["queryCache"] = MethodMetadata {1, __hostFunction_NativeImageLoaderIOSSpecJSI_queryCache};
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1466,7 +1466,39 @@ namespace facebook {
|
|||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@protocol NativeImageLoaderSpec <RCTBridgeModule, RCTTurboModule>
|
||||
@protocol NativeImageLoaderAndroidSpec <RCTBridgeModule, RCTTurboModule>
|
||||
|
||||
- (void)abortRequest:(double)requestId;
|
||||
- (void)getSize:(NSString *)uri
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject;
|
||||
- (void)getSizeWithHeaders:(NSString *)uri
|
||||
headers:(NSDictionary *)headers
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject;
|
||||
- (void)prefetchImage:(NSString *)uri
|
||||
requestId:(double)requestId
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject;
|
||||
- (void)queryCache:(NSArray *)uris
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject;
|
||||
|
||||
@end
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
/**
|
||||
* ObjC++ class for module 'ImageLoaderAndroid'
|
||||
*/
|
||||
|
||||
class JSI_EXPORT NativeImageLoaderAndroidSpecJSI : public ObjCTurboModule {
|
||||
public:
|
||||
NativeImageLoaderAndroidSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<CallInvoker> jsInvoker);
|
||||
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@protocol NativeImageLoaderIOSSpec <RCTBridgeModule, RCTTurboModule>
|
||||
|
||||
- (void)getSize:(NSString *)uri
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
|
@ -1486,12 +1518,12 @@ namespace facebook {
|
|||
namespace facebook {
|
||||
namespace react {
|
||||
/**
|
||||
* ObjC++ class for module 'ImageLoader'
|
||||
* ObjC++ class for module 'ImageLoaderIOS'
|
||||
*/
|
||||
|
||||
class JSI_EXPORT NativeImageLoaderSpecJSI : public ObjCTurboModule {
|
||||
class JSI_EXPORT NativeImageLoaderIOSSpecJSI : public ObjCTurboModule {
|
||||
public:
|
||||
NativeImageLoaderSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<CallInvoker> jsInvoker);
|
||||
NativeImageLoaderIOSSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<CallInvoker> jsInvoker);
|
||||
|
||||
};
|
||||
} // namespace react
|
||||
|
|
|
@ -14,7 +14,6 @@ const DeprecatedImageStylePropTypes = require('../DeprecatedPropTypes/Deprecated
|
|||
const DeprecatedStyleSheetPropType = require('../DeprecatedPropTypes/DeprecatedStyleSheetPropType');
|
||||
const DeprecatedViewPropTypes = require('../DeprecatedPropTypes/DeprecatedViewPropTypes');
|
||||
const ImageViewNativeComponent = require('./ImageViewNativeComponent');
|
||||
const NativeModules = require('../BatchedBridge/NativeModules');
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
const ReactNative = require('../Renderer/shims/ReactNative'); // eslint-disable-line no-unused-vars
|
||||
|
@ -24,7 +23,7 @@ const TextAncestor = require('../Text/TextAncestor');
|
|||
const flattenStyle = require('../StyleSheet/flattenStyle');
|
||||
const resolveAssetSource = require('./resolveAssetSource');
|
||||
|
||||
const {ImageLoader} = NativeModules;
|
||||
import NativeImageLoaderAndroid from './NativeImageLoaderAndroid';
|
||||
|
||||
const TextInlineImageNativeComponent = require('./TextInlineImageNativeComponent');
|
||||
|
||||
|
@ -149,7 +148,7 @@ function getSize(
|
|||
success: (width: number, height: number) => void,
|
||||
failure?: (error: any) => void,
|
||||
): any {
|
||||
return ImageLoader.getSize(url)
|
||||
return NativeImageLoaderAndroid.getSize(url)
|
||||
.then(function(sizes) {
|
||||
success(sizes.width, sizes.height);
|
||||
})
|
||||
|
@ -173,7 +172,7 @@ function getSizeWithHeaders(
|
|||
success: (width: number, height: number) => void,
|
||||
failure?: (error: any) => void,
|
||||
): any {
|
||||
return ImageLoader.getSizeWithHeaders(url, headers)
|
||||
return NativeImageLoaderAndroid.getSizeWithHeaders(url, headers)
|
||||
.then(function(sizes) {
|
||||
success(sizes.width, sizes.height);
|
||||
})
|
||||
|
@ -188,11 +187,11 @@ function getSizeWithHeaders(
|
|||
function prefetch(url: string, callback: ?Function): any {
|
||||
const requestId = generateRequestId();
|
||||
callback && callback(requestId);
|
||||
return ImageLoader.prefetchImage(url, requestId);
|
||||
return NativeImageLoaderAndroid.prefetchImage(url, requestId);
|
||||
}
|
||||
|
||||
function abortPrefetch(requestId: number) {
|
||||
ImageLoader.abortRequest(requestId);
|
||||
NativeImageLoaderAndroid.abortRequest(requestId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,7 +202,7 @@ function abortPrefetch(requestId: number) {
|
|||
async function queryCache(
|
||||
urls: Array<string>,
|
||||
): Promise<{[string]: 'memory' | 'disk' | 'disk/memory'}> {
|
||||
return await ImageLoader.queryCache(urls);
|
||||
return await NativeImageLoaderAndroid.queryCache(urls);
|
||||
}
|
||||
|
||||
type ImageComponentStatics = $ReadOnly<{|
|
||||
|
|
|
@ -24,7 +24,7 @@ import type {ImageProps as ImagePropsType} from './ImageProps';
|
|||
import type {HostComponent} from '../Renderer/shims/ReactNativeTypes';
|
||||
|
||||
import type {ImageStyleProp} from '../StyleSheet/StyleSheet';
|
||||
import NativeImageLoader from './NativeImageLoader';
|
||||
import NativeImageLoaderIOS from './NativeImageLoaderIOS';
|
||||
|
||||
const ImageViewManager = NativeModules.ImageViewManager;
|
||||
const RCTImageView: HostComponent<mixed> = requireNativeComponent(
|
||||
|
@ -36,7 +36,7 @@ function getSize(
|
|||
success: (width: number, height: number) => void,
|
||||
failure?: (error: any) => void,
|
||||
) {
|
||||
NativeImageLoader.getSize(uri)
|
||||
NativeImageLoaderIOS.getSize(uri)
|
||||
.then(([width, height]) => success(width, height))
|
||||
.catch(
|
||||
failure ||
|
||||
|
@ -52,7 +52,7 @@ function getSizeWithHeaders(
|
|||
success: (width: number, height: number) => void,
|
||||
failure?: (error: any) => void,
|
||||
): any {
|
||||
return NativeImageLoader.getSizeWithHeaders(uri, headers)
|
||||
return NativeImageLoaderIOS.getSizeWithHeaders(uri, headers)
|
||||
.then(function(sizes) {
|
||||
success(sizes.width, sizes.height);
|
||||
})
|
||||
|
@ -65,13 +65,13 @@ function getSizeWithHeaders(
|
|||
}
|
||||
|
||||
function prefetch(url: string): any {
|
||||
return NativeImageLoader.prefetchImage(url);
|
||||
return NativeImageLoaderIOS.prefetchImage(url);
|
||||
}
|
||||
|
||||
async function queryCache(
|
||||
urls: Array<string>,
|
||||
): Promise<{[string]: 'memory' | 'disk' | 'disk/memory'}> {
|
||||
return await NativeImageLoader.queryCache(urls);
|
||||
return await NativeImageLoaderIOS.queryCache(urls);
|
||||
}
|
||||
|
||||
type ImageComponentStatics = $ReadOnly<{|
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+abortRequest: (requestId: number) => void;
|
||||
+getConstants: () => {||};
|
||||
+getSize: (
|
||||
uri: string,
|
||||
) => Promise<$ReadOnly<{width: number, height: number}>>;
|
||||
+getSizeWithHeaders: (
|
||||
uri: string,
|
||||
headers: Object,
|
||||
) => Promise<{width: number, height: number}>;
|
||||
+prefetchImage: (uri: string, requestId: number) => Promise<boolean>;
|
||||
+queryCache: (uris: Array<string>) => Promise<Object>;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.getEnforcing<Spec>('ImageLoader'): Spec);
|
|
@ -28,7 +28,7 @@ static NSInteger RCTImageBytesForImage(UIImage *image)
|
|||
return image.images ? image.images.count * singleImageBytes : singleImageBytes;
|
||||
}
|
||||
|
||||
@interface RCTImageLoader() <NativeImageLoaderSpec>
|
||||
@interface RCTImageLoader() <NativeImageLoaderIOSSpec>
|
||||
|
||||
@end
|
||||
|
||||
|
@ -946,7 +946,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image,
|
|||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModuleWithJsInvoker:
|
||||
(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return std::make_shared<facebook::react::NativeImageLoaderSpecJSI>(self, jsInvoker);
|
||||
return std::make_shared<facebook::react::NativeImageLoaderIOSSpecJSI>(self, jsInvoker);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getSize:(NSString *)uri resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
*
|
||||
* <p>Generated by an internal genrule from Flow types.
|
||||
*
|
||||
* @generated
|
||||
* @nolint
|
||||
*/
|
||||
|
||||
package com.facebook.fbreact.specs;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReactModuleWithSpec;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
||||
|
||||
public abstract class NativeImageLoaderAndroidSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule {
|
||||
public NativeImageLoaderAndroidSpec(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public abstract void getSize(String uri, Promise promise);
|
||||
|
||||
@ReactMethod
|
||||
public abstract void abortRequest(double requestId);
|
||||
|
||||
@ReactMethod
|
||||
public abstract void prefetchImage(String uri, double requestId, Promise promise);
|
||||
|
||||
@ReactMethod
|
||||
public abstract void queryCache(ReadableArray uris, Promise promise);
|
||||
|
||||
@ReactMethod
|
||||
public abstract void getSizeWithHeaders(String uri, ReadableMap headers, Promise promise);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
*
|
||||
* <p>Generated by an internal genrule from Flow types.
|
||||
*
|
||||
* @generated
|
||||
* @nolint
|
||||
*/
|
||||
|
||||
package com.facebook.fbreact.specs;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReactModuleWithSpec;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
||||
|
||||
public abstract class NativeImageLoaderIOSSpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule {
|
||||
public NativeImageLoaderIOSSpec(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public abstract void getSize(String uri, Promise promise);
|
||||
|
||||
@ReactMethod
|
||||
public abstract void prefetchImage(String uri, Promise promise);
|
||||
|
||||
@ReactMethod
|
||||
public abstract void queryCache(ReadableArray uris, Promise promise);
|
||||
|
||||
@ReactMethod
|
||||
public abstract void getSizeWithHeaders(String uri, ReadableMap headers, Promise promise);
|
||||
}
|
Загрузка…
Ссылка в новой задаче