Introducing RCTSurface, new experimental thread-safe interop layer

Summary:
RCTSurface instance represents React Native-powered piece of a user interface
which can be a full-screen app, separate modal view controller,
or even small widget. It is called "Surface".

The RCTSurface instance is completely thread-safe by design;
it can be created on any thread, and any its method can be called from
any thread (if the opposite is not mentioned explicitly).
The primary goals of the RCTSurface are:
 - ability to measure and layout the surface in a thread-safe and synchronous manner;
 - ability to create a UIView instance on demand (later);
 - ability to communicate the current stage of the surface granularly.

Differential Revision: D6202576

fbshipit-source-id: 8e644c87fcaad2b6a9c9304b58384d7192747556
This commit is contained in:
Valentin Shergin 2017-11-07 16:10:55 -08:00 committed by Facebook Github Bot
parent be6976d6fa
commit 7df58e23a3
15 changed files with 1198 additions and 3 deletions

View File

@ -0,0 +1,119 @@
/**
* 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 <Foundation/Foundation.h>
#import <React/RCTSurfaceStage.h>
NS_ASSUME_NONNULL_BEGIN
@class RCTBridge;
@class RCTSurfaceView;
@protocol RCTSurfaceDelegate;
/**
* RCTSurface instance represents React Native-powered piece of a user interface
* which can be a full-screen app, separate modal view controller,
* or even small widget.
* It is called "Surface".
*
* The RCTSurface instance is completely thread-safe by design;
* it can be created on any thread, and any its method can be called from
* any thread (if the opposite is not mentioned explicitly).
*
* The primary goals of the RCTSurface are:
* * ability to measure and layout the surface in a thread-safe
* and synchronous manner;
* * ability to create a UIView instance on demand (later);
* * ability to communicate the current stage of the surface granularly.
*/
@interface RCTSurface : NSObject
@property (atomic, readonly) RCTSurfaceStage stage;
@property (atomic, readonly) RCTBridge *bridge;
@property (atomic, readonly) NSString *moduleName;
@property (atomic, readonly) NSNumber *rootViewTag;
@property (atomic, readwrite, weak, nullable) id<RCTSurfaceDelegate> delegate;
@property (atomic, copy, readwrite) NSDictionary *properties;
- (instancetype)initWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties NS_DESIGNATED_INITIALIZER;
#pragma mark - Dealing with UIView representation, the Main thread only access
/**
* Creates (if needed) and returns `UIView` instance which represents the Surface.
* The Surface will cache and *retain* this object.
* Returning the UIView instance does not mean that the Surface is ready
* to execute and layout. It can be just a handler which Surface will use later
* to mount the actual views.
* RCTSurface does not control (or influence in any way) the size or origin
* of this view. Some superview (or another owner) must use other methods
* of this class to setup proper layout and interop interactions with UIKit
* or another UI framework.
* This method must be called only from the main queue.
*/
- (RCTSurfaceView *)view;
#pragma mark - Layout: Setting the size constrains
/**
* Sets `minimumSize` and `maximumSize` layout constraints for the Surface.
*/
- (void)setMinimumSize:(CGSize)minimumSize
maximumSize:(CGSize)maximumSize;
/**
* Previously set `minimumSize` layout constraint.
* Defaults to `{0, 0}`.
*/
@property (atomic, assign, readonly) CGSize minimumSize;
/**
* Previously set `maximumSize` layout constraint.
* Defaults to `{INFINITY, INFINITY}`.
*/
@property (atomic, assign, readonly) CGSize maximumSize;
/**
* Simple shortcut to `-[RCTSurface setMinimumSize:size maximumSize:size]`.
*/
- (void)setSize:(CGSize)size;
#pragma mark - Layout: Measuring
/**
* Measures the Surface with given constraints.
* This method does not cause any side effects on the surface object.
*/
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize
maximumSize:(CGSize)maximumSize;
/**
* Return the current size of the root view based on (but not clamp by) current
* size constraints.
*/
@property (atomic, assign, readonly) CGSize intrinsicSize;
#pragma mark - Synchronous waiting
/**
* Synchronously blocks the current thread up to given `timeout` until
* the Surface will not have given `stage`.
* Do nothing, if called from the main or `UIManager` queue.
*/
- (BOOL)synchronouslyWaitForStage:(RCTSurfaceStage)stage timeout:(NSTimeInterval)timeout;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,482 @@
/**
* 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 "RCTSurface.h"
#import "RCTSurfaceView+Internal.h"
#import <mutex>
#import "RCTAssert.h"
#import "RCTBridge+Private.h"
#import "RCTBridge.h"
#import "RCTSurfaceDelegate.h"
#import "RCTSurfaceRootShadowView.h"
#import "RCTSurfaceRootShadowViewDelegate.h"
#import "RCTSurfaceRootView.h"
#import "RCTSurfaceView.h"
#import "RCTTouchHandler.h"
#import "RCTUIManager.h"
#import "RCTUIManagerUtils.h"
@interface RCTSurface () <RCTSurfaceRootShadowViewDelegate>
@end
@implementation RCTSurface {
// Immutable
RCTBridge *_bridge;
NSString *_moduleName;
NSNumber *_rootViewTag;
// Protected by the `_mutex`
std::mutex _mutex;
RCTBridge *_batchedBridge;
RCTSurfaceStage _stage;
NSDictionary *_properties;
CGSize _minimumSize;
CGSize _maximumSize;
CGSize _intrinsicSize;
// The Main thread only
RCTSurfaceView *_Nullable _view;
RCTTouchHandler *_Nullable _touchHandler;
// Semaphores
dispatch_semaphore_t _rootShadowViewDidStartRenderingSemaphore;
dispatch_semaphore_t _rootShadowViewDidStartLayingOutSemaphore;
}
- (instancetype)initWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
{
RCTAssert(bridge.valid, @"Valid bridge is required to instanciate `RCTSurface`.");
if (self = [super init]) {
_bridge = bridge;
_batchedBridge = [_bridge batchedBridge] ?: _bridge;
_moduleName = moduleName;
_properties = [initialProperties copy];
_rootViewTag = RCTAllocateRootViewTag();
_rootShadowViewDidStartRenderingSemaphore = dispatch_semaphore_create(0);
_rootShadowViewDidStartLayingOutSemaphore = dispatch_semaphore_create(0);
_minimumSize = CGSizeZero;
_maximumSize = CGSizeMake(INFINITY, INFINITY);
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleBridgeWillLoadJavaScriptNotification:)
name:RCTJavaScriptWillStartLoadingNotification
object:_bridge];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleBridgeDidLoadJavaScriptNotification:)
name:RCTJavaScriptDidLoadNotification
object:_bridge];
_stage = RCTSurfaceStageSurfaceDidInitialize;
if (!bridge.loading) {
_stage = (RCTSurfaceStage)(_stage | RCTSurfaceStageBridgeDidLoad);
}
[self _registerRootViewTag];
[self _run];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Immutable Properties (no need to enforce synchonization)
- (RCTBridge *)bridge
{
return _bridge;
}
- (NSString *)moduleName
{
return _moduleName;
}
- (NSNumber *)rootViewTag
{
return _rootViewTag;
}
#pragma mark - Convinience Internal Thread-Safe Properties
- (RCTBridge *)_batchedBridge
{
std::lock_guard<std::mutex> lock(_mutex);
return _batchedBridge;
}
- (RCTUIManager *)_uiManager
{
return self._batchedBridge.uiManager;
}
#pragma mark - Main-Threaded Routines
- (RCTSurfaceView *)view
{
RCTAssertMainQueue();
if (!_view) {
_view = [[RCTSurfaceView alloc] initWithSurface:self];
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:self.bridge];
[_touchHandler attachToView:_view];
[self _mountRootViewIfNeeded];
}
return _view;
}
- (void)_mountRootViewIfNeeded
{
RCTAssertMainQueue();
RCTSurfaceView *view = self->_view;
if (!view) {
return;
}
RCTSurfaceRootView *rootView =
(RCTSurfaceRootView *)[self._uiManager viewForReactTag:self->_rootViewTag];
if (!rootView) {
return;
}
RCTAssert([rootView isKindOfClass:[RCTSurfaceRootView class]],
@"Received root view is not an instanse of `RCTSurfaceRootView`.");
if (rootView.superview != view) {
view.rootView = rootView;
}
}
#pragma mark - Bridge Events
- (void)handleBridgeWillLoadJavaScriptNotification:(NSNotification *)notification
{
RCTAssertMainQueue();
[self _setStage:RCTSurfaceStageBridgeDidLoad];
}
- (void)handleBridgeDidLoadJavaScriptNotification:(NSNotification *)notification
{
RCTAssertMainQueue();
[self _setStage:RCTSurfaceStageModuleDidLoad];
RCTBridge *bridge = notification.userInfo[@"bridge"];
BOOL isRerunNeeded = NO;
{
std::lock_guard<std::mutex> lock(_mutex);
if (bridge != _batchedBridge) {
_batchedBridge = bridge;
isRerunNeeded = YES;
}
}
if (isRerunNeeded) {
[self _run];
}
}
#pragma mark - Stage management
- (RCTSurfaceStage)stage
{
std::lock_guard<std::mutex> lock(_mutex);
return _stage;
}
- (void)_setStage:(RCTSurfaceStage)stage
{
{
std::lock_guard<std::mutex> lock(_mutex);
if (_stage & stage) {
return;
}
_stage = (RCTSurfaceStage)(_stage | stage);
}
[self _propagateStageChange:stage];
}
- (void)_propagateStageChange:(RCTSurfaceStage)stage
{
// Updating the `view`
RCTExecuteOnMainQueue(^{
self->_view.stage = stage;
});
// Notifying the `delegate`
id<RCTSurfaceDelegate> delegate = self.delegate;
if ([delegate respondsToSelector:@selector(surface:didChangeStage:)]) {
[delegate surface:self didChangeStage:stage];
}
}
#pragma mark - Properties Management
- (NSDictionary *)properties
{
std::lock_guard<std::mutex> lock(_mutex);
return _properties;
}
- (void)setProperties:(NSDictionary *)properties
{
{
std::lock_guard<std::mutex> lock(_mutex);
if ([properties isEqualToDictionary:_properties]) {
return;
}
_properties = [properties copy];
}
[self _run];
}
#pragma mark - Running
- (void)_run
{
RCTBridge *batchedBridge;
NSDictionary *properties;
{
std::lock_guard<std::mutex> lock(_mutex);
batchedBridge = _batchedBridge;
properties = _properties;
}
if (!batchedBridge.valid) {
return;
}
NSDictionary *applicationParameters =
@{
@"rootTag": _rootViewTag,
@"initialProps": properties,
};
RCTLogInfo(@"Running surface %@ (%@)", _moduleName, applicationParameters);
[batchedBridge enqueueJSCall:@"AppRegistry"
method:@"runApplication"
args:@[_moduleName, applicationParameters]
completion:NULL];
[self _setStage:RCTSurfaceStageSurfaceDidRun];
}
- (void)_registerRootViewTag
{
RCTBridge *batchedBridge;
CGSize minimumSize;
CGSize maximumSize;
{
std::lock_guard<std::mutex> lock(_mutex);
batchedBridge = _batchedBridge;
minimumSize = _minimumSize;
maximumSize = _maximumSize;
}
RCTUIManager *uiManager = batchedBridge.uiManager;
RCTUnsafeExecuteOnUIManagerQueueSync(^{
[uiManager registerRootViewTag:self->_rootViewTag];
RCTSurfaceRootShadowView *rootShadowView =
(RCTSurfaceRootShadowView *)[uiManager shadowViewForReactTag:self->_rootViewTag];
RCTAssert([rootShadowView isKindOfClass:[RCTSurfaceRootShadowView class]],
@"Received shadow view is not an instanse of `RCTSurfaceRootShadowView`.");
[rootShadowView setMinimumSize:minimumSize
maximumSize:maximumSize];
rootShadowView.delegate = self;
});
}
#pragma mark - Layout
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize
maximumSize:(CGSize)maximumSize
{
RCTUIManager *uiManager = self._uiManager;
__block CGSize fittingSize;
RCTUnsafeExecuteOnUIManagerQueueSync(^{
RCTSurfaceRootShadowView *rootShadowView =
(RCTSurfaceRootShadowView *)[uiManager shadowViewForReactTag:self->_rootViewTag];
RCTAssert([rootShadowView isKindOfClass:[RCTSurfaceRootShadowView class]],
@"Received shadow view is not an instanse of `RCTSurfaceRootShadowView`.");
fittingSize = [rootShadowView sizeThatFitsMinimumSize:minimumSize
maximumSize:maximumSize];
});
return fittingSize;
}
#pragma mark - Size Constraints
- (void)setSize:(CGSize)size
{
[self setMinimumSize:size maximumSize:size];
}
- (void)setMinimumSize:(CGSize)minimumSize
maximumSize:(CGSize)maximumSize
{
{
std::lock_guard<std::mutex> lock(_mutex);
if (CGSizeEqualToSize(minimumSize, _minimumSize) &&
CGSizeEqualToSize(maximumSize, _maximumSize)) {
return;
}
_maximumSize = maximumSize;
_minimumSize = minimumSize;
}
RCTUIManager *uiManager = self._uiManager;
RCTUnsafeExecuteOnUIManagerQueueSync(^{
RCTSurfaceRootShadowView *rootShadowView =
(RCTSurfaceRootShadowView *)[uiManager shadowViewForReactTag:self->_rootViewTag];
RCTAssert([rootShadowView isKindOfClass:[RCTSurfaceRootShadowView class]],
@"Received shadow view is not an instanse of `RCTSurfaceRootShadowView`.");
[rootShadowView setMinimumSize:minimumSize maximumSize:maximumSize];
[uiManager setNeedsLayout];
});
}
- (CGSize)minimumSize
{
std::lock_guard<std::mutex> lock(_mutex);
return _minimumSize;
}
- (CGSize)maximumSize
{
std::lock_guard<std::mutex> lock(_mutex);
return _maximumSize;
}
#pragma mark - intrinsicSize
- (void)setIntrinsicSize:(CGSize)intrinsicSize
{
{
std::lock_guard<std::mutex> lock(_mutex);
if (CGSizeEqualToSize(intrinsicSize, _intrinsicSize)) {
return;
}
_intrinsicSize = intrinsicSize;
}
// Notifying `delegate`
id<RCTSurfaceDelegate> delegate = self.delegate;
if ([delegate respondsToSelector:@selector(surface:didChangeIntrinsicSize:)]) {
[delegate surface:self didChangeIntrinsicSize:intrinsicSize];
}
}
- (CGSize)intrinsicSize
{
std::lock_guard<std::mutex> lock(_mutex);
return _intrinsicSize;
}
#pragma mark - Synchronous Waiting
- (BOOL)synchronouslyWaitForStage:(RCTSurfaceStage)stage timeout:(NSTimeInterval)timeout
{
dispatch_semaphore_t semaphore;
switch (stage) {
case RCTSurfaceStageSurfaceDidInitialLayout:
semaphore = _rootShadowViewDidStartLayingOutSemaphore;
break;
case RCTSurfaceStageSurfaceDidInitialRendering:
semaphore = _rootShadowViewDidStartRenderingSemaphore;
break;
default:
RCTAssert(NO, @"Only waiting for `RCTSurfaceStageSurfaceDidInitialRendering` and `RCTSurfaceStageSurfaceDidInitialLayout` stages is supported.");
}
if (RCTIsMainQueue()) {
RCTLogInfo(@"Synchronous waiting is not supported on the main queue.");
return NO;
}
if (RCTIsUIManagerQueue()) {
RCTLogInfo(@"Synchronous waiting is not supported on UIManager queue.");
return NO;
}
BOOL timeoutOccured = dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, timeout * NSEC_PER_SEC));
if (!timeoutOccured) {
// Balancing the semaphore.
// Note: `dispatch_semaphore_wait` reverts the decrement in case when timeout occured.
dispatch_semaphore_signal(semaphore);
}
return !timeoutOccured;
}
#pragma mark - RCTSurfaceRootShadowViewDelegate
- (void)rootShadowView:(RCTRootShadowView *)rootShadowView didChangeIntrinsicSize:(CGSize)intrinsicSize
{
self.intrinsicSize = intrinsicSize;
}
- (void)rootShadowViewDidStartRendering:(RCTSurfaceRootShadowView *)rootShadowView
{
[self _setStage:RCTSurfaceStageSurfaceDidInitialRendering];
dispatch_semaphore_signal(_rootShadowViewDidStartRenderingSemaphore);
}
- (void)rootShadowViewDidStartLayingOut:(RCTSurfaceRootShadowView *)rootShadowView
{
[self _setStage:RCTSurfaceStageSurfaceDidInitialLayout];
dispatch_semaphore_signal(_rootShadowViewDidStartLayingOutSemaphore);
RCTExecuteOnMainQueue(^{
// Rendering is happening, let's mount `rootView` into `view` if we already didn't do this.
[self _mountRootViewIfNeeded];
});
}
@end

View File

@ -0,0 +1,36 @@
/**
* 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 <UIKit/UIKit.h>
#import <React/RCTSurfaceStage.h>
NS_ASSUME_NONNULL_BEGIN
@class RCTSurface;
@protocol RCTSurfaceDelegate <NSObject>
@optional
/**
* Notifies a receiver that a surface transitioned to a new stage.
* See `RCTSurfaceStage` for more details.
*/
- (void)surface:(RCTSurface *)surface didChangeStage:(RCTSurfaceStage)stage;
/**
* Notifies a receiver that root view got a new (intrinsic) size during the last
* layout pass.
*/
- (void)surface:(RCTSurface *)surface didChangeIntrinsicSize:(CGSize)intrinsicSize;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,41 @@
/**
* 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 <React/RCTShadowView.h>
#import <React/RCTSurfaceRootShadowViewDelegate.h>
#import <yoga/YGEnums.h>
@interface RCTSurfaceRootShadowView : RCTShadowView
@property (nonatomic, assign, readonly) CGSize minimumSize;
@property (nonatomic, assign, readonly) CGSize maximumSize;
- (void)setMinimumSize:(CGSize)size maximumSize:(CGSize)maximumSize;
@property (nonatomic, assign, readonly) CGSize intrinsicSize;
@property (nonatomic, weak) id<RCTSurfaceRootShadowViewDelegate> delegate;
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize
maximumSize:(CGSize)maximumSize;
/**
* Layout direction (LTR or RTL) inherited from native environment and
* is using as a base direction value in layout engine.
* Defaults to value inferred from current locale.
*/
@property (nonatomic, assign) YGDirection baseDirection;
/**
* Calculate all views whose frame needs updating after layout has been calculated.
* Returns a set contains the shadowviews that need updating.
*/
- (NSSet<RCTShadowView *> *)collectViewsWithUpdatedFrames;
@end

View File

@ -0,0 +1,138 @@
/**
* 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 "RCTSurfaceRootShadowView.h"
#import <React/RCTUIManagerUtils.h>
#import "RCTI18nUtil.h"
@implementation RCTSurfaceRootShadowView {
CGSize _intrinsicSize;
BOOL _isRendered;
BOOL _isLaidOut;
}
- (instancetype)init
{
if (self = [super init]) {
self.viewName = @"RCTSurfaceRootView";
_baseDirection = [[RCTI18nUtil sharedInstance] isRTL] ? YGDirectionRTL : YGDirectionLTR;
_minimumSize = CGSizeZero;
_maximumSize = CGSizeMake(INFINITY, INFINITY);
self.alignSelf = YGAlignStretch;
self.flex = 1;
}
return self;
}
- (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex
{
[super insertReactSubview:subview atIndex:atIndex];
if (!_isRendered) {
[_delegate rootShadowViewDidStartRendering:self];
_isRendered = YES;
}
}
- (void)calculateLayoutWithMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximimSize
{
// Treating `INFINITY` as `YGUndefined` (which equals `NAN`).
float availableWidth = isinf(maximimSize.width) ? YGUndefined : maximimSize.width;
float availableHeight = isinf(maximimSize.height) ? YGUndefined : maximimSize.height;
self.minWidth = (YGValue){isinf(minimumSize.width) ? YGUndefined : minimumSize.width, YGUnitPoint};
self.minWidth = (YGValue){isinf(minimumSize.height) ? YGUndefined : minimumSize.height, YGUnitPoint};
YGNodeCalculateLayout(self.yogaNode, availableWidth, availableHeight, _baseDirection);
}
- (NSSet<RCTShadowView *> *)collectViewsWithUpdatedFrames
{
[self calculateLayoutWithMinimumSize:_minimumSize
maximumSize:_maximumSize];
NSMutableSet<RCTShadowView *> *viewsWithNewFrame = [NSMutableSet set];
[self applyLayoutNode:self.yogaNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:CGPointZero];
self.intrinsicSize = self.frame.size;
if (_isRendered && !_isLaidOut) {
[_delegate rootShadowViewDidStartLayingOut:self];
_isLaidOut = YES;
}
return viewsWithNewFrame;
}
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize
maximumSize:(CGSize)maximumSize
{
// Positive case where requested constraind are aready enforced.
if (CGSizeEqualToSize(minimumSize, _minimumSize) &&
CGSizeEqualToSize(maximumSize, _maximumSize)) {
// We stil need to call `calculateLayoutWithMinimumSize:maximumSize`
// mehtod though.
[self calculateLayoutWithMinimumSize:_minimumSize
maximumSize:_maximumSize];
YGNodeRef yogaNode = self.yogaNode;
return CGSizeMake(YGNodeLayoutGetWidth(yogaNode), YGNodeLayoutGetHeight(yogaNode));
}
// Generic case, where requested constraind are different from enforced.
// Applying given size constraints.
[self calculateLayoutWithMinimumSize:minimumSize
maximumSize:maximumSize];
YGNodeRef yogaNode = self.yogaNode;
CGSize fittingSize =
CGSizeMake(YGNodeLayoutGetWidth(yogaNode), YGNodeLayoutGetHeight(yogaNode));
// Reverting size constraints.
[self calculateLayoutWithMinimumSize:_minimumSize
maximumSize:_maximumSize];
return CGSizeMake(
MAX(minimumSize.width, MIN(maximumSize.width, fittingSize.width)),
MAX(minimumSize.height, MIN(maximumSize.height, fittingSize.height))
);
}
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize
{
if (CGSizeEqualToSize(minimumSize, _minimumSize) &&
CGSizeEqualToSize(maximumSize, _maximumSize)) {
return;
}
_maximumSize = maximumSize;
_minimumSize = minimumSize;
}
- (void)setIntrinsicSize:(CGSize)intrinsicSize
{
if (CGSizeEqualToSize(_intrinsicSize, intrinsicSize)) {
return;
}
_intrinsicSize = intrinsicSize;
[_delegate rootShadowView:self didChangeIntrinsicSize:intrinsicSize];
}
- (CGSize)intrinsicSize
{
return _intrinsicSize;
}
@end

View File

@ -0,0 +1,24 @@
/**
* 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 <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class RCTSurfaceRootShadowView;
@protocol RCTSurfaceRootShadowViewDelegate <NSObject>
- (void)rootShadowView:(RCTSurfaceRootShadowView *)rootShadowView didChangeIntrinsicSize:(CGSize)instrinsicSize;
- (void)rootShadowViewDidStartRendering:(RCTSurfaceRootShadowView *)rootShadowView;
- (void)rootShadowViewDidStartLayingOut:(RCTSurfaceRootShadowView *)rootShadowView;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,23 @@
/**
* 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 <UIKit/UIKit.h>
#import <React/RCTView.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Internal class represents Surface's root view.
*/
@interface RCTSurfaceRootView : RCTView
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,18 @@
/**
* 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 "RCTSurfaceRootView.h"
#import "RCTDefines.h"
@implementation RCTSurfaceRootView
RCT_NOT_IMPLEMENTED(- (nullable instancetype)initWithCoder:(NSCoder *)coder)
@end

View File

@ -0,0 +1,24 @@
/**
* 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 <UIKit/UIKit.h>
/**
* The stage of the Surface
*/
typedef NS_OPTIONS(NSInteger, RCTSurfaceStage) {
RCTSurfaceStageSurfaceDidInitialize = 1 << 0, // Surface object was created
RCTSurfaceStageBridgeDidLoad = 1 << 1, // Bridge was loaded
RCTSurfaceStageModuleDidLoad = 1 << 2, // Module (JavaScript code) was loaded
RCTSurfaceStageSurfaceDidRun = 1 << 3, // Module (JavaScript code) was run
RCTSurfaceStageSurfaceDidInitialRendering = 1 << 4, // UIManager created the first shadow views
RCTSurfaceStageSurfaceDidInitialLayout = 1 << 5, // UIManager completed the first layout pass
RCTSurfaceStageSurfaceDidInitialMounting = 1 << 6, // UIManager completed the first mounting pass
RCTSurfaceStageSurfaceDidInvalidate = 1 << 7, // Surface received `invalidate` message
};

View File

@ -0,0 +1,26 @@
/**
* 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 <UIKit/UIKit.h>
#import <React/RCTSurfaceStage.h>
#import <React/RCTSurfaceView.h>
@class RCTSurfaceRootView;
NS_ASSUME_NONNULL_BEGIN
@interface RCTSurfaceView (Internal)
@property (nonatomic, strong) RCTSurfaceRootView *rootView;
@property (nonatomic, assign) RCTSurfaceStage stage;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,30 @@
/**
* 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 <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class RCTSurface;
typedef UIView *(^RCTSurfaceActivityIndicatorViewFactory)();
/**
* UIView instance which represents the Surface
*/
@interface RCTSurfaceView : UIView
- (instancetype)initWithSurface:(RCTSurface *)surface NS_DESIGNATED_INITIALIZER;
@property (nonatomic, copy, nullable) RCTSurfaceActivityIndicatorViewFactory activityIndicatorViewFactory;
@property (nonatomic, weak, readonly, nullable) RCTSurface *surface;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,115 @@
/**
* 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 "RCTSurfaceView.h"
#import "RCTSurfaceView+Internal.h"
#import "RCTDefines.h"
#import "RCTSurface.h"
#import "RCTSurfaceRootView.h"
@implementation RCTSurfaceView {
RCTSurfaceRootView *_Nullable _rootView;
UIView *_Nullable _activityIndicatorView;
RCTSurfaceStage _stage;
}
RCT_NOT_IMPLEMENTED(- (instancetype)init)
RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
RCT_NOT_IMPLEMENTED(- (nullable instancetype)initWithCoder:(NSCoder *)coder)
- (instancetype)initWithSurface:(RCTSurface *)surface
{
if (self = [super initWithFrame:CGRectZero]) {
_stage = surface.stage;
_surface = surface;
}
return self;
}
#pragma mark - Internal Interface
- (void)setRootView:(RCTSurfaceRootView *)rootView
{
if (_rootView == rootView) {
return;
}
[_rootView removeFromSuperview];
_rootView = rootView;
[self updateStage];
}
- (RCTSurfaceRootView *)rootView
{
return _rootView;
}
#pragma mark - activityIndicatorView
- (void)setActivityIndicatorView:(UIView *)view
{
[_activityIndicatorView removeFromSuperview];
_activityIndicatorView = view;
_activityIndicatorView.frame = self.bounds;
_activityIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:_activityIndicatorView];
}
- (UIView *)activityIndicatorView
{
return _activityIndicatorView;
}
#pragma mark - stage
- (void)setStage:(RCTSurfaceStage)stage
{
if (stage == _stage) {
return;
}
_stage = stage;
[self updateStage];
}
- (RCTSurfaceStage)stage
{
return _stage;
}
#pragma mark - Visibility
- (void)updateStage
{
BOOL displayRootView = _stage & RCTSurfaceStageSurfaceDidInitialLayout;
BOOL displayActivityIndicator = !displayRootView;
if (displayRootView) {
if (_rootView.superview != self) {
[self addSubview:_rootView];
}
}
else {
[_rootView removeFromSuperview];
}
if (displayActivityIndicator) {
if (!_activityIndicatorView && self.activityIndicatorViewFactory != nil) {
self.activityIndicatorView = self.activityIndicatorViewFactory();
}
}
else {
[_activityIndicatorView removeFromSuperview];
}
}
@end

View File

@ -29,6 +29,12 @@ RCT_EXTERN NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplier
*/
@interface RCTUIManager : NSObject <RCTBridgeModule, RCTInvalidating>
/**
* Register a root view tag and creates corresponding `rootView` and
* `rootShadowView`.
*/
- (void)registerRootViewTag:(NSNumber *)rootTag;
/**
* Register a root view with the RCTUIManager.
*/

View File

@ -32,6 +32,8 @@
#import "RCTScrollableProtocol.h"
#import "RCTShadowView+Internal.h"
#import "RCTShadowView.h"
#import "RCTSurfaceRootShadowView.h"
#import "RCTSurfaceRootView.h"
#import "RCTUIManagerObserverCoordinator.h"
#import "RCTUIManagerUtils.h"
#import "RCTUtils.h"
@ -96,7 +98,10 @@ RCT_EXPORT_MODULE()
RCTExecuteOnMainQueue(^{
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"UIManager invalidate", nil);
for (NSNumber *rootViewTag in self->_rootViewTags) {
[(id<RCTInvalidating>)self->_viewRegistry[rootViewTag] invalidate];
UIView *rootView = self->_viewRegistry[rootViewTag];
if ([rootView conformsToProtocol:@protocol(RCTInvalidating)]) {
[(id<RCTInvalidating>)rootView invalidate];
}
}
self->_rootViewTags = nil;
@ -246,6 +251,31 @@ static NSDictionary *deviceOrientationEventBody(UIDeviceOrientation orientation)
return RCTGetUIManagerQueue();
}
- (void)registerRootViewTag:(NSNumber *)rootTag
{
RCTAssertUIManagerQueue();
RCTAssert(RCTIsReactRootView(rootTag),
@"Attempt to register rootTag (%@) which is not actually root tag.", rootTag);
RCTAssert(![_rootViewTags containsObject:rootTag],
@"Attempt to register rootTag (%@) which was already registred.", rootTag);
[_rootViewTags addObject:rootTag];
// Registering root shadow view
RCTSurfaceRootShadowView *shadowView = [RCTSurfaceRootShadowView new];
shadowView.reactTag = rootTag;
_shadowViewRegistry[rootTag] = shadowView;
// Registering root view
RCTExecuteOnMainQueue(^{
RCTSurfaceRootView *rootView = [RCTSurfaceRootView new];
rootView.reactTag = rootTag;
self->_viewRegistry[rootTag] = rootView;
});
}
- (void)registerRootView:(RCTRootContentView *)rootView
{
RCTAssertMainQueue();
@ -551,7 +581,9 @@ static NSDictionary *deviceOrientationEventBody(UIDeviceOrientation orientation)
RCTAssert(view != nil, @"view (for ID %@) not found", reactTag);
RCTRootView *rootView = (RCTRootView *)[view superview];
rootView.intrinsicContentSize = contentSize;
if ([rootView isKindOfClass:[RCTRootView class]]) {
rootView.intrinsicContentSize = contentSize;
}
});
}
}
@ -948,7 +980,8 @@ RCT_EXPORT_METHOD(createView:(nonnull NSNumber *)reactTag
[componentData setProps:props forShadowView:shadowView];
_shadowViewRegistry[reactTag] = shadowView;
RCTShadowView *rootView = _shadowViewRegistry[rootTag];
RCTAssert([rootView isKindOfClass:[RCTRootShadowView class]],
RCTAssert([rootView isKindOfClass:[RCTRootShadowView class]] ||
[rootView isKindOfClass:[RCTSurfaceRootShadowView class]],
@"Given `rootTag` (%@) does not correspond to a valid root shadow view instance.", rootTag);
shadowView.rootView = (RCTRootShadowView *)rootView;
}

View File

@ -1030,6 +1030,30 @@
598FD1951F817335006C54CB /* RCTModalManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 91076A881F743AB00081B4FA /* RCTModalManager.h */; };
598FD1961F817335006C54CB /* RCTModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91076A871F743AB00081B4FA /* RCTModalManager.m */; };
598FD1971F817336006C54CB /* RCTModalManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 91076A881F743AB00081B4FA /* RCTModalManager.h */; };
599FAA361FB274980058CCF6 /* RCTSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2A1FB274970058CCF6 /* RCTSurface.h */; };
599FAA371FB274980058CCF6 /* RCTSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2A1FB274970058CCF6 /* RCTSurface.h */; };
599FAA381FB274980058CCF6 /* RCTSurface.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA2B1FB274970058CCF6 /* RCTSurface.mm */; };
599FAA391FB274980058CCF6 /* RCTSurface.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA2B1FB274970058CCF6 /* RCTSurface.mm */; };
599FAA3A1FB274980058CCF6 /* RCTSurfaceDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2C1FB274970058CCF6 /* RCTSurfaceDelegate.h */; };
599FAA3B1FB274980058CCF6 /* RCTSurfaceDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2C1FB274970058CCF6 /* RCTSurfaceDelegate.h */; };
599FAA3C1FB274980058CCF6 /* RCTSurfaceRootShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2D1FB274970058CCF6 /* RCTSurfaceRootShadowView.h */; };
599FAA3D1FB274980058CCF6 /* RCTSurfaceRootShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2D1FB274970058CCF6 /* RCTSurfaceRootShadowView.h */; };
599FAA3E1FB274980058CCF6 /* RCTSurfaceRootShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA2E1FB274970058CCF6 /* RCTSurfaceRootShadowView.m */; };
599FAA3F1FB274980058CCF6 /* RCTSurfaceRootShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA2E1FB274970058CCF6 /* RCTSurfaceRootShadowView.m */; };
599FAA401FB274980058CCF6 /* RCTSurfaceRootShadowViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2F1FB274970058CCF6 /* RCTSurfaceRootShadowViewDelegate.h */; };
599FAA411FB274980058CCF6 /* RCTSurfaceRootShadowViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA2F1FB274970058CCF6 /* RCTSurfaceRootShadowViewDelegate.h */; };
599FAA421FB274980058CCF6 /* RCTSurfaceRootView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA301FB274970058CCF6 /* RCTSurfaceRootView.h */; };
599FAA431FB274980058CCF6 /* RCTSurfaceRootView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA301FB274970058CCF6 /* RCTSurfaceRootView.h */; };
599FAA441FB274980058CCF6 /* RCTSurfaceRootView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA311FB274970058CCF6 /* RCTSurfaceRootView.mm */; };
599FAA451FB274980058CCF6 /* RCTSurfaceRootView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA311FB274970058CCF6 /* RCTSurfaceRootView.mm */; };
599FAA461FB274980058CCF6 /* RCTSurfaceStage.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA321FB274970058CCF6 /* RCTSurfaceStage.h */; };
599FAA471FB274980058CCF6 /* RCTSurfaceStage.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA321FB274970058CCF6 /* RCTSurfaceStage.h */; };
599FAA481FB274980058CCF6 /* RCTSurfaceView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA331FB274970058CCF6 /* RCTSurfaceView+Internal.h */; };
599FAA491FB274980058CCF6 /* RCTSurfaceView+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA331FB274970058CCF6 /* RCTSurfaceView+Internal.h */; };
599FAA4A1FB274980058CCF6 /* RCTSurfaceView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA341FB274970058CCF6 /* RCTSurfaceView.h */; };
599FAA4B1FB274980058CCF6 /* RCTSurfaceView.h in Headers */ = {isa = PBXBuildFile; fileRef = 599FAA341FB274970058CCF6 /* RCTSurfaceView.h */; };
599FAA4C1FB274980058CCF6 /* RCTSurfaceView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA351FB274970058CCF6 /* RCTSurfaceView.mm */; };
599FAA4D1FB274980058CCF6 /* RCTSurfaceView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 599FAA351FB274970058CCF6 /* RCTSurfaceView.mm */; };
59A7B9FD1E577DBF0068EDBF /* RCTRootContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59A7B9FB1E577DBF0068EDBF /* RCTRootContentView.h */; };
59A7B9FE1E577DBF0068EDBF /* RCTRootContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59A7B9FC1E577DBF0068EDBF /* RCTRootContentView.m */; };
59B1EBC91EBD46250047B19B /* RCTShadowView+Layout.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; };
@ -2073,6 +2097,18 @@
5960C1B41F0804A00066FD5B /* RCTLayoutAnimationGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTLayoutAnimationGroup.m; sourceTree = "<group>"; };
597633341F4E021D005BE8A4 /* RCTShadowView+Internal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTShadowView+Internal.m"; sourceTree = "<group>"; };
597633351F4E021D005BE8A4 /* RCTShadowView+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTShadowView+Internal.h"; sourceTree = "<group>"; };
599FAA2A1FB274970058CCF6 /* RCTSurface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurface.h; sourceTree = "<group>"; };
599FAA2B1FB274970058CCF6 /* RCTSurface.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTSurface.mm; sourceTree = "<group>"; };
599FAA2C1FB274970058CCF6 /* RCTSurfaceDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceDelegate.h; sourceTree = "<group>"; };
599FAA2D1FB274970058CCF6 /* RCTSurfaceRootShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceRootShadowView.h; sourceTree = "<group>"; };
599FAA2E1FB274970058CCF6 /* RCTSurfaceRootShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSurfaceRootShadowView.m; sourceTree = "<group>"; };
599FAA2F1FB274970058CCF6 /* RCTSurfaceRootShadowViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceRootShadowViewDelegate.h; sourceTree = "<group>"; };
599FAA301FB274970058CCF6 /* RCTSurfaceRootView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceRootView.h; sourceTree = "<group>"; };
599FAA311FB274970058CCF6 /* RCTSurfaceRootView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTSurfaceRootView.mm; sourceTree = "<group>"; };
599FAA321FB274970058CCF6 /* RCTSurfaceStage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceStage.h; sourceTree = "<group>"; };
599FAA331FB274970058CCF6 /* RCTSurfaceView+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTSurfaceView+Internal.h"; sourceTree = "<group>"; };
599FAA341FB274970058CCF6 /* RCTSurfaceView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceView.h; sourceTree = "<group>"; };
599FAA351FB274970058CCF6 /* RCTSurfaceView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTSurfaceView.mm; sourceTree = "<group>"; };
59A7B9FB1E577DBF0068EDBF /* RCTRootContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootContentView.h; sourceTree = "<group>"; };
59A7B9FC1E577DBF0068EDBF /* RCTRootContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootContentView.m; sourceTree = "<group>"; };
59D031E51F8353D3008361F0 /* RCTSafeAreaShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSafeAreaShadowView.h; sourceTree = "<group>"; };
@ -2647,6 +2683,25 @@
path = "../third-party";
sourceTree = "<group>";
};
599FAA291FB274970058CCF6 /* Surface */ = {
isa = PBXGroup;
children = (
599FAA2A1FB274970058CCF6 /* RCTSurface.h */,
599FAA2B1FB274970058CCF6 /* RCTSurface.mm */,
599FAA2C1FB274970058CCF6 /* RCTSurfaceDelegate.h */,
599FAA2D1FB274970058CCF6 /* RCTSurfaceRootShadowView.h */,
599FAA2E1FB274970058CCF6 /* RCTSurfaceRootShadowView.m */,
599FAA2F1FB274970058CCF6 /* RCTSurfaceRootShadowViewDelegate.h */,
599FAA301FB274970058CCF6 /* RCTSurfaceRootView.h */,
599FAA311FB274970058CCF6 /* RCTSurfaceRootView.mm */,
599FAA321FB274970058CCF6 /* RCTSurfaceStage.h */,
599FAA331FB274970058CCF6 /* RCTSurfaceView+Internal.h */,
599FAA341FB274970058CCF6 /* RCTSurfaceView.h */,
599FAA351FB274970058CCF6 /* RCTSurfaceView.mm */,
);
path = Surface;
sourceTree = "<group>";
};
59D031E41F8353D3008361F0 /* SafeAreaView */ = {
isa = PBXGroup;
children = (
@ -2803,6 +2858,7 @@
83CBBA4F1A601E3B00E9B192 /* RCTUtils.h */,
83CBBA501A601E3B00E9B192 /* RCTUtils.m */,
199B8A6E1F44DB16005DEF67 /* RCTVersion.h */,
599FAA291FB274970058CCF6 /* Surface */,
);
path = Base;
sourceTree = "<group>";
@ -2949,10 +3005,13 @@
59D031F61F8353D3008361F0 /* RCTSafeAreaViewLocalData.h in Headers */,
3D302F3C1DF828F800D6DDAE /* RCTJavaScriptLoader.h in Headers */,
3D302F3D1DF828F800D6DDAE /* RCTJSStackFrame.h in Headers */,
599FAA491FB274980058CCF6 /* RCTSurfaceView+Internal.h in Headers */,
3D302F3E1DF828F800D6DDAE /* RCTKeyCommands.h in Headers */,
135A9C031E7B0F6100587AEB /* RCTJSCErrorHandling.h in Headers */,
599FAA411FB274980058CCF6 /* RCTSurfaceRootShadowViewDelegate.h in Headers */,
3D7BFD261EA8E351008DFB7A /* RCTSamplingProfilerPackagerMethod.h in Headers */,
3D302F3F1DF828F800D6DDAE /* RCTLog.h in Headers */,
599FAA431FB274980058CCF6 /* RCTSurfaceRootView.h in Headers */,
3D302F401DF828F800D6DDAE /* RCTModuleData.h in Headers */,
5960C1B61F0804A00066FD5B /* RCTLayoutAnimation.h in Headers */,
3D302F411DF828F800D6DDAE /* RCTModuleMethod.h in Headers */,
@ -2988,6 +3047,8 @@
3D302F5C1DF828F800D6DDAE /* RCTEventEmitter.h in Headers */,
652971261EE976BD003C8BD5 /* InspectorInterfaces.h in Headers */,
3D302F5D1DF828F800D6DDAE /* RCTExceptionsManager.h in Headers */,
599FAA4B1FB274980058CCF6 /* RCTSurfaceView.h in Headers */,
599FAA3D1FB274980058CCF6 /* RCTSurfaceRootShadowView.h in Headers */,
3D302F5E1DF828F800D6DDAE /* RCTI18nManager.h in Headers */,
3D302F5F1DF828F800D6DDAE /* RCTI18nUtil.h in Headers */,
3D302F601DF828F800D6DDAE /* RCTKeyboardObserver.h in Headers */,
@ -2997,6 +3058,7 @@
3D302F631DF828F800D6DDAE /* RCTStatusBarManager.h in Headers */,
3D302F641DF828F800D6DDAE /* RCTTiming.h in Headers */,
3D302F651DF828F800D6DDAE /* RCTUIManager.h in Headers */,
599FAA3B1FB274980058CCF6 /* RCTSurfaceDelegate.h in Headers */,
3D302F661DF828F800D6DDAE /* RCTFPSGraph.h in Headers */,
3D302F681DF828F800D6DDAE /* RCTMacros.h in Headers */,
3D302F691DF828F800D6DDAE /* RCTProfile.h in Headers */,
@ -3039,6 +3101,7 @@
3D302F8A1DF828F800D6DDAE /* RCTScrollView.h in Headers */,
CF2731C21E7B8DEF0044CA4F /* RCTDeviceInfo.h in Headers */,
3D302F8B1DF828F800D6DDAE /* RCTScrollViewManager.h in Headers */,
599FAA371FB274980058CCF6 /* RCTSurface.h in Headers */,
3D302F8C1DF828F800D6DDAE /* RCTSegmentedControl.h in Headers */,
66CD94B21F1045E700CB3C7C /* RCTMaskedView.h in Headers */,
3D302F8D1DF828F800D6DDAE /* RCTSegmentedControlManager.h in Headers */,
@ -3057,6 +3120,7 @@
3D302F9A1DF828F800D6DDAE /* RCTViewManager.h in Headers */,
3D302F9D1DF828F800D6DDAE /* RCTWrapperViewController.h in Headers */,
3D302F9F1DF828F800D6DDAE /* UIView+React.h in Headers */,
599FAA471FB274980058CCF6 /* RCTSurfaceStage.h in Headers */,
13134CA11E296B2A00B9F3CB /* RCTCxxUtils.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -3219,12 +3283,15 @@
3D80DA211DF820620028D040 /* RCTBridge.h in Headers */,
13F880381E296D2800C3C7A1 /* JSCWrapper.h in Headers */,
3D80DA221DF820620028D040 /* RCTBridge+Private.h in Headers */,
599FAA461FB274980058CCF6 /* RCTSurfaceStage.h in Headers */,
3D7BFD211EA8E351008DFB7A /* RCTReloadPackagerMethod.h in Headers */,
599FAA361FB274980058CCF6 /* RCTSurface.h in Headers */,
3D80DA231DF820620028D040 /* RCTBridgeDelegate.h in Headers */,
3D80DA241DF820620028D040 /* RCTBridgeMethod.h in Headers */,
3D7BFD151EA8E351008DFB7A /* RCTPackagerClient.h in Headers */,
3D80DA251DF820620028D040 /* RCTBridgeModule.h in Headers */,
3D80DA261DF820620028D040 /* RCTBundleURLProvider.h in Headers */,
599FAA401FB274980058CCF6 /* RCTSurfaceRootShadowViewDelegate.h in Headers */,
5960C1B51F0804A00066FD5B /* RCTLayoutAnimation.h in Headers */,
3D80DA271DF820620028D040 /* RCTConvert.h in Headers */,
3D80DA281DF820620028D040 /* RCTDefines.h in Headers */,
@ -3240,6 +3307,7 @@
3D80DA2F1DF820620028D040 /* RCTInvalidating.h in Headers */,
598FD1971F817336006C54CB /* RCTModalManager.h in Headers */,
3D7BFD251EA8E351008DFB7A /* RCTSamplingProfilerPackagerMethod.h in Headers */,
599FAA3A1FB274980058CCF6 /* RCTSurfaceDelegate.h in Headers */,
9936F3381F5F2F480010BF04 /* PrivateDataBase.h in Headers */,
3D80DA301DF820620028D040 /* RCTJavaScriptExecutor.h in Headers */,
135A9BFF1E7B0EE600587AEB /* RCTJSCHelpers.h in Headers */,
@ -3255,6 +3323,7 @@
3D80DA381DF820620028D040 /* RCTMultipartStreamReader.h in Headers */,
3D80DA391DF820620028D040 /* RCTNullability.h in Headers */,
3D80DA3A1DF820620028D040 /* RCTParserUtils.h in Headers */,
599FAA421FB274980058CCF6 /* RCTSurfaceRootView.h in Headers */,
59D031F91F8353D3008361F0 /* RCTSafeAreaViewManager.h in Headers */,
3D80DA3B1DF820620028D040 /* RCTPerformanceLogger.h in Headers */,
59D031F51F8353D3008361F0 /* RCTSafeAreaViewLocalData.h in Headers */,
@ -3343,6 +3412,7 @@
3D80DA801DF820620028D040 /* RCTScrollViewManager.h in Headers */,
3D80DA811DF820620028D040 /* RCTSegmentedControl.h in Headers */,
C6827DF61EF17CCC00D66BEF /* RCTJSEnvironment.h in Headers */,
599FAA3C1FB274980058CCF6 /* RCTSurfaceRootShadowView.h in Headers */,
3D80DA821DF820620028D040 /* RCTSegmentedControlManager.h in Headers */,
3D80DA831DF820620028D040 /* RCTShadowView.h in Headers */,
3D80DA841DF820620028D040 /* RCTSlider.h in Headers */,
@ -3361,6 +3431,7 @@
590D7BFD1EBD458B00D8A370 /* RCTShadowView+Layout.h in Headers */,
3D80DA8F1DF820620028D040 /* RCTViewManager.h in Headers */,
13134CA01E296B2A00B9F3CB /* RCTCxxUtils.h in Headers */,
599FAA4A1FB274980058CCF6 /* RCTSurfaceView.h in Headers */,
3D80DA901DF820620028D040 /* RCTWebView.h in Headers */,
652971251EE976BA003C8BD5 /* InspectorInterfaces.h in Headers */,
3D80DA911DF820620028D040 /* RCTWebViewManager.h in Headers */,
@ -3368,6 +3439,7 @@
3D80DA931DF820620028D040 /* UIView+Private.h in Headers */,
59FBEFB01E46D91C0095D885 /* RCTScrollContentShadowView.h in Headers */,
3D80DA941DF820620028D040 /* UIView+React.h in Headers */,
599FAA481FB274980058CCF6 /* RCTSurfaceView+Internal.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3860,6 +3932,7 @@
2D3B5ECA1D9B095F00451313 /* RCTComponentData.m in Sources */,
2D3B5EA31D9B08BE00451313 /* RCTParserUtils.m in Sources */,
59500D461F71C63F00B122B7 /* RCTUIManagerUtils.m in Sources */,
599FAA4D1FB274980058CCF6 /* RCTSurfaceView.mm in Sources */,
2D3B5EA01D9B08B200451313 /* RCTLog.mm in Sources */,
2D3B5EE21D9B09B400451313 /* RCTScrollViewManager.m in Sources */,
5960C1BC1F0804A00066FD5B /* RCTLayoutAnimationGroup.m in Sources */,
@ -3900,11 +3973,13 @@
2D3B5EB61D9B091400451313 /* RCTExceptionsManager.m in Sources */,
2D3B5EEB1D9B09D000451313 /* RCTTabBarItem.m in Sources */,
2D3B5ED41D9B097D00451313 /* RCTModalHostView.m in Sources */,
599FAA391FB274980058CCF6 /* RCTSurface.mm in Sources */,
C606692F1F3CC60500E67165 /* RCTModuleMethod.mm in Sources */,
2D3B5E9F1D9B08AF00451313 /* RCTKeyCommands.m in Sources */,
2D3B5EA51D9B08C700451313 /* RCTRootView.m in Sources */,
13134C871E296B2A00B9F3CB /* RCTCxxBridge.mm in Sources */,
CF2731C31E7B8DF30044CA4F /* RCTDeviceInfo.m in Sources */,
599FAA3F1FB274980058CCF6 /* RCTSurfaceRootShadowView.m in Sources */,
597633371F4E021D005BE8A4 /* RCTShadowView+Internal.m in Sources */,
2D3B5EB11D9B090100451313 /* RCTAppState.m in Sources */,
1384E20B1E806D5B00545659 /* RCTNativeModule.mm in Sources */,
@ -3927,6 +4002,7 @@
2D3B5EBD1D9B092A00451313 /* RCTTiming.m in Sources */,
135A9C041E7B0F6400587AEB /* RCTJSCErrorHandling.mm in Sources */,
2D3B5EA81D9B08D300451313 /* RCTUtils.m in Sources */,
599FAA451FB274980058CCF6 /* RCTSurfaceRootView.mm in Sources */,
2D3B5EC81D9B095800451313 /* RCTActivityIndicatorViewManager.m in Sources */,
598FD1961F817335006C54CB /* RCTModalManager.m in Sources */,
3DCD185D1DF978E7007FE5A1 /* RCTReloadCommand.m in Sources */,
@ -4120,6 +4196,7 @@
14C2CA761B3AC64F00E6CBB2 /* RCTFrameUpdate.m in Sources */,
13134C861E296B2A00B9F3CB /* RCTCxxBridge.mm in Sources */,
13B07FEF1A69327A00A75B9A /* RCTAlertManager.m in Sources */,
599FAA4C1FB274980058CCF6 /* RCTSurfaceView.mm in Sources */,
3D7BFD231EA8E351008DFB7A /* RCTReloadPackagerMethod.m in Sources */,
352DCFF01D19F4C20056D623 /* RCTI18nUtil.m in Sources */,
66CD94B71F1045E700CB3C7C /* RCTMaskedViewManager.m in Sources */,
@ -4148,6 +4225,7 @@
3D7BFD171EA8E351008DFB7A /* RCTPackagerClient.m in Sources */,
14F3620D1AABD06A001CE568 /* RCTSwitch.m in Sources */,
13134C8E1E296B2A00B9F3CB /* RCTMessageThread.mm in Sources */,
599FAA381FB274980058CCF6 /* RCTSurface.mm in Sources */,
59D031EF1F8353D3008361F0 /* RCTSafeAreaShadowView.m in Sources */,
3D1E68DB1CABD13900DD7465 /* RCTDisplayLink.m in Sources */,
14F3620E1AABD06A001CE568 /* RCTSwitchManager.m in Sources */,
@ -4159,6 +4237,7 @@
C606692E1F3CC60500E67165 /* RCTModuleMethod.mm in Sources */,
1450FF8A1BCFF28A00208362 /* RCTProfileTrampoline-x86_64.S in Sources */,
13D9FEEB1CDCCECF00158BD7 /* RCTEventEmitter.m in Sources */,
599FAA3E1FB274980058CCF6 /* RCTSurfaceRootShadowView.m in Sources */,
AC70D2E91DE489E4002E6351 /* RCTJavaScriptLoader.mm in Sources */,
14F7A0EC1BDA3B3C003C6C10 /* RCTPerfMonitor.m in Sources */,
5960C1B71F0804A00066FD5B /* RCTLayoutAnimation.m in Sources */,
@ -4169,6 +4248,7 @@
13B080061A6947C200A75B9A /* RCTScrollViewManager.m in Sources */,
137327EA1AA5CF210034F82E /* RCTTabBarManager.m in Sources */,
369123E11DDC75850095B341 /* RCTJSCSamplingProfiler.m in Sources */,
599FAA441FB274980058CCF6 /* RCTSurfaceRootView.mm in Sources */,
C60669361F3CCF1B00E67165 /* RCTManagedPointer.mm in Sources */,
13B080261A694A8400A75B9A /* RCTWrapperViewController.m in Sources */,
13B080051A6947C200A75B9A /* RCTScrollView.m in Sources */,