Skip to content

Commit 61c648d

Browse files
committed
Merged RCTNetworkImageView functionality into RCTStaticImage
Summary: RCTNetworkImageView and RCTStaticImage had significant overlap in functionality, but each had a different subset of features and bugs. This diff merges most of the functionality of RCTNetworkImageView into RCTStaticImage, eliminating some bugs in the former, such as constant redrawing when properties were changed. I've also removed the onLoadAbort event for now (as it wasn't implemented), and renamed the other events to match the web specs for `<img>` and XHMLHttpRequest. The API is essentially what Adobe proposed here: http://blogs.adobe.com/webplatform/2012/01/13/html5-image-progress-events/ The following features have not yet been ported from RCTNetworkImageView: - Background color compositing. It's not clear that this adds much value and it increases memory consumption, etc. - Image request cancelling when images are removed from view. Again, it's not clear if this is a huge benefit, but if it is it should be combined with other optimisations, such as unloading offscreen images. (Note that this only affects the open source fork. For now, internal apps will still use FBNetworkImageView for remote images.)
1 parent 82a774e commit 61c648d

17 files changed

+253
-542
lines changed

Examples/UIExplorer/ImageExample.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var NetworkImageExample = React.createClass({
3232
getInitialState: function() {
3333
return {
3434
error: false,
35-
loading: true,
35+
loading: false,
3636
progress: 0
3737
};
3838
},
@@ -47,10 +47,10 @@ var NetworkImageExample = React.createClass({
4747
<Image
4848
source={this.props.source}
4949
style={[styles.base, {overflow: 'visible'}]}
50-
onLoadError={(e) => this.setState({error: e.nativeEvent.error})}
51-
onLoadProgress={(e) => this.setState({progress: Math.max(0, Math.round(100 * e.nativeEvent.written / e.nativeEvent.total))}) }
52-
onLoadEnd={() => this.setState({loading: false, error: false})}
53-
onLoadAbort={() => this.setState({error: 'Loading has aborted'})} >
50+
onLoadStart={(e) => this.setState({loading: true})}
51+
onError={(e) => this.setState({error: e.nativeEvent.error, loading: false})}
52+
onProgress={(e) => this.setState({progress: Math.round(100 * e.nativeEvent.loaded / e.nativeEvent.total)})}
53+
onLoad={() => this.setState({loading: false, error: false})}>
5454
{loader}
5555
</Image>;
5656
}

Libraries/Image/Image.ios.js

Lines changed: 29 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ var StyleSheetPropType = require('StyleSheetPropType');
2424

2525
var flattenStyle = require('flattenStyle');
2626
var invariant = require('invariant');
27-
var merge = require('merge');
2827
var requireNativeComponent = require('requireNativeComponent');
2928
var resolveAssetSource = require('resolveAssetSource');
3029
var verifyPropTypes = require('verifyPropTypes');
@@ -57,6 +56,7 @@ var warning = require('warning');
5756

5857
var Image = React.createClass({
5958
propTypes: {
59+
style: StyleSheetPropType(ImageStylePropTypes),
6060
/**
6161
* `uri` is a string representing the resource identifier for the image, which
6262
* could be an http address, a local file path, or the name of a static image
@@ -93,7 +93,6 @@ var Image = React.createClass({
9393
* image dimensions.
9494
*/
9595
resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']),
96-
style: StyleSheetPropType(ImageStylePropTypes),
9796
/**
9897
* A unique identifier for this element to be used in UI Automation
9998
* testing scripts.
@@ -102,7 +101,7 @@ var Image = React.createClass({
102101
/**
103102
* Invoked on mount and layout changes with
104103
*
105-
* {nativeEvent: { layout: {x, y, width, height}}}.
104+
* {nativeEvent: {layout: {x, y, width, height}}}.
106105
*/
107106
onLayout: PropTypes.func,
108107
/**
@@ -112,25 +111,23 @@ var Image = React.createClass({
112111
/**
113112
* Invoked on download progress with
114113
*
115-
* {nativeEvent: { written, total}}.
116-
*/
117-
onLoadProgress: PropTypes.func,
118-
/**
119-
* Invoked on load abort
114+
* {nativeEvent: {loaded, total}}.
120115
*/
121-
onLoadAbort: PropTypes.func,
116+
onProgress: PropTypes.func,
122117
/**
123118
* Invoked on load error
124119
*
125-
* {nativeEvent: { error}}.
120+
* {nativeEvent: {error}}.
126121
*/
127-
onLoadError: PropTypes.func,
122+
onError: PropTypes.func,
128123
/**
129-
* Invoked on load end
130-
*
124+
* Invoked when load completes successfully
131125
*/
132-
onLoaded: PropTypes.func
133-
126+
onLoad: PropTypes.func,
127+
/**
128+
* Invoked when load either succeeds or fails
129+
*/
130+
onLoadEnd: PropTypes.func,
134131
},
135132

136133
statics: {
@@ -149,46 +146,27 @@ var Image = React.createClass({
149146
},
150147

151148
render: function() {
152-
for (var prop in nativeOnlyProps) {
153-
if (this.props[prop] !== undefined) {
154-
console.warn('Prop `' + prop + ' = ' + this.props[prop] + '` should ' +
155-
'not be set directly on Image.');
156-
}
157-
}
158149
var source = resolveAssetSource(this.props.source) || {};
150+
var defaultSource = (this.props.defaultSource && resolveAssetSource(this.props.defaultSource)) || {};
159151

160152
var {width, height} = source;
161-
var style = flattenStyle([{width, height}, styles.base, this.props.style]);
162-
invariant(style, 'style must be initialized');
153+
var style = flattenStyle([{width, height}, styles.base, this.props.style]) || {};
163154

164155
var isNetwork = source.uri && source.uri.match(/^https?:/);
165-
invariant(
166-
!(isNetwork && source.isStatic),
167-
'static image uris cannot start with "http": "' + source.uri + '"'
156+
var RawImage = isNetwork ? RCTNetworkImageView : RCTImageView;
157+
var resizeMode = this.props.resizeMode || (style || {}).resizeMode || 'cover'; // Workaround for flow bug t7737108
158+
var tintColor = (style || {}).tintColor; // Workaround for flow bug t7737108
159+
160+
return (
161+
<RawImage
162+
{...this.props}
163+
style={style}
164+
resizeMode={resizeMode}
165+
tintColor={tintColor}
166+
src={source.uri}
167+
defaultSrc={defaultSource.uri}
168+
/>
168169
);
169-
var isStored = !source.isStatic && !isNetwork;
170-
var RawImage = isNetwork ? RCTNetworkImage : RCTStaticImage;
171-
172-
if (this.props.style && this.props.style.tintColor) {
173-
warning(RawImage === RCTStaticImage, 'tintColor style only supported on static images.');
174-
}
175-
var resizeMode = this.props.resizeMode || style.resizeMode || 'cover';
176-
177-
var nativeProps = merge(this.props, {
178-
style,
179-
resizeMode,
180-
tintColor: style.tintColor,
181-
});
182-
if (isStored) {
183-
nativeProps.imageTag = source.uri;
184-
} else {
185-
nativeProps.src = source.uri;
186-
}
187-
if (this.props.defaultSource) {
188-
nativeProps.defaultImageSrc = this.props.defaultSource.uri;
189-
}
190-
nativeProps.progressHandlerRegistered = isNetwork && this.props.onLoadProgress;
191-
return <RawImage {...nativeProps} />;
192170
}
193171
});
194172

@@ -198,18 +176,7 @@ var styles = StyleSheet.create({
198176
},
199177
});
200178

201-
var RCTNetworkImage = requireNativeComponent('RCTNetworkImageView', null);
202-
var RCTStaticImage = requireNativeComponent('RCTStaticImage', null);
203-
204-
var nativeOnlyProps = {
205-
src: true,
206-
defaultImageSrc: true,
207-
imageTag: true,
208-
progressHandlerRegistered: true
209-
};
210-
if (__DEV__) {
211-
verifyPropTypes(Image, RCTStaticImage.viewConfig, nativeOnlyProps);
212-
verifyPropTypes(Image, RCTNetworkImage.viewConfig, nativeOnlyProps);
213-
}
179+
var RCTImageView = requireNativeComponent('RCTImageView', null);
180+
var RCTNetworkImageView = (NativeModules.NetworkImageViewManager) ? requireNativeComponent('RCTNetworkImageView', null) : RCTImageView;
214181

215182
module.exports = Image;

Libraries/Image/RCTImage.xcodeproj/project.pbxproj

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@
88

99
/* Begin PBXBuildFile section */
1010
03559E7F1B064DAF00730281 /* RCTDownloadTaskWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 03559E7E1B064DAF00730281 /* RCTDownloadTaskWrapper.m */; };
11-
1304D5AB1AA8C4A30002E2BE /* RCTStaticImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5A81AA8C4A30002E2BE /* RCTStaticImage.m */; };
12-
1304D5AC1AA8C4A30002E2BE /* RCTStaticImageManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5AA1AA8C4A30002E2BE /* RCTStaticImageManager.m */; };
11+
1304D5AB1AA8C4A30002E2BE /* RCTImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5A81AA8C4A30002E2BE /* RCTImageView.m */; };
12+
1304D5AC1AA8C4A30002E2BE /* RCTImageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5AA1AA8C4A30002E2BE /* RCTImageViewManager.m */; };
1313
1304D5B21AA8C50D0002E2BE /* RCTGIFImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1304D5B11AA8C50D0002E2BE /* RCTGIFImage.m */; };
1414
1345A8391B26592900583190 /* RCTImageRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 1345A8381B26592900583190 /* RCTImageRequestHandler.m */; };
1515
134B00A21B54232B00EC8DFB /* RCTImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 134B00A11B54232B00EC8DFB /* RCTImageUtils.m */; };
1616
137620351B31C53500677FF0 /* RCTImagePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 137620341B31C53500677FF0 /* RCTImagePickerManager.m */; };
1717
143879351AAD238D00F088A5 /* RCTCameraRollManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 143879341AAD238D00F088A5 /* RCTCameraRollManager.m */; };
1818
143879381AAD32A300F088A5 /* RCTImageLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 143879371AAD32A300F088A5 /* RCTImageLoader.m */; };
1919
58B5118F1A9E6BD600147676 /* RCTImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B5118A1A9E6BD600147676 /* RCTImageDownloader.m */; };
20-
58B511901A9E6BD600147676 /* RCTNetworkImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B5118C1A9E6BD600147676 /* RCTNetworkImageView.m */; };
21-
58B511911A9E6BD600147676 /* RCTNetworkImageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B5118E1A9E6BD600147676 /* RCTNetworkImageViewManager.m */; };
2220
/* End PBXBuildFile section */
2321

2422
/* Begin PBXCopyFilesBuildPhase section */
@@ -36,10 +34,10 @@
3634
/* Begin PBXFileReference section */
3735
03559E7D1B064D3A00730281 /* RCTDownloadTaskWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTDownloadTaskWrapper.h; sourceTree = "<group>"; };
3836
03559E7E1B064DAF00730281 /* RCTDownloadTaskWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDownloadTaskWrapper.m; sourceTree = "<group>"; };
39-
1304D5A71AA8C4A30002E2BE /* RCTStaticImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTStaticImage.h; sourceTree = "<group>"; };
40-
1304D5A81AA8C4A30002E2BE /* RCTStaticImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTStaticImage.m; sourceTree = "<group>"; };
41-
1304D5A91AA8C4A30002E2BE /* RCTStaticImageManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTStaticImageManager.h; sourceTree = "<group>"; };
42-
1304D5AA1AA8C4A30002E2BE /* RCTStaticImageManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTStaticImageManager.m; sourceTree = "<group>"; };
37+
1304D5A71AA8C4A30002E2BE /* RCTImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageView.h; sourceTree = "<group>"; };
38+
1304D5A81AA8C4A30002E2BE /* RCTImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageView.m; sourceTree = "<group>"; };
39+
1304D5A91AA8C4A30002E2BE /* RCTImageViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageViewManager.h; sourceTree = "<group>"; };
40+
1304D5AA1AA8C4A30002E2BE /* RCTImageViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageViewManager.m; sourceTree = "<group>"; };
4341
1304D5B01AA8C50D0002E2BE /* RCTGIFImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTGIFImage.h; sourceTree = "<group>"; };
4442
1304D5B11AA8C50D0002E2BE /* RCTGIFImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTGIFImage.m; sourceTree = "<group>"; };
4543
1345A8371B26592900583190 /* RCTImageRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageRequestHandler.h; sourceTree = "<group>"; };
@@ -55,10 +53,6 @@
5553
58B5115D1A9E6B3D00147676 /* libRCTImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTImage.a; sourceTree = BUILT_PRODUCTS_DIR; };
5654
58B511891A9E6BD600147676 /* RCTImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageDownloader.h; sourceTree = "<group>"; };
5755
58B5118A1A9E6BD600147676 /* RCTImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageDownloader.m; sourceTree = "<group>"; };
58-
58B5118B1A9E6BD600147676 /* RCTNetworkImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTNetworkImageView.h; sourceTree = "<group>"; };
59-
58B5118C1A9E6BD600147676 /* RCTNetworkImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTNetworkImageView.m; sourceTree = "<group>"; };
60-
58B5118D1A9E6BD600147676 /* RCTNetworkImageViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTNetworkImageViewManager.h; sourceTree = "<group>"; };
61-
58B5118E1A9E6BD600147676 /* RCTNetworkImageViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTNetworkImageViewManager.m; sourceTree = "<group>"; };
6256
/* End PBXFileReference section */
6357

6458
/* Begin PBXFrameworksBuildPhase section */
@@ -89,14 +83,10 @@
8983
137620341B31C53500677FF0 /* RCTImagePickerManager.m */,
9084
1345A8371B26592900583190 /* RCTImageRequestHandler.h */,
9185
1345A8381B26592900583190 /* RCTImageRequestHandler.m */,
92-
58B5118B1A9E6BD600147676 /* RCTNetworkImageView.h */,
93-
58B5118C1A9E6BD600147676 /* RCTNetworkImageView.m */,
94-
58B5118D1A9E6BD600147676 /* RCTNetworkImageViewManager.h */,
95-
58B5118E1A9E6BD600147676 /* RCTNetworkImageViewManager.m */,
96-
1304D5A71AA8C4A30002E2BE /* RCTStaticImage.h */,
97-
1304D5A81AA8C4A30002E2BE /* RCTStaticImage.m */,
98-
1304D5A91AA8C4A30002E2BE /* RCTStaticImageManager.h */,
99-
1304D5AA1AA8C4A30002E2BE /* RCTStaticImageManager.m */,
86+
1304D5A71AA8C4A30002E2BE /* RCTImageView.h */,
87+
1304D5A81AA8C4A30002E2BE /* RCTImageView.m */,
88+
1304D5A91AA8C4A30002E2BE /* RCTImageViewManager.h */,
89+
1304D5AA1AA8C4A30002E2BE /* RCTImageViewManager.m */,
10090
134B00A01B54232B00EC8DFB /* RCTImageUtils.h */,
10191
134B00A11B54232B00EC8DFB /* RCTImageUtils.m */,
10292
58B5115E1A9E6B3D00147676 /* Products */,
@@ -171,15 +161,13 @@
171161
files = (
172162
58B5118F1A9E6BD600147676 /* RCTImageDownloader.m in Sources */,
173163
137620351B31C53500677FF0 /* RCTImagePickerManager.m in Sources */,
174-
58B511911A9E6BD600147676 /* RCTNetworkImageViewManager.m in Sources */,
175-
1304D5AC1AA8C4A30002E2BE /* RCTStaticImageManager.m in Sources */,
164+
1304D5AC1AA8C4A30002E2BE /* RCTImageViewManager.m in Sources */,
176165
1345A8391B26592900583190 /* RCTImageRequestHandler.m in Sources */,
177-
58B511901A9E6BD600147676 /* RCTNetworkImageView.m in Sources */,
178166
1304D5B21AA8C50D0002E2BE /* RCTGIFImage.m in Sources */,
179167
143879351AAD238D00F088A5 /* RCTCameraRollManager.m in Sources */,
180168
143879381AAD32A300F088A5 /* RCTImageLoader.m in Sources */,
181169
03559E7F1B064DAF00730281 /* RCTDownloadTaskWrapper.m in Sources */,
182-
1304D5AB1AA8C4A30002E2BE /* RCTStaticImage.m in Sources */,
170+
1304D5AB1AA8C4A30002E2BE /* RCTImageView.m in Sources */,
183171
134B00A21B54232B00EC8DFB /* RCTImageUtils.m in Sources */,
184172
);
185173
runOnlyForDeploymentPostprocessing = 0;

Libraries/Image/RCTImageDownloader.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,4 @@ typedef void (^RCTImageDownloadCancellationBlock)(void);
4343
progressBlock:(RCTDataProgressBlock)progressBlock
4444
block:(RCTImageDownloadBlock)block;
4545

46-
/**
47-
* Cancel an in-flight download. If multiple requets have been made for the
48-
* same image, only the request that relates to the token passed will be
49-
* cancelled.
50-
*/
51-
- (void)cancelDownload:(RCTImageDownloadCancellationBlock)downloadToken;
52-
5346
@end

Libraries/Image/RCTImageDownloader.m

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ - (instancetype)init
5252
return self;
5353
}
5454

55-
- (RCTImageDownloadCancellationBlock)_downloadDataForURL:(NSURL *)url progressBlock:progressBlock block:(RCTCachedDataDownloadBlock)block
55+
- (RCTImageDownloadCancellationBlock)_downloadDataForURL:(NSURL *)url
56+
progressBlock:progressBlock
57+
block:(RCTCachedDataDownloadBlock)block
5658
{
5759
NSString *const cacheKey = url.absoluteString;
5860

@@ -134,7 +136,9 @@ - (RCTImageDownloadCancellationBlock)_downloadDataForURL:(NSURL *)url progressBl
134136
return [cancel copy];
135137
}
136138

137-
- (RCTImageDownloadCancellationBlock)downloadDataForURL:(NSURL *)url progressBlock:(RCTDataProgressBlock)progressBlock block:(RCTDataDownloadBlock)block
139+
- (RCTImageDownloadCancellationBlock)downloadDataForURL:(NSURL *)url
140+
progressBlock:(RCTDataProgressBlock)progressBlock
141+
block:(RCTDataDownloadBlock)block
138142
{
139143
return [self _downloadDataForURL:url progressBlock:progressBlock block:^(BOOL cached, NSURLResponse *response, NSData *data, NSError *error) {
140144
block(data, error);
@@ -150,24 +154,19 @@ - (RCTImageDownloadCancellationBlock)downloadImageForURL:(NSURL *)url
150154
progressBlock:(RCTDataProgressBlock)progressBlock
151155
block:(RCTImageDownloadBlock)block
152156
{
157+
scale = scale ?: RCTScreenScale();
158+
153159
return [self downloadDataForURL:url progressBlock:progressBlock block:^(NSData *data, NSError *error) {
154160
if (!data || error) {
155161
block(nil, error);
156162
return;
157163
}
158164

159-
if (CGSizeEqualToSize(size, CGSizeZero)) {
160-
// Target size wasn't available yet, so abort image drawing
161-
block(nil, nil);
162-
return;
163-
}
164-
165165
UIImage *image = [UIImage imageWithData:data scale:scale];
166-
if (image) {
166+
if (image && !CGSizeEqualToSize(size, CGSizeZero)) {
167167

168168
// Get scale and size
169-
CGFloat destScale = scale ?: RCTScreenScale();
170-
CGRect imageRect = RCTClipRect(image.size, image.scale, size, destScale, resizeMode);
169+
CGRect imageRect = RCTClipRect(image.size, scale, size, scale, resizeMode);
171170
CGSize destSize = RCTTargetSizeForClipRect(imageRect);
172171

173172
// Opacity optimizations
@@ -183,7 +182,7 @@ - (RCTImageDownloadCancellationBlock)downloadImageForURL:(NSURL *)url
183182
}
184183

185184
// Decompress image at required size
186-
UIGraphicsBeginImageContextWithOptions(destSize, opaque, destScale);
185+
UIGraphicsBeginImageContextWithOptions(destSize, opaque, scale);
187186
if (blendColor) {
188187
[blendColor setFill];
189188
UIRectFill((CGRect){CGPointZero, destSize});
@@ -201,11 +200,4 @@ - (RCTImageDownloadCancellationBlock)downloadImageForURL:(NSURL *)url
201200
}];
202201
}
203202

204-
- (void)cancelDownload:(RCTImageDownloadCancellationBlock)downloadToken
205-
{
206-
if (downloadToken) {
207-
downloadToken();
208-
}
209-
}
210-
211203
@end

Libraries/Image/RCTImageLoader.h

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
@class ALAssetsLibrary;
1313

14+
typedef void (^RCTImageLoaderProgressBlock)(int64_t written, int64_t total);
15+
typedef void (^RCTImageLoaderCompletionBlock)(NSError *error, id /* UIImage or CAAnimation */);
16+
typedef void (^RCTImageLoaderCancellationBlock)(void);
17+
1418
@interface RCTImageLoader : NSObject
1519

1620
/**
@@ -22,22 +26,28 @@
2226
* Can be called from any thread.
2327
* Will always call callback on main thread.
2428
*/
25-
+ (void)loadImageWithTag:(NSString *)imageTag
26-
callback:(void (^)(NSError *error, id /* UIImage or CAAnimation */ image))callback;
29+
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
30+
callback:(RCTImageLoaderCompletionBlock)callback;
2731

2832
/**
2933
* As above, but includes target size, scale and resizeMode, which are used to
3034
* select the optimal dimensions for the loaded image.
3135
*/
32-
+ (void)loadImageWithTag:(NSString *)imageTag
33-
size:(CGSize)size
34-
scale:(CGFloat)scale
35-
resizeMode:(UIViewContentMode)resizeMode
36-
callback:(void (^)(NSError *error, id /* UIImage or CAAnimation */ image))callback;
36+
+ (RCTImageLoaderCancellationBlock)loadImageWithTag:(NSString *)imageTag
37+
size:(CGSize)size
38+
scale:(CGFloat)scale
39+
resizeMode:(UIViewContentMode)resizeMode
40+
progressBlock:(RCTImageLoaderProgressBlock)progress
41+
completionBlock:(RCTImageLoaderCompletionBlock)completion;
3742

3843
/**
3944
* Is the specified image tag an asset library image?
4045
*/
4146
+ (BOOL)isAssetLibraryImage:(NSString *)imageTag;
4247

48+
/**
49+
* Is the specified image tag a remote image?
50+
*/
51+
+ (BOOL)isRemoteImage:(NSString *)imageTag;
52+
4353
@end

0 commit comments

Comments
 (0)