Սա իրականում իմ առաջին (և ով գիտի, գուցե նաև վերջին) հոդվածն է այստեղ Medium-ում, և այս պահին այն պարզապես փաստաթղթավորում է այն քայլերը, որոնք անհրաժեշտ են iOS-ի համար React Native Turbo մոդուլի ներդրման համար: Ես դժվարություններ ունեի պատշաճ ուղեցույց գտնելու հարցում, և նաև պաշտոնական փաստաթղթերը այնքան էլ լավ չեն իմո գրելու հարցում: Այսպիսով, ես գրում եմ այս հոդվածը իմ ապագա հղումների համար, և հուսով եմ, որ այն նույնպես օգտակար կլինի:

Օգտագործված կարգավորում՝
- RN v0.71
- Vanille RN նախագիծը ստեղծվել է RN CLI-ի միջոցով (պաշտոնական փաստաթղթեր)

Սկսած v0.71-ից՝ RN թիմն իսկապես պարզեցրել է Turbo Modules-ի ամբողջ կարգավորումը: Եթե ​​դուք ավելի հին տարբերակով եք, լրացուցիչ կոդ է պահանջվում, և այս ուղեցույցը անբավարար կլինի:

Քայլ 1. TS Spec ֆայլ

Սա TypeScript (կամ Flow) ինտերֆեյսն է, որը սահմանում է այն հատկություններն ու գործառույթները, որոնք հայրենի կոդը կտրամադրի ձեր React Native հավելվածին: Եկեք ստեղծենք այս ֆայլը RN նախագծի ներսում՝ նոր turbomodules թղթապանակում: Պայմանականորեն ֆայլի անունը պետք է սկսվի Native-ով, և այս օրինակի համար մենք այն կանվանենք NativeTurboModule.ts:

Նշում. ակնհայտորեն հնարավոր է (և, հավանաբար, խորհուրդ է տրվում) ստեղծել առանձին հանգույց փաթեթ ձեր մոդուլների համար, բայց պարզության համար մենք ստեղծում ենք մեր Turbo մոդուլը RN նախագծում:

// YourProject/turbomodules/NativeTurboModule.ts
import type {TurboModule} from 'react-native';
import {TurboModuleRegistry} from 'react-native';
 
export interface Spec extends TurboModule {
  // Define your methods and properties below
}
 
export default TurboModuleRegistry.getEnforcing<Spec>(
  'MyTurboModule', // this is the name of your TurboModule
);

Այժմ մենք պետք է սահմանենք մեր հարմարեցված ինտերֆեյսը այս ֆայլի ներսում, եկեք հիմա գնանք Hello World-ի պարզ օրինակով.

// YourProject/turbomodules/NativeTurboModule.ts
...
export interface Spec extends TurboModule {
 // Define your methods and properties here:
 getTurboHelloWorld(value: string): string;  // Only new line
}
...

Քայլ 2. Codegen

Codegen-ը գործիք է, որը կստեղծի ձեր TS ինտերֆեյսի C++ և Objective-C++ տարբերակը: RN գրադարանի Codegen մասը, սակայն ձեր նախագծի package.json-ի ներսում որոշ լրացուցիչ կազմաձևումներ են պահանջվում.

  // YourProject/package.json
  ...
  "codegenConfig": {
    "name": "NativeTurboModuleSpec",
    "type": "modules",
    "jsSrcsDir": "turbomodules",
  }
  ... 

Հաջորդիվ մեզ անհրաժեշտ է .podspec ֆայլ, քանի որ լրացուցիչ Pod կստեղծվի Turbo Module-ի համար: Այսպիսով, մեր TS հատուկ ֆայլի կողքին ստեղծեք ևս մեկ նոր ֆայլ:

# YourProject/turbomodules/TurboPodSpec.podspec
require "json"

package = JSON.parse(File.read(File.join(__dir__, "../package.json")))

Pod::Spec.new do |s|
  s.name            = "TurboPodSpec"
  s.version         = "version"
  s.summary         = "summary"
  s.description     = "description"
  s.homepage        = "homepage"
  s.license         = "license"
  s.platforms       = { :ios => "12.4" }
  s.authors         = "author"
  s.source          = { :git => '' }
  s.source_files    = "ios/**/*.{h,m,mm,swift}"
  s.pod_target_xcconfig = {
    "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
  }
  install_modules_dependencies(s)
end

Եվ հետո մենք պարզապես պետք է ավելացնենք այս Pod-ը մեր նախագծի Podfile-ում, և մենք կստուգենք, որպեսզի համոզվենք, որ նոր RN ճարտարապետությունը միացված է այն ավելացնելիս:

# YourProject/ios/Podfile
  use_react_native!(
    ... 
  )

  # Add this below the use_react_native! directive 
  if ENV['RCT_NEW_ARCH_ENABLED'] == '1'
    pod 'TurboPodSpec', :path => "./../turbomodules"
  end

Սա այն ամենն է, ինչ մեզ անհրաժեշտ է, որպեսզի Codegen-ը կարողանա ստեղծել տեղական ինտերֆեյս iOS-ի համար: Նոր ճարտարապետության համար պատյաններ տեղադրելիս Codegen-ը ավտոմատ կերպով գործարկվում է որպես գործընթացի մաս: Այսպիսով, գործարկեք ստորև նշված հրամանը ձեր RN նախագծի ios թղթապանակում.

RCT_NEW_ARCH_ENABLED=1 bundle exec pod install

Ios թղթապանակի ներսում դուք այժմ կգտնեք բոլորովին նոր build թղթապանակ, որը պարունակում է մի փունջ C++ և Objective-C++ ֆայլեր և կոդ:

Քայլ 3. Մայրենի ծածկագիր

Այժմ ամեն ինչ տեղում է, որպեսզի սկսեք գրել ձեր հայրենի կոդը: Ավելացրեք Objective-C++ վերնագիր և իրականացում (. մմ ֆայլ) ֆայլ XCode-ում: Սովորական Objective-C (.m ֆայլ) իրականացման ֆայլը բավարար չէ, քանի որ այն հղում է կատարելու C++ կոդին: Սկսենք վերնագրի ֆայլից.

// YourProject/ios/MyTurboModule.h
// Name needs to be the same as defined inside your TS Spec file
#import <NativeTurboModuleSpec/NativeTurboModuleSpec.h>
 
@interface MyTurboModule: NSObject <NativeTurboModuleSpec>
@end

Եվ հաջորդ հետաքրքիր մասը՝ իրականացման ֆայլի ներսում.

// YourProject/ios/MyTurboModule.mm
#import "MyTurboModule"

@implementation MyTurboModule
 
-(std::shared_ptr<facebook::react::TurboModule>)getTurboModule: (const facebook::react::ObjCTurboModule::InitParams &)params {
  return std::make_shared<facebook::react::NativeTurboModuleSpecJSI>(params);
}
 
@end

Վերևում մենք գրանցում ենք հայրենի մոդուլը: Եթե ​​դուք պահում եք այն այսպես, XCode-ը պետք է նախազգուշացնի ձեզ, որ իրականացումն ավարտված չէ, քանի որ այն բացակայում է մեր ինտերֆեյսում սահմանված գործառույթից: Այսպիսով, եկեք ավելացնենք.

// YourProject/ios/MyTurboModule.mm
#import "MyTurboModule"

@implementation TurboPill
 
-(std::shared_ptr<facebook::react::TurboModule>)getTurboModule: (const facebook::react::ObjCTurboModule::InitParams &)params {
  return std::make_shared<facebook::react::NativeTurboModuleSpecJSI>(params);
}
 
- (NSString *)getTurboHelloWorld:(NSString *)value {
  return [NSString stringWithFormat:@"Hello world from turbo module: %@", value];
}

@end

Քանի որ մենք ներդնում ենք այս ամբողջը, մենք դեռ պետք է ինչ-որ տեղ ներմուծենք կոդը: Այսպիսով, եկեք ներմուծենք այն մեր AppDelegate.mm ներսում:

#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>

#import "MyTurboModule" // Only addition! 

// rest of delegate  ... 

Վերջնական քայլ. React Native!

Եվ հիմա ամեն ինչ տեղում է, որպեսզի սկսենք փորձարկել մեր Turbo մոդուլը: Գնացեք App.tsx,ներմուծեք մեր մոդուլը և փորձարկեք այն.

import TheModule from './turbomodules/NativeTurboModule';

function App(): JSX.Element {
  
  return (
    <Text>{TheModule.getTurboHelloWorld("Does this thing work?")}</Text>
  );
}

Դա այն էր, շնորհակալություն կարդալու համար և հուսով եմ, որ օգտակար էր: