### Clone Nitro Repository and Install Dependencies (Windows/Linux) Source: https://nitro.margelo.com/docs/guides/running-example-app Clones the Nitro repository, navigates into the directory, installs dependencies, and builds the project using Bun. This is the initial setup for building the example app on Windows or Linux. ```shell git clone https://github.com/mrousavy/nitro cd nitro bun i bun run build ``` -------------------------------- ### Install Dependencies with Bun Source: https://nitro.margelo.com/docs/resources/contributing Installs all project dependencies and builds the project using Bun. Ensure Bun is installed and you are in the root of the cloned repository. ```sh bun install bun run build ``` -------------------------------- ### Install Local NPM Package Source: https://nitro.margelo.com/docs/getting-started/how-to-build-a-nitro-module Install your local Nitro module into an example application. This command assumes your example app is in a subdirectory named 'example' and your module is in the parent directory. ```bash cd example npm install ../ ``` -------------------------------- ### Install Nitro Docs Dependencies Source: https://nitro.margelo.com/docs/resources/contributing Navigate to the 'docs/' directory and install project dependencies using bun. ```shell cd docs bun install ``` -------------------------------- ### Clone Nitro Repository and Bootstrap Dependencies (macOS) Source: https://nitro.margelo.com/docs/guides/running-example-app Clones the Nitro repository, navigates into the directory, and installs dependencies using Bun. This is the initial setup for building the example app on macOS. ```shell git clone https://github.com/mrousavy/nitro cd nitro bun bootstrap ``` -------------------------------- ### Synchronous Get Example (react-native-mmkv) Source: https://nitro.margelo.com/docs/guides/sync-vs-async Demonstrates getting a string value synchronously from react-native-mmkv. This is suitable for light operations where immediate return is desired. ```typescript function App() { const mmkv = new MMKV() const name = mmkv.getString('username') // --> Marc } ``` -------------------------------- ### Install iOS Dependencies Source: https://nitro.margelo.com/docs/resources/contributing Installs CocoaPods dependencies for iOS development after cloning the repository. This command should be run from the `example/` directory. ```sh cd example bundle install bun pods ``` -------------------------------- ### Asynchronous Get Example (react-native-mmkv) Source: https://nitro.margelo.com/docs/guides/sync-vs-async Illustrates how getting a value would be handled asynchronously using `useState` and `useEffect`. This approach is more cumbersome for simple synchronous operations. ```typescript function App() { const mmkv = new MMKV() const [name, setName] = useState(undefined) useEffect(() => { (async () => { const n = await mmkv.getString('username') // --> Marc setName(n) })() }, []) } ``` -------------------------------- ### Start Android Emulator Source: https://nitro.margelo.com/docs/guides/running-example-app Lists available Android Virtual Devices (AVDs) and starts a specified emulator. This is a prerequisite for dragging and dropping the .apk file onto it. ```shell emulator -list-avds emulator -avd ``` -------------------------------- ### Create an Expo Example App Source: https://nitro.margelo.com/docs/concepts/nitro-modules Set up a new Expo project to test your Nitro Module. ```sh npx create-expo-app@latest ``` -------------------------------- ### Install React Native Nitro Modules (bun) Source: https://nitro.margelo.com/docs/resources/for-library-users Install the core package using bun and run pod install for iOS dependencies. ```sh bun i react-native-nitro-modules cd ios && pod install ``` -------------------------------- ### Install Nitrogen with bun Source: https://nitro.margelo.com/docs/concepts/nitrogen Install Nitrogen as a development dependency using bun. This command is typically run in the root directory of a Nitro Module. ```sh bun i nitrogen -d ``` -------------------------------- ### Open iOS Simulator Source: https://nitro.margelo.com/docs/guides/running-example-app Starts the iOS Simulator application. This is a prerequisite for dragging and dropping the .app file onto it. ```shell open -a Simulator ``` -------------------------------- ### Generated C++ Namespace Example Source: https://nitro.margelo.com/docs/getting-started/configuration-nitro-json This shows how the `cxxNamespace` configuration translates into a C++ namespace. ```cpp namespace margelo::nitro::math::extra { // ...generated classes } ``` -------------------------------- ### Install Custom Nitro Dispatcher Source: https://nitro.margelo.com/docs/guides/worklets C++ code to install a custom Dispatcher for a JSI runtime. This should be done once after the runtime is created. ```cpp auto myDispatcher = std::make_shared(); Dispatcher::installRuntimeGlobalDispatcher(myRuntime, myDispatcher); ``` -------------------------------- ### Run Nitro Docs Development Server Source: https://nitro.margelo.com/docs/resources/contributing Start the Docusaurus development server for the Nitro documentation. ```shell bun start ``` -------------------------------- ### Install Nitrogen with pnpm Source: https://nitro.margelo.com/docs/concepts/nitrogen Install Nitrogen as a development dependency using pnpm. This command is typically run in the root directory of a Nitro Module. ```sh pnpm add nitrogen -D ``` -------------------------------- ### Create a Bare React Native Example App Source: https://nitro.margelo.com/docs/concepts/nitro-modules Initialize a new Bare React Native project for testing your Nitro Module. ```sh npx @react-native-community/cli@latest init NitroMathExample ``` -------------------------------- ### Open Android Studio Source: https://nitro.margelo.com/docs/guides/running-example-app Opens the Android Studio application. This is a step required before opening the example app's Android project. ```shell open -a "Android Studio" ``` -------------------------------- ### Run Nitrogen for Initial Code Generation Source: https://nitro.margelo.com/docs/getting-started/how-to-build-a-nitro-module Execute the Nitrogen CLI once after creating the 'nitro.json' file to generate the autolinking setup. ```sh npx nitrogen ``` -------------------------------- ### Manually Install Nitro with Dispatcher Source: https://nitro.margelo.com/docs/guides/entry-point Use this snippet to install Nitro modules in a pure JSI environment when you have a Dispatcher instance. Ensure your Dispatcher correctly implements runAsync and runSync. ```cpp #include \n#include \n#include \n\njsi::Runtime& runtime = ...\nstd::shared_ptr dispatcher = ...\nmargelo::nitro::install(runtime, dispatcher); ``` -------------------------------- ### Install React Native Nitro Modules (npm) Source: https://nitro.margelo.com/docs/resources/for-library-users Install the core package using npm and run pod install for iOS dependencies. ```sh npm i react-native-nitro-modules cd ios && pod install ``` -------------------------------- ### Install React Native Nitro Modules (pnpm) Source: https://nitro.margelo.com/docs/resources/for-library-users Install the core package using pnpm and run pod install for iOS dependencies. ```sh pnpm add react-native-nitro-modules cd ios && pod install ``` -------------------------------- ### Swift Callback Example Source: https://nitro.margelo.com/docs/types/callbacks In Swift, callbacks are implemented using closures. This example demonstrates a function that accepts a closure taking a User object. ```swift func start(onNewUserJoined: (User) -> Void) { onNewUserJoined(user) } ``` -------------------------------- ### Install Nitrogen with npm Source: https://nitro.margelo.com/docs/concepts/nitrogen Install Nitrogen as a development dependency using npm. This command is typically run in the root directory of a Nitro Module. ```sh npm i nitrogen --save-dev ``` -------------------------------- ### Install Nitrogen with yarn Source: https://nitro.margelo.com/docs/concepts/nitrogen Install Nitrogen as a development dependency using yarn. This command is typically run in the root directory of a Nitro Module. ```sh yarn add nitrogen -D ``` -------------------------------- ### Install React Native Nitro Modules (yarn) Source: https://nitro.margelo.com/docs/resources/for-library-users Install the core package using yarn and run pod install for iOS dependencies. ```sh yarn add react-native-nitro-modules cd ios && pod install ``` -------------------------------- ### Typed Map Example in C++ Source: https://nitro.margelo.com/docs/types/typed-maps Presents the C++ implementation of a typed map for user ages using std::unordered_map. ```cpp class HybridDatabase: public HybridDatabaseSpec { std::unordered_map getAllUsers(); } ``` -------------------------------- ### Example CMakeLists.txt for C++ Library Source: https://nitro.margelo.com/docs/getting-started/configuration-nitro-json This CMakeLists.txt defines a shared library named NitroMath, which is loaded by JNI. ```cmake project(NitroMath) add_library(NitroMath SHARED src/main/cpp/cpp-adapter.cpp ../cpp/HybridMath.cpp ) ``` -------------------------------- ### Install Nitro and Nitrogen Dev Dependencies Source: https://nitro.margelo.com/docs/getting-started/how-to-build-a-nitro-module Install the necessary Nitro and Nitrogen packages as development dependencies in an existing React Native library. ```sh npm install react-native-nitro-modules --save-dev npm install nitrogen --save-dev ``` -------------------------------- ### Use Custom ImageView Component Source: https://nitro.margelo.com/docs/guides/view-components Example of using the custom `` component in an application. It demonstrates loading an image and passing it as a prop to the `imageview`. ```jsx function App() { const image = await loadImage('https://...') return } ``` -------------------------------- ### Typed Map Example in Kotlin Source: https://nitro.margelo.com/docs/types/typed-maps Illustrates the use of a typed map for user ages in Kotlin, utilizing the Map type. ```kotlin class HybridDatabase: HybridDatabaseSpec() { fun getAllUsers(): Map } ``` -------------------------------- ### Manually Install Nitro without Dispatcher Source: https://nitro.margelo.com/docs/guides/entry-point Install Nitro modules in a pure JSI environment without a Dispatcher. Note that asynchronous operations will throw an error in this configuration. ```cpp #include \n#include \n\njsi::Runtime& runtime = ...\nmargelo::nitro::install(runtime); ``` -------------------------------- ### Typed Map Example in Swift Source: https://nitro.margelo.com/docs/types/typed-maps Shows the equivalent of a typed map for user ages using Swift's Dictionary type. ```swift class HybridDatabase: HybridDatabaseSpec { func getAllUsers() -> Dictionary } ``` -------------------------------- ### C++ Callback Example Source: https://nitro.margelo.com/docs/types/callbacks In C++, callbacks are handled using std::function. This example defines a function that accepts a std::function object for callbacks. ```cpp void start(std::function onNewUserJoined) { onNewUserJoined(user); } ``` -------------------------------- ### Legacy React Native Callback Limitation Example Source: https://nitro.margelo.com/docs/types/callbacks This example demonstrates a scenario that was not possible in legacy React Native due to the limitation of only two callbacks per native method. Nitro overcomes this limitation. ```typescript interface Camera { startRecording(onStatusUpdate: () => void, onRecordingFailed: () => void, onRecordingFinished: () => void): Promise } ``` -------------------------------- ### Turbo Module Implementation in Objective-C Source: https://nitro.margelo.com/docs/resources/comparison Example of a Turbo Module implemented in Objective-C, showcasing an 'add' function. This is the standard way to build Turbo Modules for iOS. ```objectivec @implementation RTNMath RCT_EXPORT_MODULE() - (NSNumber*)add:(NSNumber*)a b:(NSNumber*)b { double added = a.doubleValue + b.doubleValue; return [NSNumber numberWithDouble:added]; } @end ``` -------------------------------- ### TypeScript Tuple Type Example Source: https://nitro.margelo.com/docs/resources/comparison Shows the TypeScript syntax for defining a tuple type, which is not supported in Turbo Modules. ```typescript type SomeTuple = [number, number] ``` -------------------------------- ### Typed Map Example in TypeScript Source: https://nitro.margelo.com/docs/types/typed-maps Demonstrates how to define a typed map for user ages in TypeScript. Note that Nitro cannot optimize typed maps as keys are not known in advance. ```typescript interface Database extends HybridObject<{ ... }> { getAllUsers(): Record } ``` -------------------------------- ### Nitro Module Implementation in Swift Source: https://nitro.margelo.com/docs/resources/comparison Example of a Nitro Module implemented in Swift, demonstrating a simple 'add' function. Requires the HybridMathSpec interface. ```swift class HybridMath : HybridMathSpec { func add(a: Double, b: Double) -> Double { return a + b } } ``` -------------------------------- ### Nitro Module Event Listener (Swift) Source: https://nitro.margelo.com/docs/resources/comparison Example of how Nitro Modules handle event listeners using first-class functions in Swift. ```swift class Math: MathSpec { var listeners: [(String) -> Void] = [] func addListener(listener: (String) -> Void) { listeners.add(listener) } func onSomethingChanged() { for listener in listeners { listener("something changed!") } } } ``` -------------------------------- ### Nitro Module Image Cropping (Swift) Source: https://nitro.margelo.com/docs/resources/comparison Example of handling native objects like images directly within a Nitro Module using Swift. ```swift class HybridImageEditor: HybridImageEditorSpec { func crop(image: HybridImage, size: Size) -> HybridImage { let original = image.cgImage let cropped = original.cropping(to: size) return HybridImage(cgImage: cropped) } } ``` -------------------------------- ### Kotlin Callback Example Source: https://nitro.margelo.com/docs/types/callbacks In Kotlin, callbacks are represented as lambdas. This snippet shows a function accepting a lambda that takes a User object. ```kotlin fun start(onNewUserJoined: (User) -> Unit) { onNewUserJoined(user) } ``` -------------------------------- ### Implement Native Struct Retrieval Source: https://nitro.margelo.com/docs/types/custom-structs Implement the native method to retrieve a 'Person' struct. This Swift example shows how to create and return an instance of the 'Person' struct. ```swift class HybridNitro: HybridNitroSpec { func getAuthor() -> Person { return Person(name: "Marc", age: 24) } } ``` -------------------------------- ### Kotlin Class for Fetch with AnyMap Source: https://nitro.margelo.com/docs/types/untyped-maps Provides a Kotlin class for Fetch operations, with a get method designed to return an AnyMap. ```kotlin class HybridFetch: HybridFetchSpec() { fun get(url: String): AnyMap } ``` -------------------------------- ### TypeScript Callback with Return Value Example Source: https://nitro.margelo.com/docs/resources/comparison Illustrates a TypeScript callback function that is designed to return a value, a feature not supported by Turbo Modules. ```typescript type SomeCallback = () => number ``` -------------------------------- ### Access Hybrid Object from JavaScript Source: https://nitro.margelo.com/docs/getting-started/what-is-nitro Access and use a Hybrid Object implemented in native code directly from JavaScript. This example creates an instance of the 'Math' Hybrid Object and calls its 'add' method. ```javascript const math = NitroModules.createHybridObject('Math') const result = math.add(5, 7) ``` -------------------------------- ### Reset Image View State for Recycling (Swift) Source: https://nitro.margelo.com/docs/guides/view-components Example of implementing `prepareForRecycle` in a Swift `HybridImageView` to reset the `UIImageView`'s image to `nil`. This prevents displaying stale images when the view is recycled. ```swift class HybridImageView: HybridImageViewSpec, RecyclableView { var view: UIView { imageView } private var imageView = UIImageView() func prepareForRecycle() { // highlight-next-line imageView.image = nil } } ``` -------------------------------- ### C++ Class for Fetch with AnyMap Source: https://nitro.margelo.com/docs/types/untyped-maps Defines a C++ class for Fetch operations, including a get method that returns a shared pointer to an AnyMap. ```cpp class HybridFetch: public HybridFetchSpec { std::shared_ptr get(const std::string& url); } ``` -------------------------------- ### TypeScript Callback Example Source: https://nitro.margelo.com/docs/types/callbacks In TypeScript, callbacks are defined as anonymous functions. This example shows the signature for a callback that accepts a User object. ```typescript interface Server extends HybridObject<{ ... }> { start(onNewUserJoined: (user: User) => void): void } ``` -------------------------------- ### Bootstrap Nitro Module with Nitrogen CLI Source: https://nitro.margelo.com/docs/getting-started/how-to-build-a-nitro-module Use the Nitrogen CLI to initialize a new Nitro Module project. ```sh npx nitrogen@latest init ``` -------------------------------- ### Bootstrap React Native Library with Bob Source: https://nitro.margelo.com/docs/getting-started/how-to-build-a-nitro-module Use the create-react-native-library tool to bootstrap a new React Native library, which can be adapted for Nitro. ```sh npx create-react-native-library@latest ``` -------------------------------- ### Create Native ArrayBuffers (C++) Source: https://nitro.margelo.com/docs/types/array-buffers Illustrates creating owning ArrayBuffers in C++ by wrapping, copying, or allocating. The wrap function requires a callback for deallocation, and copy creates a new buffer from existing data. ```cpp auto myData = new uint8_t[4096]; // wrap (no copy) auto wrappingArrayBuffer = ArrayBuffer::wrap(myData, 4096, [=]() { delete[] myData; }); // copy auto copiedArrayBuffer = ArrayBuffer::copy(myData, 4096); // new blank buffer auto newArrayBuffer = ArrayBuffer::allocate(4096); ``` -------------------------------- ### Bootstrap Nitro Module with create-nitro-module Source: https://nitro.margelo.com/docs/getting-started/how-to-build-a-nitro-module Use the create-nitro-module CLI tool to initialize a new Nitro Module project. ```sh npx create-nitro-module@latest ``` -------------------------------- ### Initialize a New Nitro Module Source: https://nitro.margelo.com/docs/concepts/nitro-modules Use this command to create a new Nitro Module project with the specified module name. ```sh npx nitrogen@latest init react-native-math ``` -------------------------------- ### Implementing Async Method in C++ Source: https://nitro.margelo.com/docs/guides/sync-vs-async Shows how to implement an asynchronous native method in C++. It utilizes `Promise::async` to execute the `computeBitcoin` function on a background thread, ensuring the JS Thread remains responsive. ```cpp std::shared_ptr> mineOneBitcoin() override { // 1. synchronous in here, JS Thread is still blocked // useful e.g. for argument checking before starting async Thread return Promise::async([]() { // 2. asynchronous in here, JS Thread is now free return computeBitcoin(); }); } ``` -------------------------------- ### Create and Use a Hybrid Object from JavaScript Source: https://nitro.margelo.com/docs/concepts/hybrid-objects Demonstrates how to create an instance of a Hybrid Object (Math) from JavaScript using `createHybridObject` and call its methods. ```typescript const math = NitroModules.createHybridObject("Math") const result = math.add(5, 7) ``` -------------------------------- ### Overriding toString() in C++ Source: https://nitro.margelo.com/docs/concepts/hybrid-objects Example of overriding the toString() method for a Hybrid Object in C++. ```cpp class HybridMath: public HybridMathSpec { std::string toString() override { return "{HybridMath}"; } }; ``` -------------------------------- ### Overriding toString() in Kotlin Source: https://nitro.margelo.com/docs/concepts/hybrid-objects Example of overriding the toString() method for a Hybrid Object in Kotlin. ```kotlin class HybridMath : HybridMathSpec() { override fun toString(): String { return "{HybridMath}" } } ``` -------------------------------- ### Overriding toString() in Swift Source: https://nitro.margelo.com/docs/concepts/hybrid-objects Example of overriding the toString() method for a Hybrid Object in Swift. ```swift class HybridMath : HybridMathSpec { func toString() -> String { return "{HybridMath}" } } ``` -------------------------------- ### Create Native ArrayBuffers (Swift) Source: https://nitro.margelo.com/docs/types/array-buffers Demonstrates creating owning ArrayBuffers in Swift by wrapping, copying, or allocating. The wrap function requires a callback to deallocate the original pointer. ```swift let myData = UnsafeMutablePointer.allocate(capacity: 4096) // wrap (no copy) let wrappingArrayBuffer = ArrayBuffer.wrap(dataWithoutCopy: myData, size: 4096, onDelete: { myData.deallocate() }) // copy let copiedArrayBuffer = ArrayBuffer.copy(of: wrappingArrayBuffer) // new blank buffer let newArrayBuffer = ArrayBuffer.allocate(size: 4096) ``` -------------------------------- ### Manual Hybrid Object Registration Source: https://nitro.margelo.com/docs/types/custom-types Demonstrates manual registration of hybrid methods for a `MyHybrid` class, including the `doSomething` method that accepts a `std::shared_ptr`. Ensure the `JSIConverter` header is included. ```cpp #pragma once #include "JSIConverter+ShadowNode.hpp" // ... class MyHybrid: public HybridObject { public: void doSomething(std::shared_ptr view) override { // ... } void loadHybridMethods() { HybridObject::loadHybridMethods(); registerHybrids(this, [](Prototype& prototype) { prototype.registerHybridMethod("doSomething", &MyHybrid::doSomething); }); } }; ``` -------------------------------- ### Create Native ArrayBuffers (Kotlin) Source: https://nitro.margelo.com/docs/types/array-buffers Shows how to create owning ArrayBuffers in Kotlin by wrapping, copying, or allocating. The wrap function takes a ByteBuffer, and copy creates a new buffer from an existing one. ```kotlin val myData = ByteBuffer.allocateDirect(4096) // wrap (no copy) val wrappingArrayBuffer = ArrayBuffer.wrap(myData) // copy let copiedArrayBuffer = ArrayBuffer.copy(myData) // new blank buffer val newArrayBuffer = ArrayBuffer.allocate(4096) ``` -------------------------------- ### Multiple Native Implementations of a Hybrid Object (Swift) Source: https://nitro.margelo.com/docs/types/hybrid-objects Demonstrates how a single Hybrid Object interface can have multiple distinct native implementations. This allows for flexibility in how the object is represented and managed on the native side. ```swift class HybridUIImage: HybridImageSpec { // ... var uiImage: UIImage } class HybridCGImage: HybridImageSpec { // ... var cgImage: CGImage } class HybridBufferImage: HybridImageSpec { // ... var gpuBuffer: CMSampleBuffer } ``` -------------------------------- ### Initialize Native Module in Android Package Source: https://nitro.margelo.com/docs/concepts/nitrogen Call `initializeNative()` from your library's entry point (`*Package.kt`) to load and initialize the C++ part of your library. ```kotlin public class NitroMathPackage: BaseReactPackage() { // ... companion object { init { NitroMathOnLoad.initializeNative(); } } } ``` -------------------------------- ### Swift Class for Fetch with AnyMap Source: https://nitro.margelo.com/docs/types/untyped-maps Implements a Swift class for Fetch operations, specifying a get method that returns an AnyMap. ```swift class HybridFetch: HybridFetchSpec { func get(url: String) -> AnyMap } ``` -------------------------------- ### Turbo Module Image Cropping (Objective-C) Source: https://nitro.margelo.com/docs/resources/comparison Illustrates a workaround for passing image data in Turbo Modules by saving to a temporary file using Objective-C. ```objc @implementation ImageEditor - (NSString*)crop:(NSString*)imageUri size:(CGRect)size { UIImage* image = [UIImage imageWithContentsOfFile:imageUri]; CGImageRef cropped = CGImageCreateWithImageInRect([image CGImage], size); UIImage* croppedImage = [UIImage imageWithCGImage:cropped]; CGImageRelease(cropped); NSString* fileName = [NSString stringWithFormat:@"%@.png", [[NSUUID UUID] UUIDString]]; NSString* filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; NSData* pngData = UIImagePNGRepresentation(croppedImage); [pngData writeToFile:tempPath atomically:YES]; return tempPath; } @end ``` -------------------------------- ### Implement Orientation Listener in C++ Source: https://nitro.margelo.com/docs/types/callbacks This C++ code illustrates how to register a callback for orientation changes using std::function and how to notify all active listeners when the orientation updates. ```cpp void listenToOrientation(std::function onChanged) { this->listeners.push_back(onChanged); } void onRotate() { for (const auto& listener: this->listeners) { listener(newOrientation); } } ``` -------------------------------- ### TypeScript Interface for Fetch with AnyMap Source: https://nitro.margelo.com/docs/types/untyped-maps Defines a TypeScript interface for a Fetch object that includes a get method returning an AnyMap. ```typescript interface Fetch extends HybridObject<{ ... }> { get(url: string): AnyMap } ``` -------------------------------- ### Implement Raw JSI Method Logic Source: https://nitro.margelo.com/docs/types/raw-jsi-value Implement the logic for your raw JSI method. Access arguments using the `args` array and perform necessary conversions. Return a `jsi::Value`. ```cpp jsi::Value HybridMath::myRawMethod(jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* args, size_t count) { double a = args[0].asNumber(); double b = args[1].asNumber(); return jsi::Value(a + b); } ``` -------------------------------- ### Register Raw JSI Method Source: https://nitro.margelo.com/docs/types/raw-jsi-value In `loadHybridMethods()`, call the base's method and then register your raw JSI method using `registerRawHybridMethod`. Specify the expected argument count and a pointer to your implementation. ```cpp void HybridMath::loadHybridMethods() { // 1. Load base methods HybridMathSpec::loadHybridMethods(); // 2. Register own methods registerHybrids(this, [](Prototype& prototype) { prototype.registerRawHybridMethod("myRawMethod", /* args count */ 2, &HybridMath::myRawMethod); }); } ``` -------------------------------- ### Implement RecyclableView in Swift Source: https://nitro.margelo.com/docs/guides/view-components Shows how to make a Swift view recyclable by implementing the `RecyclableView` protocol and the `prepareForRecycle` method. This is used to reset the view's state when it's reused. ```swift class HybridMyView: HybridMyViewSpec, RecyclableView { // ... func prepareForRecycle() {} } ``` -------------------------------- ### Get Hybrid Object Constructor in JavaScript Source: https://nitro.margelo.com/docs/concepts/hybrid-objects Shows how to obtain the constructor for a Hybrid Object using `getHybridObjectConstructor` to enable `new` and `instanceof`. ```typescript const HybridMath = getHybridObjectConstructor("Math") const math = new HybridMath() const isMath = math instanceof HybridMath ``` -------------------------------- ### Variant with Literal Values (Discouraged) Source: https://nitro.margelo.com/docs/types/variants This example shows a variant with literal values, which is discouraged. For literal variants, use an enum (union) instead. ```typescript export interface Person extends HybridObject<{ … }> { // diff-remove getGender(): 'male' | 'female' } ``` -------------------------------- ### Register Raw JSI Method Source: https://nitro.margelo.com/docs/concepts/hybrid-objects Use `registerRawHybridMethod` to create a raw JSI method for direct interaction with `jsi::Runtime` and `jsi::Value`. This is useful when Nitro's typing system is insufficient. ```cpp class HybridMath: HybridMathSpec { public: jsi::Value sayHello(jsi::Runtime& runtime, const jsi::Value& thisValue, const jsi::Value* args, size_t count); void loadHybridMethods() override { // register base protoype HybridMathSpec::loadHybridMethods(); // register all methods we override here registerHybrids(this, [](Prototype& prototype) { prototype.registerRawHybridMethod("sayHello", 0, &HybridMath::sayHello); }); } } ``` -------------------------------- ### Calling a Component Method with hybridRef Source: https://nitro.margelo.com/docs/guides/view-components Demonstrates how to use `hybridRef` to obtain a reference to a component's HybridObject and call its methods, such as `takePhoto()`. ```jsx function App() { return ( ) } ``` -------------------------------- ### Reinstall Pods for iOS Source: https://nitro.margelo.com/docs/guides/running-example-app Installs or updates CocoaPods dependencies for the iOS project. This command should be run if any iOS files have changed, especially after regenerating specs. ```shell bun example pods ``` -------------------------------- ### Turbo Modules Architecture Source: https://nitro.margelo.com/docs/resources/comparison Illustrates the communication path for Turbo Modules, which involves an extra layer through Objective-C before reaching Swift. ```mermaid graph LR; JS--> C++ --> Objective-C --> Swift; ``` -------------------------------- ### Implement HybridMathSpec Implementation in C++ Source: https://nitro.margelo.com/docs/getting-started/how-to-build-a-nitro-module Provide the implementation for the 'add' method in a C++ source file for the HybridMath class. ```cpp #include "HybridMath.hpp" namespace margelo::nitro::math { double HybridMath::add(double a, double b) { return a + b; } } ``` -------------------------------- ### Implementing Async Method in Swift Source: https://nitro.margelo.com/docs/guides/sync-vs-async Provides a Swift implementation for an asynchronous native method. The initial part runs synchronously, and the heavy computation is offloaded to a background thread using `Promise.async`. ```swift func mineOneBitcoin() throws -> Promise { // 1. synchronous in here, JS Thread is still blocked // useful e.g. for argument checking before starting async Thread return Promise.async { // 2. asynchronous in here, JS Thread is now free return computeBitcoin() } } ``` -------------------------------- ### Implement Hybrid Object in Swift Source: https://nitro.margelo.com/docs/getting-started/what-is-nitro Implement a Hybrid Object in Swift, adhering to the interface defined by Nitrogen. This example shows the 'Math' Hybrid Object. ```swift class HybridMath : HybridMathSpec { var pi: Double { return Double.pi } func add(a: Double, b: Double) -> Double { return a + b } } ``` -------------------------------- ### Implement Hybrid Objects in Swift Source: https://nitro.margelo.com/docs/types/hybrid-objects Implement native classes in Swift that conform to the HybridObject interfaces defined in TypeScript. This example shows implementations for HybridImage and HybridCamera. ```swift class HybridImage: HybridImageSpec { let uiImage: UIImage var width: Double { uiImage.size.width } var height: Double { uiImage.size.height } } class HybridCamera: HybridCameraSpec { func takePhoto() -> HybridImageSpec { return HybridImage(uiImage: …) } } ``` -------------------------------- ### Basic nitro.json Configuration Source: https://nitro.margelo.com/docs/getting-started/configuration-nitro-json This is the default nitro.json configuration file. It sets up the schema, C++ namespace, iOS module name, Android namespace and C++ library name, autolinking, ignored paths, and a git attributes generated flag. ```json { "$schema": "https://nitro.margelo.com/nitro.schema.json", "cxxNamespace": ["$$cxxNamespace$$"], "ios": { "iosModuleName": "$$iosModuleName$$" }, "android": { "androidNamespace": ["$$androidNamespace$$"], "androidCxxLibName": "$$androidCxxLibName$$" }, "autolinking": {}, "ignorePaths": ["**/node_modules"], "gitAttributesGeneratedFlag": true } ``` -------------------------------- ### Creating and Using an Owning ArrayBuffer Source: https://nitro.margelo.com/docs/types/array-buffers Demonstrates allocating an owning ArrayBuffer, accessing its data, and safely retaining it across asynchronous operations. ```swift func doSomething() -> ArrayBuffer { // highlight-next-line let buffer = ArrayBuffer.allocate(1024 * 10) print(buffer.isOwner) // <-- ✅ true let data = buffer.data // <-- ✅ safe to do because we own it! self.buffer = buffer // <-- ✅ safe to use it later! DispatchQueue.global().async { let data = buffer.data // <-- ✅ also safe because we own it! } return buffer } ``` -------------------------------- ### Get Image Creation Date in TypeScript Source: https://nitro.margelo.com/docs/types/dates Defines an `Image` interface with a `getCreationDate` method that returns a `Date` object. Use this when working with image metadata in TypeScript. ```typescript interface Image extends HybridObject<{ ... }> { getCreationDate(): Date } ``` -------------------------------- ### Run Nitrogen CLI Source: https://nitro.margelo.com/docs/concepts/nitrogen Execute the Nitrogen CLI to generate native code from your TypeScript specs. This command should be run in your project's root directory. ```bash npx nitrogen ``` ```bash yarn nitrogen ``` ```bash pnpm nitrogen ``` ```bash bun nitrogen ``` -------------------------------- ### Get Image Creation Date in Kotlin Source: https://nitro.margelo.com/docs/types/dates Defines a `HybridImage` class in Kotlin with a `getCreationDate` method returning an `Instant`. This is used for Kotlin implementations of hybrid image objects. ```kotlin class HybridImage: HybridImageSpec() { fun getCreationDate(): Instant } ``` -------------------------------- ### Implement HybridCameraView in Swift Source: https://nitro.margelo.com/docs/guides/view-components Provides a basic implementation of `HybridCameraView` in Swift, extending `HybridCameraViewSpec`. Includes empty `beforeUpdate` and `afterUpdate` methods for potential prop batching. ```swift class HybridCameraView: HybridCameraViewSpec { // View var view: UIView = UIView() func beforeUpdate() { } func afterUpdate() { } } ``` -------------------------------- ### Get Image Creation Date in Swift Source: https://nitro.margelo.com/docs/types/dates Declares a `HybridImage` class with a `getCreationDate` method returning a `Date` object. This is for Swift implementations interacting with hybrid image objects. ```swift class HybridImage: HybridImageSpec { func getCreationDate() -> Date } ``` -------------------------------- ### Variant with Custom Alias Name (Recommended) Source: https://nitro.margelo.com/docs/types/variants Demonstrates using a type alias for a variant to improve readability of generated code. The 'Bad' example shows the default generated type name. ```typescript type MathOutput = string | number interface Math extends HybridObject<{ … }> { calculate(): MathOutput } ``` -------------------------------- ### Nitro Module Property Handling (Swift) Source: https://nitro.margelo.com/docs/resources/comparison Demonstrates how Nitro Modules use direct property declarations in Swift for managing state. ```swift class HybridMath : HybridMathSpec { var someValue: Double } ``` -------------------------------- ### Get Image Creation Date in C++ Source: https://nitro.margelo.com/docs/types/dates Declares a `HybridImage` class in C++ with a `getCreationDate` method returning a `std::chrono::system_clock::time_point`. This is for C++ implementations of hybrid image objects. ```cpp class HybridImage: public HybridImageSpec { std::chrono::system_clock::time_point getCreationDate(); } ``` -------------------------------- ### Kotlin: HybridImage Class with ArrayBuffer Source: https://nitro.margelo.com/docs/types/array-buffers Demonstrates a Kotlin class `HybridImage` with a `getData` function that returns an ArrayBuffer. Import ArrayBuffer from `com.margelo.nitro.core`. ```kotlin class HybridImage: HybridImageSpec() { fun getData(): ArrayBuffer } ``` -------------------------------- ### Turbo Module Property Handling (Objective-C) Source: https://nitro.margelo.com/docs/resources/comparison Shows the conventional getter/setter method approach for properties in Turbo Modules using Objective-C. ```objc @implementation RTNMath { NSNumber* _someValue; } RCT_EXPORT_MODULE() - (NSNumber*)getSomeValue { return _someValue; } - (void)setSomeValue:(NSNumber*)someValue { _someValue = someValue; } @end ``` -------------------------------- ### Define Hybrid Object Interfaces (TypeScript) Source: https://nitro.margelo.com/docs/types/hybrid-objects Define interfaces for native objects that extend HybridObject, specifying native language targets like 'swift'. This example shows interfaces for Image and Camera. ```typescript interface Image extends HybridObject<{ ios: 'swift' }> { readonly width: number readonly height: number } interface Camera extends HybridObject<{ ios: 'swift' }> { takePhoto(): Image } ``` -------------------------------- ### Get Renderable Hybrid View Component (TypeScript) Source: https://nitro.margelo.com/docs/concepts/hybrid-views Obtains a renderable React Native component from a Hybrid View definition. Use this function to bridge your native Hybrid View to the React Native environment. ```typescript export const Camera = getHostComponent( 'Camera', () => CameraViewConfig ) ``` -------------------------------- ### Accessing Base Methods of Hybrid Object Source: https://nitro.margelo.com/docs/concepts/hybrid-objects Demonstrates how to create a Hybrid Object and access its base methods like name, toString(), and equals(). ```typescript const math = NitroModules.createHybridObject("Math") const anotherMath = math console.log(math.name) // "Math" console.log(math.toString()) // "[HybridObject Math]" console.log(math.equals(anotherMath)) // true ``` -------------------------------- ### Implement HybridMath C++ Class (Manual) Source: https://nitro.margelo.com/docs/types/custom-types Manually implement the `HybridMath` class, including the necessary header for `JSIConverter`. This version registers hybrid methods explicitly. ```cpp #pragma once #include "JSIConverter+Float.hpp" // ... class HybridMath : public HybridObject { public: float add(float a, float b) { return a + b; } void loadHybridMethods() { HybridObject::loadHybridMethods(); registerHybrids(this, [](Prototype& prototype) { prototype.registerHybridMethod("add", &HybridMath::add); }); } } ``` -------------------------------- ### Implement HybridCameraView in Kotlin Source: https://nitro.margelo.com/docs/guides/view-components Provides a basic implementation of `HybridCameraView` in Kotlin, extending `HybridCameraViewSpec`. Includes empty `beforeUpdate` and `afterUpdate` methods for potential prop batching. ```kotlin class HybridCameraView(context: ThemedReactContext): HybridCameraViewSpec() { // View override val view: View = View(context) override fun beforeUpdate() { } override fun afterUpdate() { } } ``` -------------------------------- ### Configure Android Namespace Source: https://nitro.margelo.com/docs/getting-started/configuration-nitro-json Sets the Java/Kotlin package namespace for generated files. Keep this in sync with your build.gradle namespace. ```json { "android": { "androidNamespace": ["math", "extra"] } } ``` -------------------------------- ### Initialize Hybrid Object from JavaScript Source: https://nitro.margelo.com/docs/concepts/nitrogen Initialize a hybrid object from JavaScript using `createHybridObject` and then use its methods. ```typescript export const MathModule = NitroModules.createHybridObject("Math") const result = MathModule.add(5, 7) ``` -------------------------------- ### Implement RecyclableView in Kotlin Source: https://nitro.margelo.com/docs/guides/view-components Shows how to make a Kotlin view recyclable by implementing the `RecyclableView` interface and the `prepareForRecycle` method. This is used to reset the view's state when it's reused. ```kotlin class HybridMyView: HybridMyViewSpec(), RecyclableView { // ... override fun prepareForRecycle() {} } ``` -------------------------------- ### Implement Nitro Dispatcher for Custom Runtime Source: https://nitro.margelo.com/docs/guides/worklets C++ code for creating a custom Dispatcher to handle asynchronous operations for a JSI runtime. Implement runSync and runAsync to execute functions on the correct thread. ```cpp #include using namespace margelo::nitro; class MyRuntimeDispatcher: public Dispatcher { public: void runSync(std::function&& function) override; void runAsync(std::function&& function) override; }; ``` -------------------------------- ### iOS Podspec Configuration Source: https://nitro.margelo.com/docs/concepts/nitrogen Integrate generated Nitrogen files into your iOS project by adding `add_nitrogen_files(...)` to your `.podspec` file. Ensure the `NitroExample+autolinking.rb` file is loaded. ```ruby Pod::Spec.new do |s| # ... load 'nitrogen/generated/ios/NitroExample+autolinking.rb' add_nitrogen_files(s) end ``` -------------------------------- ### Manually Implement Hybrid Object Source in C++ Source: https://nitro.margelo.com/docs/concepts/hybrid-objects Provide the C++ implementation for a Hybrid Object's methods and register them using `registerHybrids`. Ensure `loadHybridMethods` is overridden to include custom method registrations. ```cpp double HybridMath::add(double a, double b) { return a + b; } void HybridMath::loadHybridMethods() { // register base methods (toString, ...) HybridObject::loadHybridMethods(); // register custom methods (add) registerHybrids(this, [](Prototype& proto) { proto.registerHybridMethod( "add", &HybridMath::add ); }); } ``` -------------------------------- ### Implement Orientation Listener in Swift Source: https://nitro.margelo.com/docs/types/callbacks This Swift code demonstrates how to add a listener for orientation changes and how to notify all registered listeners when a rotation occurs. ```swift func listenToOrientation(onChanged: (Orientation) -> Void) { self.listeners.append(onChanged) } func onRotate() { for listener in self.listeners { listener(newOrientation) } } ``` -------------------------------- ### Defining an Async Method Signature (TypeScript) Source: https://nitro.margelo.com/docs/guides/sync-vs-async Shows the TypeScript interface definition for an asynchronous native method `mineOneBitcoin` that returns a Promise of a number. ```typescript interface Miner extends HybridObject<{ ... }> { mineOneBitcoin(): Promise } ``` -------------------------------- ### Registering Hybrid Objects for C++ Source: https://nitro.margelo.com/docs/concepts/nitrogen Configure your `nitro.json` to register a hybrid object for all platforms using C++. ```json { ... "autolinking": { "Math": { "all": { "language": "c++", "implementationClassName": "HybridMath" } } } } ``` -------------------------------- ### Catching Native Errors in JavaScript Source: https://nitro.margelo.com/docs/guides/errors Demonstrates how to use `try/catch` in JavaScript to handle errors propagated from native code, such as a negative value error from `Math.add`. ```ts const math = // ... try { await math.add(-5, -1) } catch (error) { console.log(error) } ``` -------------------------------- ### Turbo Module Event Emission (Objective-C) Source: https://nitro.margelo.com/docs/resources/comparison Demonstrates emitting events from a Turbo Module using Objective-C, requiring native definition of event names. ```objc @implementation RTNMath RCT_EXPORT_MODULE(); - (NSArray *)supportedEvents { return @[@"onSomethingChanged"]; } - (void)onSomethingChanged { NSString* message = @"something changed!"; [self sendEventWithName:@"onSomethingChanged" body:@{@"msg": message}]; } @end ``` -------------------------------- ### Configure Android CMakeLists.txt for Nitro Autolinking Source: https://nitro.margelo.com/docs/getting-started/how-to-build-a-nitro-module Include the generated '+autolinking.cmake' file in your 'CMakeLists.txt' to set up C++/JNI autolinking. ```cmake add_library($$androidCxxLibName$$ SHARED ... ) // diff-add include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/$$androidCxxLibName$$+autolinking.cmake) ``` -------------------------------- ### Implement HybridMathSpec in Swift Source: https://nitro.margelo.com/docs/getting-started/how-to-build-a-nitro-module Implement the generated HybridMathSpec protocol in a Swift file. This provides the native logic for the 'add' method. ```swift class HybridMath : HybridMathSpec { func add(a: Double, b: Double) throws -> Double { return a + b } } ``` -------------------------------- ### Implement Orientation Listener in Kotlin Source: https://nitro.margelo.com/docs/types/callbacks This Kotlin code shows how to add a listener for orientation changes and how to iterate through and call all registered listeners when a rotation event happens. ```kotlin fun listenToOrientation(onChanged: (Orientation) -> Unit) { this.listeners.add(onChanged) } fun onRotate() { for (listener in this.listeners) { listener(newOrientation) } } ``` -------------------------------- ### Implementing Async Method in Kotlin Source: https://nitro.margelo.com/docs/guides/sync-vs-async Demonstrates an asynchronous native method implementation in Kotlin. Similar to Swift, it uses `Promise.async` to perform the computation on a background thread, freeing the JS Thread. ```kotlin override fun mineOneBitcoin(): Promise { // 1. synchronous in here, JS Thread is still blocked // useful e.g. for argument checking before starting async Thread return Promise.async { // 2. asynchronous in here, JS Thread is now free return computeBitcoin() } } ```