Skip to content

Commit

Permalink
fix: macOS new architecture build (#2341)
Browse files Browse the repository at this point in the history
# Summary
Based on recommendations from this
[proposition](#2192 (comment))
and added some changes now we can build macOS using the new
architecture.

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| macOS     |    ✅     |

---------

Co-authored-by: Maciej Stosio <[email protected]>
  • Loading branch information
bohdanprog and maciekstosio authored Jul 23, 2024
1 parent 0d97399 commit 67620f5
Show file tree
Hide file tree
Showing 21 changed files with 459 additions and 260 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/macos-build-fabric-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Test new architecture macOS build
on:
pull_request:
paths:
- '.github/workflows/macos-fabric-test.yml'
- 'RNSVG.podspec'
- 'apple/**'
- 'macos-example/package.json'
- 'macos-example/macos/**'
- 'src/fabric/**'
- 'package.json'
push:
branches:
- main

jobs:
reusable-macos-build:
if: github.repository == 'software-mansion/react-native-svg'
uses: ./.github/workflows/reusable-macos-build.yml
with:
new_arch_enabled: '1'
76 changes: 12 additions & 64 deletions .github/workflows/macos-build-test.yml
Original file line number Diff line number Diff line change
@@ -1,73 +1,21 @@
name: Test macOS build
name: Test paper macOS build
on:
pull_request:
paths:
- .github/workflows/macos-build-test.yml
- RNSVG.podspec
- apple/**
- macos-example/package.json
- macos-example/macos/**
- src/fabric/**
- package.json
- '.github/workflows/macos-build-test.yml'
- 'RNSVG.podspec'
- 'apple/**'
- 'macos-example/package.json'
- 'macos-example/macos/**'
- 'src/fabric/**'
- 'package.json'
push:
branches:
- main

jobs:
build:
reusable-macos-build:
if: github.repository == 'software-mansion/react-native-svg'
runs-on: macos-14
strategy:
matrix:
working-directory: [macos-example]
fail-fast: false
concurrency:
group: macos-${{ matrix.working-directory }}-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Check out Git repository
uses: actions/checkout@v3

- name: Restore react-native-svg node_modules from cache
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-modules-svg-${{ hashFiles('yarn.lock') }}
restore-keys: ${{ runner.os }}-node-modules-svg-

- name: Install react-native-svg node_modules
run: yarn install

- name: Restore app node_modules from cache
uses: actions/cache@v3
with:
path: ${{ matrix.working-directory }}/node_modules
key: ${{ runner.os }}-node-modules-${{ matrix.working-directory }}-${{ hashFiles(format('{0}/yarn.lock', matrix.working-directory)) }}
restore-keys: ${{ runner.os }}-node-modules-${{ matrix.working-directory }}-

- name: Install app node_modules
working-directory: ${{ matrix.working-directory }}
run: yarn install

- name: Restore Pods from cache
uses: actions/cache@v3
with:
path: |
${{ matrix.working-directory }}/macos/Pods
~/Library/Caches/CocoaPods
~/.cocoapods
key: ${{ runner.os }}-pods-${{ matrix.working-directory }}-${{ hashFiles(format('{0}/macos/Podfile.lock', matrix.working-directory)) }}

- name: Install Pods
working-directory: ${{ matrix.working-directory }}/macos
run: pod install

- name: Restore build artifacts from cache
uses: actions/cache@v3
with:
path: ~/Library/Developer/Xcode/DerivedData
key: ${{ runner.os }}-macos-derived-data-${{ matrix.working-directory }}-${{ hashFiles(format('{0}/macos/Podfile.lock', matrix.working-directory)) }}

- name: Build app
working-directory: ${{ matrix.working-directory }}
run: yarn macos
uses: ./.github/workflows/reusable-macos-build.yml
with:
new_arch_enabled: '0'
66 changes: 66 additions & 0 deletions .github/workflows/reusable-macos-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Reusable macOS Build

on:
workflow_call:
inputs:
new_arch_enabled:
required: true
type: string

jobs:
build:
runs-on: macos-14
strategy:
matrix:
working-directory: [macos-example]
fail-fast: false
concurrency:
group: macos-${{ matrix.working-directory }}-${{ github.ref }}-${{ inputs.new_arch_enabled }}
cancel-in-progress: true
steps:
- name: Check out Git repository
uses: actions/checkout@v3

- name: Restore react-native-svg node_modules from cache
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-modules-svg-${{ hashFiles('yarn.lock') }}
restore-keys: ${{ runner.os }}-node-modules-svg-

- name: Install react-native-svg node modules
run: yarn install

- name: Restore app node_modules from cache
uses: actions/cache@v3
with:
path: ${{ matrix.working-directory }}/node_modules
key: ${{ runner.os }}-node-modules-${{ matrix.working-directory }}-${{ hashFiles(format('{0}/yarn.lock', matrix.working-directory)) }}
restore-keys: ${{ runner.os }}-node-modules-${{ matrix.working-directory }}-

- name: Install app node modules
working-directory: ${{ matrix.working-directory }}
run: yarn install

- name: Restore Pods from cache
uses: actions/cache@v3
with:
path: |
${{ matrix.working-directory }}/macos/Pods
~/Library/Caches/CocoaPods
~/.cocoapods
key: ${{ runner.os }}-pods-${{ matrix.working-directory }}-${{ hashFiles(format('{0}/macos/Podfile.lock', matrix.working-directory)) }}

- name: Install Pods
working-directory: ${{ matrix.working-directory }}/macos
run: RCT_NEW_ARCH_ENABLED=${{ inputs.new_arch_enabled }} pod install

- name: Restore build artifacts from cache
uses: actions/cache@v3
with:
path: ~/Library/Developer/Xcode/DerivedData
key: ${{ runner.os }}-macos-derived-data-${{ matrix.working-directory }}-${{ hashFiles(format('{0}/macos/Podfile.lock', matrix.working-directory)) }}

- name: Build app
working-directory: ${{ matrix.working-directory }}
run: yarn macos
4 changes: 2 additions & 2 deletions apple/Elements/RNSVGClipPath.mm
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ - (void)parseReference

- (BOOL)isSimpleClipPath
{
NSArray<RNSVGView *> *children = self.subviews;
NSArray<RNSVGPlatformView *> *children = self.subviews;
if (children.count == 1) {
RNSVGView *child = children[0];
RNSVGPlatformView *child = children[0];
if ([child class] != [RNSVGGroup class]) {
return true;
}
Expand Down
11 changes: 1 addition & 10 deletions apple/Elements/RNSVGSvgView.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,12 @@
#import "RNSVGPainter.h"
#import "RNSVGVBMOS.h"

#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTViewComponentView.h>
#endif // RCT_NEW_ARCH_ENABLED

@class RNSVGNode;
@class RNSVGMarker;
@class RNSVGMask;
@class RNSVGFilter;

@interface RNSVGSvgView :
#ifdef RCT_NEW_ARCH_ENABLED
RCTViewComponentView <RNSVGContainer>
#else
RNSVGView <RNSVGContainer>
#endif // RCT_NEW_ARCH_ENABLED
@interface RNSVGSvgView : RNSVGView <RNSVGContainer>

@property (nonatomic, strong) RNSVGLength *bbWidth;
@property (nonatomic, strong) RNSVGLength *bbHeight;
Expand Down
10 changes: 5 additions & 5 deletions apple/Elements/RNSVGSvgView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -119,28 +119,28 @@ - (void)prepareForRecycle
rendered = NO;
}

- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
- (void)mountChildComponentView:(RNSVGView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[super mountChildComponentView:childComponentView index:index];
[self invalidate];
}

- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
- (void)unmountChildComponentView:(RNSVGView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[super unmountChildComponentView:childComponentView index:index];
[self invalidate];
}

#endif // RCT_NEW_ARCH_ENABLED

- (void)insertReactSubview:(RNSVGView *)subview atIndex:(NSInteger)atIndex
- (void)insertReactSubview:(RNSVGPlatformView *)subview atIndex:(NSInteger)atIndex
{
[super insertReactSubview:subview atIndex:atIndex];
[self insertSubview:subview atIndex:atIndex];
[self invalidate];
}

- (void)removeReactSubview:(RNSVGView *)subview
- (void)removeReactSubview:(RNSVGPlatformView *)subview
{
[super removeReactSubview:subview];
[self invalidate];
Expand Down Expand Up @@ -290,7 +290,7 @@ - (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect
_viewBoxTransform = CGAffineTransformIdentity;
_invviewBoxTransform = CGAffineTransformIdentity;
}
for (RNSVGView *node in self.subviews) {
for (RNSVGPlatformView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGNode class]]) {
RNSVGNode *svg = (RNSVGNode *)node;
if (svg.responsible && !self.responsible) {
Expand Down
11 changes: 1 addition & 10 deletions apple/RNSVGNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,14 @@
#import <React/RCTPointerEvents.h>
#import <React/UIView+React.h>

#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTViewComponentView.h>
#endif // RCT_NEW_ARCH_ENABLED

@class RNSVGGroup;

/**
* RNSVG nodes are implemented as base NSViews/UIViews. They should be implementation for all basic
*interfaces for all non-definition nodes.
*/

@interface RNSVGNode :
#ifdef RCT_NEW_ARCH_ENABLED
RCTViewComponentView
#else
RNSVGView
#endif // RCT_NEW_ARCH_ENABLED
@interface RNSVGNode : RNSVGView
/*
N[1/Sqrt[2], 36]
The inverse of the square root of 2.
Expand Down
12 changes: 6 additions & 6 deletions apple/RNSVGNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,27 @@ - (instancetype)init
return self;
}

- (void)insertReactSubview:(RNSVGView *)subview atIndex:(NSInteger)atIndex
- (void)insertReactSubview:(RNSVGPlatformView *)subview atIndex:(NSInteger)atIndex
{
[super insertReactSubview:subview atIndex:atIndex];
[self insertSubview:subview atIndex:atIndex];
[self invalidate];
}

- (void)removeReactSubview:(RNSVGView *)subview
- (void)removeReactSubview:(RNSVGPlatformView *)subview
{
[super removeReactSubview:subview];
[self invalidate];
}

#ifdef RCT_NEW_ARCH_ENABLED
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
- (void)mountChildComponentView:(RNSVGView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[super mountChildComponentView:childComponentView index:index];
[self invalidate];
}

- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
- (void)unmountChildComponentView:(RNSVGView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[super unmountChildComponentView:childComponentView index:index];
[self invalidate];
Expand All @@ -84,7 +84,7 @@ - (void)invalidate
return;
}
_dirty = true;
RNSVGView *container = self.superview;
RNSVGPlatformView *container = self.superview;
// on Fabric, when the child components are added to hierarchy and their props are set,
// their superview is not set yet.
if (container != nil) {
Expand Down Expand Up @@ -240,7 +240,7 @@ - (void)setMatrix:(CGAffineTransform)matrix
}
_matrix = matrix;
_invmatrix = CGAffineTransformInvert(matrix);
RNSVGView *container = self.superview;
RNSVGPlatformView *container = self.superview;
// on Fabric, when the child components are added to hierarchy and their props are set,
// their superview is still their componentView, we change it in `mountChildComponentView` method.
if ([container conformsToProtocol:@protocol(RNSVGContainer)]) {
Expand Down
18 changes: 17 additions & 1 deletion apple/RNSVGUIKit.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// Most (if not all) of this file could probably go away once react-native-macos's version of RCTUIKit.h makes its way
// upstream. https://github.com/microsoft/react-native-macos/issues/242
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTViewComponentView.h>
#endif // RCT_NEW_ARCH_ENABLED

#if !TARGET_OS_OSX

Expand All @@ -8,7 +11,11 @@
#define RNSVGColor UIColor
#define RNSVGPlatformView UIView
#define RNSVGTextView UILabel
#ifdef RCT_NEW_ARCH_ENABLED
#define RNSVGView RCTViewComponentView
#else
#define RNSVGView UIView
#endif // RCT_NEW_ARCH_ENABLED

#else // TARGET_OS_OSX [

Expand All @@ -29,7 +36,16 @@ extern "C" {
#define RNSVGPlatformView NSView
#define RNSVGTextView NSTextView

@interface RNSVGView : RCTUIView
@interface RNSVGColor (CGColor)
- (NSColor *)CGColor;
@end

@interface RNSVGView :
#ifdef RCT_NEW_ARCH_ENABLED
RCTViewComponentView
#else
RCTUIView
#endif // RCT_NEW_ARCH_ENABLED

@property CGPoint center;
@property (nonatomic, strong) RNSVGColor *tintColor;
Expand Down
2 changes: 1 addition & 1 deletion apple/Text/RNSVGTSpan.mm
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ - (CGFloat)getSubtreeTextChunksTotalAdvance

NSString *str = self.content;
if (!str) {
for (RNSVGView *node in self.subviews) {
for (RNSVGPlatformView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGText class]]) {
RNSVGText *text = (RNSVGText *)node;
advance += [text getSubtreeTextChunksTotalAdvance];
Expand Down
2 changes: 1 addition & 1 deletion apple/Text/RNSVGText.mm
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ - (CGFloat)getSubtreeTextChunksTotalAdvance
return cachedAdvance;
}
CGFloat advance = 0;
for (RNSVGView *node in self.subviews) {
for (RNSVGPlatformView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGText class]]) {
RNSVGText *text = (RNSVGText *)node;
advance += [text getSubtreeTextChunksTotalAdvance];
Expand Down
4 changes: 4 additions & 0 deletions apple/Utils/RNSVGFabricConversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ void setCommonNodeProps(const T &nodeProps, RNSVGNode *node)
node.pointerEvents = RCTPointerEventsUnspecified;
}
node.accessibilityIdentifier = RCTNSStringFromStringNilIfEmpty(nodeProps.testId);
#if !TARGET_OS_OSX
node.isAccessibilityElement = nodeProps.accessible;
#else
node.accessibilityElement = nodeProps.accessible;
#endif // !TARGET_OS_OSX
node.accessibilityLabel = RCTNSStringFromStringNilIfEmpty(nodeProps.accessibilityLabel);
}

Expand Down
Loading

0 comments on commit 67620f5

Please sign in to comment.