mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
8131b7bb7b
Summary: This is my proposal for fixing `use_frameworks!` compatibility without breaking all `<React/*>` imports I outlined in https://github.com/facebook/react-native/pull/25393#issuecomment-508457700. If accepted, it will fix https://github.com/facebook/react-native/issues/25349. It builds on the changes I made in https://github.com/facebook/react-native/pull/25496 by ensuring each podspec has a unique value for `header_dir` so that framework imports do not conflict. Every podspec which should be included in the `<React/*>` namespace now includes it's headers from `React-Core.podspec`. The following pods can still be imported with `<React/*>` and so should not have breaking changes: `React-ART`,`React-DevSupport`, `React-CoreModules`, `React-RCTActionSheet`, `React-RCTAnimation`, `React-RCTBlob`, `React-RCTImage`, `React-RCTLinking`, `React-RCTNetwork`, `React-RCTPushNotification`, `React-RCTSettings`, `React-RCTText`, `React-RCTSettings`, `React-RCTVibration`, `React-RCTWebSocket` . There are still a few breaking changes which I hope will be acceptable: - `React-Core.podspec` has been moved to the root of the project. Any `Podfile` that references it will need to update the path. - ~~`React-turbomodule-core`'s headers now live under `<turbomodule/*>`~~ Replaced by https://github.com/facebook/react-native/pull/25619#issuecomment-511091823. - ~~`React-turbomodulesamples`'s headers now live under `<turbomodulesamples/*>`~~ Replaced by https://github.com/facebook/react-native/pull/25619#issuecomment-511091823. - ~~`React-TypeSaferty`'s headers now live under `<TypeSafety/*>`~~ Replaced by https://github.com/facebook/react-native/pull/25619#issuecomment-511040967. - ~~`React-jscallinvoker`'s headers now live under `<jscallinvoker/*>`~~ Replaced by https://github.com/facebook/react-native/pull/25619#issuecomment-511091823. - Each podspec now uses `s.static_framework = true`. This means that a minimum of CocoaPods 1.5 ([released in April 2018](http://blog.cocoapods.org/CocoaPods-1.5.0/)) is now required. This is needed so that the ` __has_include` conditions can still work when frameworks are enabled. Still to do: - ~~Including `React-turbomodule-core` with `use_frameworks!` enabled causes the C++ import failures we saw in https://github.com/facebook/react-native/issues/25349. I'm sure it will be possible to fix this but I need to dig deeper (perhaps a custom modulemap would be needed).~~ Addressed by https://github.com/facebook/react-native/pull/25619/commits/33573511f02f3502a28bad48e085e9a4b8608302. - I haven't got Fabric working yet. I wonder if it would be acceptable to move Fabric out of the `<React/*>` namespace since it is new? � ## Changelog [iOS] [Fixed] - Fixed compatibility with CocoaPods frameworks. Pull Request resolved: https://github.com/facebook/react-native/pull/25619 Test Plan: ### FB ``` buck build catalyst ``` ### Sample Project Everything should work exactly as before, where `use_frameworks!` is not in `Podfile`s. I have a branch on my [sample project](https://github.com/jtreanor/react-native-cocoapods-frameworks) here which has `use_frameworks!` in its `Podfile` to demonstrate this is fixed. You can see that it works with these steps: 1. `git clone git@github.com:jtreanor/react-native-cocoapods-frameworks.git` 2. `git checkout fix-frameworks-subspecs` 3. `cd ios && pod install` 4. `cd .. && react-native run-ios` The sample app will build and run successfully. To see that it still works without frameworks, remove `use_frameworks!` from the `Podfile` and do steps 3 and 4 again. ### RNTesterPods `RNTesterPodsPods` can now work with or without `use_frameworks!`. 1. Go to the `RNTester` directory and run `pod install`. 2. Run the tests in `RNTesterPods.xcworkspace` to see that everything still works fine. 3. Uncomment the `use_frameworks!` line at the top of `RNTester/Podfile` and run `pod install` again. 4. Run the tests again and see that it still works with frameworks enabled. Reviewed By: PeteTheHeat Differential Revision: D16465247 Pulled By: PeteTheHeat fbshipit-source-id: cad837e9cced06d30cc5b372af1c65c7780b9e7a
172 lines
6.2 KiB
Objective-C
172 lines
6.2 KiB
Objective-C
/**
|
|
* 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.
|
|
*/
|
|
|
|
#import <React/RCTInterpolationAnimatedNode.h>
|
|
|
|
#import <React/RCTAnimationUtils.h>
|
|
|
|
static NSRegularExpression *regex;
|
|
|
|
@implementation RCTInterpolationAnimatedNode
|
|
{
|
|
__weak RCTValueAnimatedNode *_parentNode;
|
|
NSArray<NSNumber *> *_inputRange;
|
|
NSArray<NSNumber *> *_outputRange;
|
|
NSArray<NSArray<NSNumber *> *> *_outputs;
|
|
NSArray<NSString *> *_soutputRange;
|
|
NSString *_extrapolateLeft;
|
|
NSString *_extrapolateRight;
|
|
NSUInteger _numVals;
|
|
bool _hasStringOutput;
|
|
bool _shouldRound;
|
|
NSArray<NSTextCheckingResult*> *_matches;
|
|
}
|
|
|
|
- (instancetype)initWithTag:(NSNumber *)tag
|
|
config:(NSDictionary<NSString *, id> *)config
|
|
{
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
NSString *fpRegex = @"[+-]?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?";
|
|
regex = [NSRegularExpression regularExpressionWithPattern:fpRegex options:NSRegularExpressionCaseInsensitive error:nil];
|
|
});
|
|
if ((self = [super initWithTag:tag config:config])) {
|
|
_inputRange = [config[@"inputRange"] copy];
|
|
NSMutableArray *outputRange = [NSMutableArray array];
|
|
NSMutableArray *soutputRange = [NSMutableArray array];
|
|
NSMutableArray<NSMutableArray<NSNumber *> *> *_outputRanges = [NSMutableArray array];
|
|
|
|
_hasStringOutput = NO;
|
|
for (id value in config[@"outputRange"]) {
|
|
if ([value isKindOfClass:[NSNumber class]]) {
|
|
[outputRange addObject:value];
|
|
} else if ([value isKindOfClass:[NSString class]]) {
|
|
/**
|
|
* Supports string shapes by extracting numbers so new values can be computed,
|
|
* and recombines those values into new strings of the same shape. Supports
|
|
* things like:
|
|
*
|
|
* rgba(123, 42, 99, 0.36) // colors
|
|
* -45deg // values with units
|
|
*/
|
|
NSMutableArray *output = [NSMutableArray array];
|
|
[_outputRanges addObject:output];
|
|
[soutputRange addObject:value];
|
|
|
|
_matches = [regex matchesInString:value options:0 range:NSMakeRange(0, [value length])];
|
|
for (NSTextCheckingResult *match in _matches) {
|
|
NSString* strNumber = [value substringWithRange:match.range];
|
|
[output addObject:[NSNumber numberWithDouble:strNumber.doubleValue]];
|
|
}
|
|
|
|
_hasStringOutput = YES;
|
|
[outputRange addObject:[output objectAtIndex:0]];
|
|
}
|
|
}
|
|
if (_hasStringOutput) {
|
|
// ['rgba(0, 100, 200, 0)', 'rgba(50, 150, 250, 0.5)']
|
|
// ->
|
|
// [
|
|
// [0, 50],
|
|
// [100, 150],
|
|
// [200, 250],
|
|
// [0, 0.5],
|
|
// ]
|
|
_numVals = [_matches count];
|
|
NSString *value = [soutputRange objectAtIndex:0];
|
|
_shouldRound = [value containsString:@"rgb"];
|
|
_matches = [regex matchesInString:value options:0 range:NSMakeRange(0, [value length])];
|
|
NSMutableArray<NSMutableArray<NSNumber *> *> *outputs = [NSMutableArray arrayWithCapacity:_numVals];
|
|
NSUInteger size = [soutputRange count];
|
|
for (NSUInteger j = 0; j < _numVals; j++) {
|
|
NSMutableArray *output = [NSMutableArray arrayWithCapacity:size];
|
|
[outputs addObject:output];
|
|
for (int i = 0; i < size; i++) {
|
|
[output addObject:[[_outputRanges objectAtIndex:i] objectAtIndex:j]];
|
|
}
|
|
}
|
|
_outputs = [outputs copy];
|
|
}
|
|
_outputRange = [outputRange copy];
|
|
_soutputRange = [soutputRange copy];
|
|
_extrapolateLeft = config[@"extrapolateLeft"];
|
|
_extrapolateRight = config[@"extrapolateRight"];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)onAttachedToNode:(RCTAnimatedNode *)parent
|
|
{
|
|
[super onAttachedToNode:parent];
|
|
if ([parent isKindOfClass:[RCTValueAnimatedNode class]]) {
|
|
_parentNode = (RCTValueAnimatedNode *)parent;
|
|
}
|
|
}
|
|
|
|
- (void)onDetachedFromNode:(RCTAnimatedNode *)parent
|
|
{
|
|
[super onDetachedFromNode:parent];
|
|
if (_parentNode == parent) {
|
|
_parentNode = nil;
|
|
}
|
|
}
|
|
|
|
- (void)performUpdate
|
|
{
|
|
[super performUpdate];
|
|
if (!_parentNode) {
|
|
return;
|
|
}
|
|
|
|
CGFloat inputValue = _parentNode.value;
|
|
|
|
CGFloat interpolated = RCTInterpolateValueInRange(inputValue,
|
|
_inputRange,
|
|
_outputRange,
|
|
_extrapolateLeft,
|
|
_extrapolateRight);
|
|
self.value = interpolated;
|
|
if (_hasStringOutput) {
|
|
// 'rgba(0, 100, 200, 0)'
|
|
// ->
|
|
// 'rgba(${interpolations[0](input)}, ${interpolations[1](input)}, ...'
|
|
if (_numVals > 1) {
|
|
NSString *text = _soutputRange[0];
|
|
NSMutableString *formattedText = [NSMutableString stringWithString:text];
|
|
NSUInteger i = _numVals;
|
|
for (NSTextCheckingResult *match in [_matches reverseObjectEnumerator]) {
|
|
CGFloat val = RCTInterpolateValueInRange(inputValue,
|
|
_inputRange,
|
|
_outputs[--i],
|
|
_extrapolateLeft,
|
|
_extrapolateRight);
|
|
NSString *str;
|
|
if (_shouldRound) {
|
|
// rgba requires that the r,g,b are integers.... so we want to round them, but we *dont* want to
|
|
// round the opacity (4th column).
|
|
bool isAlpha = i == 3;
|
|
CGFloat rounded = isAlpha ? round(val * 1000) / 1000 : round(val);
|
|
str = isAlpha ? [NSString stringWithFormat:@"%1.3f", rounded] : [NSString stringWithFormat:@"%1.0f", rounded];
|
|
} else {
|
|
NSNumber *numberValue = [NSNumber numberWithDouble:val];
|
|
str = [numberValue stringValue];
|
|
}
|
|
|
|
[formattedText replaceCharactersInRange:[match range] withString:str];
|
|
}
|
|
self.animatedObject = formattedText;
|
|
} else {
|
|
self.animatedObject = [regex stringByReplacingMatchesInString:_soutputRange[0]
|
|
options:0
|
|
range:NSMakeRange(0, _soutputRange[0].length)
|
|
withTemplate:[NSString stringWithFormat:@"%1f", interpolated]];
|
|
}
|
|
}
|
|
}
|
|
|
|
@end
|