Skip to content

Commit 89db1a6

Browse files
committed
Updates from Tue Feb 17
- [ReactNative] Make run on iOS7 again | Philipp von Weitershausen - [ReactNative] Make it possible to use fbobjc's RKJSModules for ReactAndroid | Philipp von Weitershausen - [React Native] Add image/network cache | Alex Akers - [ReactNative] Sync fbandroid to fbobjc | Philipp von Weitershausen
1 parent 3d9d8e6 commit 89db1a6

File tree

8 files changed

+376
-84
lines changed

8 files changed

+376
-84
lines changed

Libraries/Components/Text/TextStylePropTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var TextStylePropTypes = merge(
1515
fontFamily: ReactPropTypes.string,
1616
fontSize: ReactPropTypes.number,
1717
fontWeight: ReactPropTypes.oneOf(['normal' /*default*/, 'bold']),
18+
fontStyle: ReactPropTypes.oneOf(['normal', 'italic']),
1819
lineHeight: ReactPropTypes.number,
1920
color: ReactPropTypes.string,
2021
containerBackgroundColor: ReactPropTypes.string,

ReactKit/Base/RCTCache.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2004-present Facebook. All Rights Reserved.
2+
3+
#import <Foundation/Foundation.h>
4+
5+
@interface RCTCache : NSObject
6+
7+
- (instancetype)init; // name = @"default"
8+
- (instancetype)initWithName:(NSString *)name;
9+
10+
@property (nonatomic, assign) NSUInteger maximumDiskSize; // in bytes
11+
12+
#pragma mark - Retrieval
13+
14+
- (BOOL)hasDataForKey:(NSString *)key;
15+
- (void)fetchDataForKey:(NSString *)key completionHandler:(void (^)(NSData *data))completionHandler;
16+
17+
#pragma mark - Insertion
18+
19+
- (void)setData:(NSData *)data forKey:(NSString *)key;
20+
- (void)removeAllData;
21+
22+
@end

ReactKit/Base/RCTCache.m

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
// Copyright 2004-present Facebook. All Rights Reserved.
2+
3+
#import "RCTCache.h"
4+
5+
#import <UIKit/UIKit.h>
6+
#import <sys/xattr.h>
7+
8+
static NSString *const CacheSubdirectoryName = @"ReactKit";
9+
static NSString *const KeyExtendedAttributeName = @"com.facebook.ReactKit.RCTCacheManager.Key";
10+
static dispatch_queue_t Queue;
11+
12+
#pragma mark - Cache Record -
13+
14+
@interface RCTCacheRecord : NSObject
15+
16+
@property (nonatomic, copy) NSUUID *UUID;
17+
@property (nonatomic, copy) NSData *data;
18+
19+
@end
20+
21+
@implementation RCTCacheRecord
22+
23+
@end
24+
25+
#pragma mark - Cache
26+
27+
@implementation RCTCache
28+
{
29+
NSString *_name;
30+
NSFileManager *_fileManager;
31+
NSMutableDictionary *_storage;
32+
NSURL *_cacheDirectoryURL;
33+
}
34+
35+
+ (void)initialize
36+
{
37+
if (self == [RCTCache class]) {
38+
Queue = dispatch_queue_create("com.facebook.ReactKit.RCTCache", DISPATCH_QUEUE_SERIAL);
39+
}
40+
}
41+
- (instancetype)init
42+
{
43+
return [self initWithName:@"default"];
44+
}
45+
46+
- (instancetype)initWithName:(NSString *)name
47+
{
48+
NSParameterAssert(name.length < NAME_MAX);
49+
if ((self = [super init])) {
50+
_name = [name copy];
51+
_fileManager = [[NSFileManager alloc] init];
52+
_storage = [NSMutableDictionary dictionary];
53+
54+
NSURL *cacheDirectoryURL = [[_fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
55+
cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:CacheSubdirectoryName isDirectory:YES];
56+
_cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:name isDirectory:YES];
57+
[_fileManager createDirectoryAtURL:_cacheDirectoryURL withIntermediateDirectories:YES attributes:nil error:NULL];
58+
59+
NSArray *fileURLs = [_fileManager contentsOfDirectoryAtURL:_cacheDirectoryURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsHiddenFiles error:NULL];
60+
for (NSURL *fileURL in fileURLs) {
61+
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:fileURL.lastPathComponent];
62+
if (!uuid) continue;
63+
64+
NSString *key = [self keyOfItemAtURL:fileURL error:NULL];
65+
if (!key) {
66+
[_fileManager removeItemAtURL:fileURL error:NULL];
67+
continue;
68+
}
69+
70+
RCTCacheRecord *record = [[RCTCacheRecord alloc] init];
71+
record.UUID = uuid;
72+
_storage[key] = record;
73+
}
74+
}
75+
return self;
76+
}
77+
78+
- (void)runOnQueue:(dispatch_block_t)block
79+
{
80+
UIBackgroundTaskIdentifier identifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
81+
dispatch_async(Queue, ^{
82+
if (block) block();
83+
if (identifier != UIBackgroundTaskInvalid) {
84+
[[UIApplication sharedApplication] endBackgroundTask:identifier];
85+
}
86+
});
87+
}
88+
89+
- (BOOL)hasDataForKey:(NSString *)key
90+
{
91+
return _storage[key] != nil;
92+
}
93+
94+
- (void)fetchDataForKey:(NSString *)key completionHandler:(void (^)(NSData *))completionHandler
95+
{
96+
NSParameterAssert(key.length > 0);
97+
NSParameterAssert(completionHandler != nil);
98+
[self runOnQueue:^{
99+
RCTCacheRecord *record = _storage[key];
100+
if (record && !record.data) {
101+
record.data = [NSData dataWithContentsOfURL:[_cacheDirectoryURL URLByAppendingPathComponent:record.UUID.UUIDString]];
102+
}
103+
104+
dispatch_async(dispatch_get_main_queue(), ^{
105+
completionHandler(record.data);
106+
});
107+
}];
108+
}
109+
110+
- (void)setData:(NSData *)data forKey:(NSString *)key
111+
{
112+
NSParameterAssert(key.length > 0);
113+
[self runOnQueue:^{
114+
RCTCacheRecord *record = _storage[key];
115+
if (data) {
116+
if (!record) {
117+
record = [[RCTCacheRecord alloc] init];
118+
record.UUID = [NSUUID UUID];
119+
_storage[key] = record;
120+
}
121+
122+
record.data = data;
123+
124+
NSURL *fileURL = [_cacheDirectoryURL URLByAppendingPathComponent:record.UUID.UUIDString];
125+
[data writeToURL:fileURL options:NSDataWritingAtomic error:NULL];
126+
} else if (record) {
127+
[_storage removeObjectForKey:key];
128+
129+
NSURL *fileURL = [_cacheDirectoryURL URLByAppendingPathComponent:record.UUID.UUIDString];
130+
[_fileManager removeItemAtURL:fileURL error:NULL];
131+
}
132+
}];
133+
}
134+
135+
- (void)removeAllData
136+
{
137+
[self runOnQueue:^{
138+
[_storage removeAllObjects];
139+
140+
NSDirectoryEnumerator *enumerator = [_fileManager enumeratorAtURL:_cacheDirectoryURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsHiddenFiles errorHandler:nil];
141+
for (NSURL *fileURL in enumerator) {
142+
[_fileManager removeItemAtURL:fileURL error:NULL];
143+
}
144+
}];
145+
}
146+
147+
#pragma mark - Extended Attributes
148+
149+
- (NSError *)errorWithPOSIXErrorNumber:(int)errorNumber
150+
{
151+
NSDictionary *userInfo = @{
152+
NSLocalizedDescriptionKey: @(strerror(errorNumber))
153+
};
154+
return [NSError errorWithDomain:NSPOSIXErrorDomain code:errorNumber userInfo:userInfo];
155+
}
156+
157+
- (BOOL)setAttribute:(NSString *)key value:(NSString *)value ofItemAtURL:(NSURL *)fileURL error:(NSError **)error
158+
{
159+
const char *path = fileURL.fileSystemRepresentation;
160+
161+
int result;
162+
if (value) {
163+
const char *valueUTF8String = value.UTF8String;
164+
result = setxattr(path, key.UTF8String, valueUTF8String, strlen(valueUTF8String), 0, 0);
165+
} else {
166+
result = removexattr(path, key.UTF8String, 0);
167+
}
168+
169+
if (result) {
170+
if (error) *error = [self errorWithPOSIXErrorNumber:errno];
171+
return NO;
172+
}
173+
174+
return YES;
175+
}
176+
177+
- (NSString *)attribute:(NSString *)key ofItemAtURL:(NSURL *)fileURL error:(NSError **)error
178+
{
179+
const char *path = fileURL.fileSystemRepresentation;
180+
const ssize_t length = getxattr(path, key.UTF8String, NULL, 0, 0, 0);
181+
if (length <= 0) {
182+
if (error) *error = [self errorWithPOSIXErrorNumber:errno];
183+
return nil;
184+
}
185+
186+
char *buffer = malloc(length);
187+
ssize_t result = getxattr(path, key.UTF8String, buffer, length, 0, 0);
188+
if (result == 0) {
189+
return [[NSString alloc] initWithBytesNoCopy:buffer length:length encoding:NSUTF8StringEncoding freeWhenDone:YES];
190+
}
191+
192+
free(buffer);
193+
if (error) *error = [self errorWithPOSIXErrorNumber:errno];
194+
return nil;
195+
}
196+
197+
#pragma mark - Extended Attributes - Key
198+
199+
- (NSString *)keyOfItemAtURL:(NSURL *)fileURL error:(NSError **)error
200+
{
201+
return [self attribute:KeyExtendedAttributeName ofItemAtURL:fileURL error:error];
202+
}
203+
204+
- (BOOL)setKey:(NSString *)key ofItemAtURL:(NSURL *)fileURL error:(NSError **)error
205+
{
206+
return [self setAttribute:KeyExtendedAttributeName value:key ofItemAtURL:fileURL error:error];
207+
}
208+
209+
@end

ReactKit/Base/RCTConvert.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ BOOL RCTSetProperty(id target, NSString *keypath, id value)
814814

815815
// Special case for numeric encodings, which may be enums
816816
if ([value isKindOfClass:[NSString class]] &&
817-
[@"iIsSlLqQ" containsString:[encoding substringToIndex:1]]) {
817+
[@"iIsSlLqQ" rangeOfString:[encoding substringToIndex:1]].length) {
818818

819819
/**
820820
* NOTE: the property names below may seem weird, but it's

0 commit comments

Comments
 (0)