Skip to content

Commit

Permalink
Setup new architecture
Browse files Browse the repository at this point in the history
  • Loading branch information
j-piasecki committed Sep 26, 2024
1 parent d91dd2c commit ebb5ac3
Show file tree
Hide file tree
Showing 19 changed files with 212 additions and 96 deletions.
20 changes: 6 additions & 14 deletions android/src/main/java/com/newarchtricks/NewArchTricksModule.kt
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
package com.newarchtricks

import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import com.facebook.react.module.annotations.ReactModule

class NewArchTricksModule(reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {
@ReactModule(name = NewArchTricksModule.NAME)
class NewArchTricksModule(reactContext: ReactApplicationContext) : NativeNewArchTricksModuleSpec(reactContext) {
override fun getName() = NAME

override fun getName(): String {
return NAME
}

// Example method
// See https://reactnative.dev/docs/native-modules-android
@ReactMethod
fun multiply(a: Double, b: Double, promise: Promise) {
promise.resolve(a * b)
override fun multiply(a: Double, b: Double): Double {
return a * b
}

companion object {
Expand Down
32 changes: 25 additions & 7 deletions android/src/main/java/com/newarchtricks/NewArchTricksPackage.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
package com.newarchtricks

import com.facebook.react.ReactPackage
import com.facebook.react.TurboReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.module.model.ReactModuleInfo
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.facebook.react.uimanager.ViewManager


class NewArchTricksPackage : ReactPackage {
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return listOf(NewArchTricksModule(reactContext))
}

class NewArchTricksPackage : TurboReactPackage() {
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
return listOf(NewArchTricksViewManager())
}

override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =
if (name == NewArchTricksModule.NAME) {
NewArchTricksModule(reactContext)
} else {
null
}

override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
mapOf(
NewArchTricksModule.NAME to ReactModuleInfo(
NewArchTricksModule.NAME,
NewArchTricksModule.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
false, // isCxxModule
true // isTurboModule
)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.newarchtricks

import android.graphics.Color
import android.view.View
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.viewmanagers.NewArchTricksViewManagerDelegate
import com.facebook.react.viewmanagers.NewArchTricksViewManagerInterface

@ReactModule(name = NewArchTricksViewManager.NAME)
class NewArchTricksViewManager : SimpleViewManager<View>(), NewArchTricksViewManagerInterface<View> {
private val delegate = NewArchTricksViewManagerDelegate(this)

override fun getDelegate() = delegate
override fun getName() = NAME

override fun createViewInstance(reactContext: ThemedReactContext): View {
return View(reactContext)
}

@ReactProp(name = "color")
override fun setColor(view: View?, color: String?) {
view!!.setBackgroundColor(Color.parseColor(color))
}

companion object {
const val NAME = "NewArchTricksView"
}
}
2 changes: 1 addition & 1 deletion example/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=false
newArchEnabled=true

# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
Expand Down
1 change: 1 addition & 0 deletions example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ENV['RCT_NEW_ARCH_ENABLED'] = '1'
# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
'require.resolve(
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,6 @@ SPEC CHECKSUMS:
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: 659904f0b473181ce89df322ba464fd98aeb691c

PODFILE CHECKSUM: 6ae25aa93d9d88784af0e95de45db492e4ffbdcc
PODFILE CHECKSUM: 5a43c81d384e2cb7bb11df6f2f4dbe0be6375976

COCOAPODS: 1.15.2
15 changes: 5 additions & 10 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { useState, useEffect } from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { multiply } from 'react-native-new-arch-tricks';
import { StyleSheet, View, Pressable } from 'react-native';
import { NewArchTricksView, multiply } from 'react-native-new-arch-tricks';

export default function App() {
const [result, setResult] = useState<number | undefined>();

useEffect(() => {
multiply(3, 7).then(setResult);
}, []);

return (
<View style={styles.container}>
<Text>Result: {result}</Text>
<Pressable onPress={() => console.log(multiply(3, 7))}>
<NewArchTricksView color="#32a852" style={styles.box} />
</Pressable>
</View>
);
}
Expand Down
12 changes: 2 additions & 10 deletions ios/NewArchTricks.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
#import <NewArchTricksSpec/NewArchTricksSpec.h>

#ifdef RCT_NEW_ARCH_ENABLED
#import "RNNewArchTricksSpec.h"

@interface NewArchTricks : NSObject <NativeNewArchTricksSpec>
#else
#import <React/RCTBridgeModule.h>

@interface NewArchTricks : NSObject <RCTBridgeModule>
#endif

@interface NewArchTricks : NSObject <NativeNewArchTricksModuleSpec>
@end
24 changes: 15 additions & 9 deletions ios/NewArchTricks.mm
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
#import "NewArchTricks.h"

#import <React/RCTBridge+Private.h>
#import <React/RCTBridge.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTUtils.h>
#import <ReactCommon/CallInvoker.h>
#import <ReactCommon/RCTTurboModule.h>

#import <react/renderer/uimanager/primitives.h>

@implementation NewArchTricks
RCT_EXPORT_MODULE()

// Example method
// See // https://reactnative.dev/docs/native-modules-ios
RCT_EXPORT_METHOD(multiply:(double)a
b:(double)b
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
- (NSNumber *)multiply:(double)a b:(double)b
{
NSNumber *result = @(a * b);

resolve(result);
return [[NSNumber alloc] initWithDouble:a * b];
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeNewArchTricksModuleSpecJSI>(params);
}

@end
6 changes: 6 additions & 0 deletions ios/NewArchTricksViewComponentView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#import <UIKit/UIKit.h>
#import <React/RCTViewComponentView.h>

@interface NewArchTricksViewComponentView : RCTViewComponentView

@end
73 changes: 73 additions & 0 deletions ios/NewArchTricksViewComponentView.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#import "NewArchTricksViewComponentView.h"

// without this header the provider won't be found by RN
#import <React/RCTFabricComponentsPlugins.h>

#import <react/renderer/components/NewArchTricksSpec/ComponentDescriptors.h>
#import <react/renderer/components/NewArchTricksSpec/EventEmitters.h>
#import <react/renderer/components/NewArchTricksSpec/Props.h>
#import <react/renderer/components/NewArchTricksSpec/RCTComponentViewHelpers.h>

using namespace facebook::react;

@interface NewArchTricksViewComponentView () <RCTNewArchTricksViewViewProtocol>
@end

@implementation NewArchTricksViewComponentView {
UIView *_customView;
}

// Needed because of this: https://github.com/facebook/react-native/pull/37274
+ (void)load
{
[super load];
}

- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const NewArchTricksViewProps>();
_props = defaultProps;
_customView = [[UIView alloc] initWithFrame:self.bounds];

self.contentView = _customView;
}

return self;
}

- hexStringToColor:(NSString *)stringToConvert
{
NSString *noHashString = [stringToConvert stringByReplacingOccurrencesOfString:@"#" withString:@""];
NSScanner *stringScanner = [NSScanner scannerWithString:noHashString];

unsigned hex;
if (![stringScanner scanHexInt:&hex]) return nil;
int r = (hex >> 16) & 0xFF;
int g = (hex >> 8) & 0xFF;
int b = (hex) & 0xFF;

return [UIColor colorWithRed:r / 255.0f green:g / 255.0f blue:b / 255.0f alpha:1.0f];
}

#pragma mark - RCTComponentViewProtocol

+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<NewArchTricksViewComponentDescriptor>();
}

- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
{
const auto &newProps = *std::static_pointer_cast<const NewArchTricksViewProps>(props);

[_customView setBackgroundColor:[self hexStringToColor:[NSString stringWithUTF8String:newProps.color.c_str()]]];

[super updateProps:props oldProps:oldProps];
}
@end

Class<RCTComponentViewProtocol> NewArchTricksViewCls(void)
{
return NewArchTricksViewComponentView.class;
}
11 changes: 11 additions & 0 deletions ios/NewArchTricksViewManager.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#import <React/RCTViewManager.h>

@interface NewArchTricksViewManager : RCTViewManager
@end

@implementation NewArchTricksViewManager

RCT_EXPORT_MODULE(NewArchTricksView)
RCT_EXPORT_VIEW_PROPERTY(color, NSString)

@end
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,13 @@
"type": "module-legacy",
"languages": "kotlin-objc",
"version": "0.41.2"
},
"codegenConfig": {
"name": "NewArchTricksSpec",
"type": "all",
"jsSrcsDir": "./src/specs",
"android": {
"javaPackageName": "com.newarchtricks"
}
}
}
23 changes: 1 addition & 22 deletions react-native-new-arch-tricks.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,5 @@ Pod::Spec.new do |s|

s.source_files = "ios/**/*.{h,m,mm}"

# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
if respond_to?(:install_modules_dependencies, true)
install_modules_dependencies(s)
else
s.dependency "React-Core"

# Don't install the dependencies when we run `pod install` in the old architecture.
if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then
s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
"OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
}
s.dependency "React-Codegen"
s.dependency "RCT-Folly"
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
end
end
install_modules_dependencies(s)
end
5 changes: 5 additions & 0 deletions src/NewArchTricksModule.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import NativeNewArchTricksModule from './specs/NativeNewArchTricksModule';

export function multiply(a: number, b: number): number {
return NativeNewArchTricksModule.multiply(a, b);
}
3 changes: 3 additions & 0 deletions src/NewArchTricksView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import NewArchTricksNativeComponent from './specs/NewArchTricksNativeComponent';

export { NewArchTricksNativeComponent as NewArchTricksView };
24 changes: 2 additions & 22 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,2 @@
import { NativeModules, Platform } from 'react-native';

const LINKING_ERROR =
`The package 'react-native-new-arch-tricks' doesn't seem to be linked. Make sure: \n\n` +
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
'- You rebuilt the app after installing the package\n' +
'- You are not using Expo Go\n';

const NewArchTricks = NativeModules.NewArchTricks
? NativeModules.NewArchTricks
: new Proxy(
{},
{
get() {
throw new Error(LINKING_ERROR);
},
}
);

export function multiply(a: number, b: number): Promise<number> {
return NewArchTricks.multiply(a, b);
}
export { NewArchTricksView } from './NewArchTricksView';
export { multiply } from './NewArchTricksModule';
8 changes: 8 additions & 0 deletions src/specs/NativeNewArchTricksModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
multiply(a: number, b: number): number;
}

export default TurboModuleRegistry.getEnforcing<Spec>('NewArchTricks');
8 changes: 8 additions & 0 deletions src/specs/NewArchTricksNativeComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
import type { ViewProps } from 'react-native';

interface NativeProps extends ViewProps {
color: string;
}

export default codegenNativeComponent<NativeProps>('NewArchTricksView');

0 comments on commit ebb5ac3

Please sign in to comment.