mirror of
https://github.com/status-im/react-native.git
synced 2025-01-09 09:12:02 +00:00
3fa648204c
Summary: Xcode 9 has compiler settings that are more strict. This can occur if someone updates there project to use the default settings. This patch declares the default type instead of allowing the compiler to determine it. Instead of `()` we now say `(void)` in a block call. <!-- Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html Happy contributing! --> It was just annoying me, and it has no side effects. If there are side effects, then we should fix the type and not go with empty to represent void. Update project settings in Xcode. This code doesn't have any known side effects since the compiler assumes the type is void when not declared. <!-- Help reviewers and the release process by writing your own release notes **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.** CATEGORY [----------] TYPE [ CLI ] [-------------] LOCATION [ DOCS ] [ BREAKING ] [-------------] [ GENERAl ] [ BUGFIX ] [-{Component}-] [ INTERNAL ] [ ENHANCEMENT ] [ {File} ] [ IOS ] [ FEATURE ] [ {Directory} ] |-----------| [ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} | [----------] [-------------] [-------------] |-----------| [CATEGORY] [TYPE] [LOCATION] - MESSAGE EXAMPLES: [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see --> [DOCS] - Fixed potential compiler build issue on Xcode 9 after updating settings in project. Closes https://github.com/facebook/react-native/pull/16554 Differential Revision: D6184949 Pulled By: shergin fbshipit-source-id: 23083248a39c56f5cf50b5ff4390629dd6335f84
243 lines
7.0 KiB
Objective-C
243 lines
7.0 KiB
Objective-C
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
#import "RCTImageStoreManager.h"
|
|
|
|
#import <stdatomic.h>
|
|
|
|
#import <ImageIO/ImageIO.h>
|
|
#import <MobileCoreServices/UTType.h>
|
|
|
|
#import <React/RCTAssert.h>
|
|
#import <React/RCTLog.h>
|
|
#import <React/RCTUtils.h>
|
|
|
|
#import "RCTImageUtils.h"
|
|
|
|
static NSString *const RCTImageStoreURLScheme = @"rct-image-store";
|
|
|
|
@implementation RCTImageStoreManager
|
|
{
|
|
NSMutableDictionary<NSString *, NSData *> *_store;
|
|
NSUInteger _id;
|
|
}
|
|
|
|
@synthesize methodQueue = _methodQueue;
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
- (float)handlerPriority
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
- (void)removeImageForTag:(NSString *)imageTag withBlock:(void (^)(void))block
|
|
{
|
|
dispatch_async(_methodQueue, ^{
|
|
[self removeImageForTag:imageTag];
|
|
if (block) {
|
|
block();
|
|
}
|
|
});
|
|
}
|
|
|
|
- (NSString *)_storeImageData:(NSData *)imageData
|
|
{
|
|
RCTAssertThread(_methodQueue, @"Must be called on RCTImageStoreManager thread");
|
|
|
|
if (!_store) {
|
|
_store = [NSMutableDictionary new];
|
|
_id = 0;
|
|
}
|
|
|
|
NSString *imageTag = [NSString stringWithFormat:@"%@://%tu", RCTImageStoreURLScheme, _id++];
|
|
_store[imageTag] = imageData;
|
|
return imageTag;
|
|
}
|
|
|
|
- (void)storeImageData:(NSData *)imageData withBlock:(void (^)(NSString *imageTag))block
|
|
{
|
|
RCTAssertParam(block);
|
|
dispatch_async(_methodQueue, ^{
|
|
block([self _storeImageData:imageData]);
|
|
});
|
|
}
|
|
|
|
- (void)getImageDataForTag:(NSString *)imageTag withBlock:(void (^)(NSData *imageData))block
|
|
{
|
|
RCTAssertParam(block);
|
|
dispatch_async(_methodQueue, ^{
|
|
block(self->_store[imageTag]);
|
|
});
|
|
}
|
|
|
|
- (void)storeImage:(UIImage *)image withBlock:(void (^)(NSString *imageTag))block
|
|
{
|
|
RCTAssertParam(block);
|
|
dispatch_async(_methodQueue, ^{
|
|
NSString *imageTag = [self _storeImageData:RCTGetImageData(image, 0.75)];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
block(imageTag);
|
|
});
|
|
});
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(removeImageForTag:(NSString *)imageTag)
|
|
{
|
|
[_store removeObjectForKey:imageTag];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(hasImageForTag:(NSString *)imageTag
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
{
|
|
callback(@[@(_store[imageTag] != nil)]);
|
|
}
|
|
|
|
// TODO (#5906496): Name could be more explicit - something like getBase64EncodedDataForTag:?
|
|
RCT_EXPORT_METHOD(getBase64ForTag:(NSString *)imageTag
|
|
successCallback:(RCTResponseSenderBlock)successCallback
|
|
errorCallback:(RCTResponseErrorBlock)errorCallback)
|
|
{
|
|
NSData *imageData = _store[imageTag];
|
|
if (!imageData) {
|
|
errorCallback(RCTErrorWithMessage([NSString stringWithFormat:@"Invalid imageTag: %@", imageTag]));
|
|
return;
|
|
}
|
|
// Dispatching to a background thread to perform base64 encoding
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
successCallback(@[[imageData base64EncodedStringWithOptions:0]]);
|
|
});
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(addImageFromBase64:(NSString *)base64String
|
|
successCallback:(RCTResponseSenderBlock)successCallback
|
|
errorCallback:(RCTResponseErrorBlock)errorCallback)
|
|
|
|
{
|
|
// Dispatching to a background thread to perform base64 decoding
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
|
|
if (imageData) {
|
|
dispatch_async(self->_methodQueue, ^{
|
|
successCallback(@[[self _storeImageData:imageData]]);
|
|
});
|
|
} else {
|
|
errorCallback(RCTErrorWithMessage(@"Failed to add image from base64String"));
|
|
}
|
|
});
|
|
}
|
|
|
|
#pragma mark - RCTURLRequestHandler
|
|
|
|
- (BOOL)canHandleRequest:(NSURLRequest *)request
|
|
{
|
|
return [request.URL.scheme caseInsensitiveCompare:RCTImageStoreURLScheme] == NSOrderedSame;
|
|
}
|
|
|
|
- (id)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
|
|
{
|
|
__block atomic_bool cancelled = ATOMIC_VAR_INIT(NO);
|
|
void (^cancellationBlock)(void) = ^{
|
|
atomic_store(&cancelled, YES);
|
|
};
|
|
|
|
// Dispatch async to give caller time to cancel the request
|
|
dispatch_async(_methodQueue, ^{
|
|
if (atomic_load(&cancelled)) {
|
|
return;
|
|
}
|
|
|
|
NSString *imageTag = request.URL.absoluteString;
|
|
NSData *imageData = self->_store[imageTag];
|
|
if (!imageData) {
|
|
NSError *error = RCTErrorWithMessage([NSString stringWithFormat:@"Invalid imageTag: %@", imageTag]);
|
|
[delegate URLRequest:cancellationBlock didCompleteWithError:error];
|
|
return;
|
|
}
|
|
|
|
CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
|
|
if (!sourceRef) {
|
|
NSError *error = RCTErrorWithMessage([NSString stringWithFormat:@"Unable to decode data for imageTag: %@", imageTag]);
|
|
[delegate URLRequest:cancellationBlock didCompleteWithError:error];
|
|
return;
|
|
}
|
|
CFStringRef UTI = CGImageSourceGetType(sourceRef);
|
|
CFRelease(sourceRef);
|
|
|
|
NSString *MIMEType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
|
|
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:request.URL
|
|
MIMEType:MIMEType
|
|
expectedContentLength:imageData.length
|
|
textEncodingName:nil];
|
|
|
|
[delegate URLRequest:cancellationBlock didReceiveResponse:response];
|
|
[delegate URLRequest:cancellationBlock didReceiveData:imageData];
|
|
[delegate URLRequest:cancellationBlock didCompleteWithError:nil];
|
|
|
|
});
|
|
|
|
return cancellationBlock;
|
|
}
|
|
|
|
- (void)cancelRequest:(id)requestToken
|
|
{
|
|
if (requestToken) {
|
|
((void (^)(void))requestToken)();
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation RCTImageStoreManager (Deprecated)
|
|
|
|
- (NSString *)storeImage:(UIImage *)image
|
|
{
|
|
RCTAssertMainQueue();
|
|
RCTLogWarn(@"RCTImageStoreManager.storeImage() is deprecated and has poor performance. Use an alternative method instead.");
|
|
__block NSString *imageTag;
|
|
dispatch_sync(_methodQueue, ^{
|
|
imageTag = [self _storeImageData:RCTGetImageData(image, 0.75)];
|
|
});
|
|
return imageTag;
|
|
}
|
|
|
|
- (UIImage *)imageForTag:(NSString *)imageTag
|
|
{
|
|
RCTAssertMainQueue();
|
|
RCTLogWarn(@"RCTImageStoreManager.imageForTag() is deprecated and has poor performance. Use an alternative method instead.");
|
|
__block NSData *imageData;
|
|
dispatch_sync(_methodQueue, ^{
|
|
imageData = self->_store[imageTag];
|
|
});
|
|
return [UIImage imageWithData:imageData];
|
|
}
|
|
|
|
- (void)getImageForTag:(NSString *)imageTag withBlock:(void (^)(UIImage *image))block
|
|
{
|
|
RCTAssertParam(block);
|
|
dispatch_async(_methodQueue, ^{
|
|
NSData *imageData = self->_store[imageTag];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
// imageWithData: is not thread-safe, so we can't do this on methodQueue
|
|
block([UIImage imageWithData:imageData]);
|
|
});
|
|
});
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation RCTBridge (RCTImageStoreManager)
|
|
|
|
- (RCTImageStoreManager *)imageStoreManager
|
|
{
|
|
return [self moduleForClass:[RCTImageStoreManager class]];
|
|
}
|
|
|
|
@end
|