This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.rnbridgingtutorial
8 |
9 | import android.content.Context
10 | import com.facebook.react.ReactInstanceManager
11 |
12 | /**
13 | * Class responsible of loading Flipper inside your React Native application. This is the release
14 | * flavor of it so it's empty as we don't want to load Flipper.
15 | */
16 | object ReactNativeFlipper {
17 | @JvmStatic
18 | fun initializeFlipper(context: Context?, reactInstanceManager: ReactInstanceManager) {
19 | // Do nothing as we don't want to initialize Flipper on Release.
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = "33.0.0"
6 | minSdkVersion = 21
7 | compileSdkVersion = 33
8 | targetSdkVersion = 33
9 | kotlinVersion = "1.6.10"
10 |
11 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
12 | ndkVersion = "23.1.7779620"
13 | }
14 | repositories {
15 | google()
16 | mavenCentral()
17 | }
18 | dependencies {
19 | classpath("com.android.tools.build:gradle:7.3.1")
20 | classpath("com.facebook.react:react-native-gradle-plugin")
21 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
22 | // NOTE: Do not place your application dependencies here; they belong
23 | // in the individual module build.gradle files
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'rnbridgingtutorial'
2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
3 | include ':app'
4 | includeBuild('../node_modules/react-native-gradle-plugin')
5 |
--------------------------------------------------------------------------------
/app-info-package-classic/AppInfoPackageClassic.podspec:
--------------------------------------------------------------------------------
1 | require "json"
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4 |
5 | new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
6 |
7 | Pod::Spec.new do |s|
8 | s.name = "AppInfoPackageClassic"
9 | s.version = package["version"]
10 | s.summary = package["description"]
11 | s.description = package["description"]
12 | s.homepage = package["homepage"]
13 | s.license = package["license"]
14 | s.platforms = { :ios => "13.0" }
15 | s.author = package["author"]
16 | s.source = { :git => package["repository"], :tag => "#{s.version}" }
17 |
18 | s.source_files = "ios/**/*.{h,m,mm,swift}"
19 |
20 | if new_arch_enabled
21 | s.pod_target_xcconfig = {
22 | "DEFINES_MODULE" => "YES",
23 | "SWIFT_OBJC_INTERFACE_HEADER_NAME" => "AppInfoPackageClassic-Swift.h",
24 | # This is handy when we want to detect if new arch is enabled in Swift code
25 | # and can be used like:
26 | # #if APP_INFO_PACKAGE_CLASSIC_NEW_ARCH_ENABLED
27 | # // do sth when new arch is enabled
28 | # #else
29 | # // do sth when old arch is enabled
30 | # #endif
31 | "OTHER_SWIFT_FLAGS" => "-DAPP_INFO_PACKAGE_CLASSIC_NEW_ARCH_ENABLED"
32 | }
33 | else
34 | s.pod_target_xcconfig = {
35 | "DEFINES_MODULE" => "YES",
36 | "SWIFT_OBJC_INTERFACE_HEADER_NAME" => "AppInfoPackageClassic-Swift.h"
37 | }
38 | end
39 |
40 | # Install all React Native dependencies (RN >= 0.71 must be used)
41 | #
42 | # check source code for more context
43 | # https://github.com/facebook/react-native/blob/0.71-stable/scripts/react_native_pods.rb#L172#L180
44 | install_modules_dependencies(s)
45 | end
46 |
--------------------------------------------------------------------------------
/app-info-package-classic/android/src/newarch/java/com/appinfopackageclassic/AppInfoModuleClassic.java:
--------------------------------------------------------------------------------
1 | package com.appinfopackageclassic;
2 |
3 | import com.facebook.react.bridge.ReactApplicationContext;
4 | import com.facebook.react.module.annotations.ReactModule;
5 |
6 | /**
7 | * Declare Java class for new arch native module implementation
8 | *
9 | * Each turbo module extends codegenerated spec class
10 | *
11 | * Class should be annotated with @ReactModule decorator
12 | */
13 | @ReactModule(name = AppInfoModuleClassic.NAME)
14 | public class AppInfoModuleClassic extends NativeAppInfoModuleClassicSpec {
15 | public static final String NAME = AppInfoModuleClassicImpl.NAME;
16 |
17 | // Use shared module implementation and forward react application context
18 | private final AppInfoModuleClassicImpl moduleImpl;
19 |
20 | public AppInfoModuleClassic(ReactApplicationContext reactContext) {
21 | super(reactContext);
22 | this.moduleImpl = new AppInfoModuleClassicImpl(reactContext);
23 | }
24 |
25 | // Return the name of the module - it should match the name provided in JS specification
26 | @Override
27 | public String getName() {
28 | return NAME;
29 | }
30 |
31 | // Exported methods are overriden - based on the spec class
32 | @Override
33 | public String getAppBuildNumber() {
34 | return moduleImpl.getAppBuildNumber();
35 | }
36 |
37 | @Override
38 | public String getAppBundleId() {
39 | return moduleImpl.getAppBundleId();
40 | }
41 |
42 | @Override
43 | public String getAppVersion() {
44 | return moduleImpl.getAppVersion();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app-info-package-classic/ios/AppInfoModuleClassic.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | /**
4 | * Declare the ObjC interface for that native module class.
5 | *
6 | * It must extend NSObject (like every class in ObjC) and
7 | * implement RCTBridgeModule (like each RN native module).
8 | *
9 | * If the module emits events, it must extend RCTEventEmitter class.
10 | */
11 | @interface AppInfoModuleClassic : NSObject
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/app-info-package-classic/ios/AppInfoModuleClassicImpl.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface AppInfoModuleClassicImpl : NSObject
4 |
5 | - (NSString *)getAppBuildNumber;
6 | - (NSString *)getAppBundleId;
7 | - (NSString *)getAppVersion;
8 |
9 | @end
10 |
--------------------------------------------------------------------------------
/app-info-package-classic/ios/AppInfoModuleClassicImpl.mm:
--------------------------------------------------------------------------------
1 | #import "AppInfoModuleClassicImpl.h"
2 |
3 | /**
4 | * Native module's shared implementation
5 | */
6 | @implementation AppInfoModuleClassicImpl
7 |
8 | - (NSString *)getAppBuildNumber
9 | {
10 | return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
11 | }
12 |
13 | - (NSString *)getAppBundleId
14 | {
15 | return [[NSBundle mainBundle] bundleIdentifier];
16 | }
17 |
18 | - (NSString *)getAppVersion
19 | {
20 | return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/app-info-package-classic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "app-info-package-classic",
4 | "version": "0.0.1",
5 | "description": "App Info package (classic)",
6 | "react-native": "src",
7 | "source": "src",
8 | "main": "src",
9 | "module": "src",
10 | "files": [
11 | "src",
12 | "android",
13 | "ios",
14 | "AppInfoPackageClassic.podspec",
15 | "!android/build",
16 | "!ios/build",
17 | "!**/__tests__",
18 | "!**/__mocks__"
19 | ],
20 | "repository": "repository url",
21 | "author": "author",
22 | "license": "MIT",
23 | "homepage": "homepage",
24 | "peerDependencies": {
25 | "react": "*",
26 | "react-native": "*"
27 | },
28 | "codegenConfig": {
29 | "name": "AppInfoPackageClassic",
30 | "type": "all",
31 | "jsSrcsDir": "src",
32 | "android": {
33 | "javaPackageName": "com.appinfopackageclassic"
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app-info-package-classic/src/NativeAppInfoModuleClassic.ts:
--------------------------------------------------------------------------------
1 | import type { TurboModule } from 'react-native';
2 | import { TurboModuleRegistry } from 'react-native';
3 |
4 | export interface Spec extends TurboModule {
5 | getAppBuildNumber(): string
6 | getAppBundleId(): string
7 | getAppVersion(): string
8 | }
9 |
10 | export default TurboModuleRegistry.getEnforcing('AppInfoModuleClassic');
--------------------------------------------------------------------------------
/app-info-package-classic/src/index.ts:
--------------------------------------------------------------------------------
1 | export { default as AppInfoModuleClassic } from './NativeAppInfoModuleClassic';
2 |
--------------------------------------------------------------------------------
/app-info-package/android/src/newarch/java/com/appinfopackage/AppInfoModule.kt:
--------------------------------------------------------------------------------
1 | package com.appinfopackage
2 |
3 | import com.facebook.react.bridge.ReactApplicationContext
4 | import com.facebook.react.module.annotations.ReactModule
5 |
6 | /**
7 | * Declare Kotlin class for new arch native module implementation
8 | *
9 | * Each turbo module extends codegenerated spec class
10 | *
11 | * Class should be annotated with @ReactModule decorator
12 | */
13 | @ReactModule(name = AppInfoModule.NAME)
14 | class AppInfoModule(
15 | // Each native module class consumes react application context
16 | reactContext: ReactApplicationContext
17 | ) : NativeAppInfoModuleSpec(reactContext) {
18 | // Use shared module implementation and forward react application context
19 | private val moduleImpl = AppInfoModuleImpl(reactContext)
20 |
21 | // Return the name of the module - it should match the name provided in JS specification
22 | override fun getName() = NAME
23 |
24 | // Exported methods are overriden - based on the spec class
25 | override fun getAppBuildNumber() = moduleImpl.getAppBuildNumber()
26 |
27 | override fun getAppBundleId() = moduleImpl.getAppBundleId()
28 |
29 | override fun getAppVersion() = moduleImpl.getAppVersion()
30 |
31 | companion object {
32 | const val NAME = AppInfoModuleImpl.NAME
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app-info-package/android/src/oldarch/java/com/appinfopackage/AppInfoModule.kt:
--------------------------------------------------------------------------------
1 | package com.appinfopackage
2 |
3 | import com.facebook.react.bridge.ReactApplicationContext
4 | import com.facebook.react.bridge.ReactContextBaseJavaModule
5 | import com.facebook.react.bridge.ReactMethod
6 | import com.facebook.react.module.annotations.ReactModule
7 |
8 | /**
9 | * Declare Kotlin class for old arch native module implementation
10 | *
11 | * Each native module extends ReactContextBaseJavaModule class
12 | *
13 | * Class should be annotated with @ReactModule decorator
14 | */
15 | @ReactModule(name = AppInfoModule.NAME)
16 | class AppInfoModule(
17 | // Each native module class consumes react application context
18 | reactContext: ReactApplicationContext
19 | ) : ReactContextBaseJavaModule(reactContext) {
20 | // Use shared module implementation and forward react application context
21 | private val moduleImpl = AppInfoModuleImpl(reactContext)
22 |
23 | // Return the name of the module - it should match the name provided in JS specification
24 | override fun getName() = NAME
25 |
26 | // Exported methods must be annotated with @ReactMethod decorator
27 | @ReactMethod(isBlockingSynchronousMethod = true)
28 | fun getAppBuildNumber() = moduleImpl.getAppBuildNumber()
29 |
30 | @ReactMethod(isBlockingSynchronousMethod = true)
31 | fun getAppBundleId() = moduleImpl.getAppBundleId()
32 |
33 | @ReactMethod(isBlockingSynchronousMethod = true)
34 | fun getAppVersion() = moduleImpl.getAppVersion()
35 |
36 | companion object {
37 | const val NAME = AppInfoModuleImpl.NAME
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app-info-package/ios/AppInfoModule.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | /**
4 | * When using Swift classes in ObjC header, the class must have its
5 | * "forward declaration"
6 | *
7 | * @see https://developer.apple.com/documentation/swift/importing-swift-into-objective-c#Include-Swift-Classes-in-Objective-C-Headers-Using-Forward-Declarations
8 | */
9 | @class AppInfoModuleImpl;
10 |
11 | /**
12 | * Declare the ObjC interface for that native module class.
13 | *
14 | * It must extend NSObject (like every class in ObjC) and
15 | * implement RCTBridgeModule (like each RN native module).
16 | */
17 | @interface AppInfoModule : NSObject
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/app-info-package/ios/AppInfoModuleImpl.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | @objc(AppInfoModuleImpl)
4 | public class AppInfoModuleImpl : NSObject {
5 | @objc public func getAppBuildNumber() -> String {
6 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String
7 | }
8 |
9 | @objc public func getAppBundleId() -> String {
10 | return Bundle.main.bundleIdentifier!
11 | }
12 |
13 | @objc public func getAppVersion() -> String {
14 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app-info-package/ios/AppInfoPackage-Bridging-Header.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mateusz1913/rnbridgingtutorial/5ffbcb451066cd43807337a3c1a42c26402a814f/app-info-package/ios/AppInfoPackage-Bridging-Header.h
--------------------------------------------------------------------------------
/app-info-package/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "app-info-package",
4 | "version": "0.0.1",
5 | "description": "App Info package",
6 | "react-native": "src",
7 | "source": "src",
8 | "main": "src",
9 | "module": "src",
10 | "files": [
11 | "src",
12 | "android",
13 | "ios",
14 | "AppInfoPackage.podspec",
15 | "!android/build",
16 | "!ios/build",
17 | "!**/__tests__",
18 | "!**/__fixtures__",
19 | "!**/__mocks__"
20 | ],
21 | "repository": "",
22 | "author": "",
23 | "license": "MIT",
24 | "homepage": "",
25 | "peerDependencies": {
26 | "react": "*",
27 | "react-native": "*"
28 | },
29 | "codegenConfig": {
30 | "name": "AppInfoPackage",
31 | "type": "all",
32 | "jsSrcsDir": "src",
33 | "android": {
34 | "javaPackageName": "com.appinfopackage"
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app-info-package/src/NativeAppInfoModule.ts:
--------------------------------------------------------------------------------
1 | import type { TurboModule } from 'react-native';
2 | import { TurboModuleRegistry } from 'react-native';
3 |
4 | export interface Spec extends TurboModule {
5 | getAppBuildNumber(): string
6 | getAppBundleId(): string
7 | getAppVersion(): string
8 | }
9 |
10 | export default TurboModuleRegistry.getEnforcing('AppInfoModule');
11 |
--------------------------------------------------------------------------------
/app-info-package/src/index.ts:
--------------------------------------------------------------------------------
1 | export { default as AppInfoModule } from './NativeAppInfoModule';
2 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rnbridgingtutorial",
3 | "displayName": "rnbridgingtutorial"
4 | }
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [ 'module:metro-react-native-babel-preset' ],
3 | plugins: [
4 | [
5 | 'module-resolver',
6 | {
7 | root: [ './' ],
8 | extensions: [
9 | '.ios.js',
10 | '.ios.ts',
11 | '.ios.tsx',
12 | '.android.js',
13 | '.android.ts',
14 | '.android.tsx',
15 | '.js',
16 | '.ts',
17 | '.tsx',
18 | '.json',
19 | ],
20 | alias: {
21 | 'app-info-package': './app-info-package',
22 | 'app-info-package-classic': './app-info-package-classic',
23 | 'conic-gradient-package': './conic-gradient-package',
24 | 'conic-gradient-package-classic': './conic-gradient-package-classic',
25 | 'native-list-package': './native-list-package',
26 | 'native-list-package-classic': './native-list-package-classic',
27 | 'range-slider-package': './range-slider-package',
28 | 'range-slider-package-classic': './range-slider-package-classic',
29 | 'save-file-picker-package': './save-file-picker-package',
30 | 'save-file-picker-package-classic': './save-file-picker-package-classic',
31 | 'screen-orientation-package': './screen-orientation-package',
32 | 'screen-orientation-package-classic': './screen-orientation-package-classic',
33 | },
34 | },
35 | ],
36 | [
37 | '@babel/plugin-transform-react-jsx',
38 | {
39 | runtime: 'automatic',
40 | },
41 | ],
42 | ],
43 | };
44 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | /node_modules
3 |
4 | # Production
5 | /build
6 |
7 | # Generated files
8 | .docusaurus
9 | .cache-loader
10 |
11 | # Misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/README.md:
--------------------------------------------------------------------------------
1 | # Website
2 |
3 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
4 |
5 | ### Installation
6 |
7 | ```
8 | $ yarn
9 | ```
10 |
11 | ### Local Development
12 |
13 | ```
14 | $ yarn start
15 | ```
16 |
17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
18 |
19 | ### Build
20 |
21 | ```
22 | $ yarn build
23 | ```
24 |
25 | This command generates static content into the `build` directory and can be served using any static contents hosting service.
26 |
27 | ### Deployment
28 |
29 | Using SSH:
30 |
31 | ```
32 | $ USE_SSH=true yarn deploy
33 | ```
34 |
35 | Not using SSH:
36 |
37 | ```
38 | $ GIT_USER= yarn deploy
39 | ```
40 |
41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
42 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [ require.resolve('@docusaurus/core/lib/babel/preset') ],
3 | };
4 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/_codegen-for-old-arch-info.mdx:
--------------------------------------------------------------------------------
1 | You may notice, that JS specs contain codegen-related methods, classes, types, etc. to make things more future-proof.
2 |
3 | That's because:
4 |
5 | - those elements are available since RN older versions (even from v0.65)
6 | - those elements are falling back to "old architecture" implementation (e.g. codegenNativeComponent)
7 | - it introduces type safety for exposed native parts on JS side
8 | - it's much easier to keep single specification on JS side - when old arch will be dropped, there'll be no need to change anything on JS side
9 |
10 | So to make it easier, let's use them, to get you more familiar with it 👍
11 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "position": 3,
3 | "label": "Guides"
4 | }
5 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/_codegen-spec.mdx:
--------------------------------------------------------------------------------
1 | You can run codegen to generate native classes and interfaces, and also check if specification is defined in correct way:
2 |
3 | - on iOS: run `yarn codegen:ios`, the code-generated classes should be available under your app's `/ios/build/generated/ios` directory
4 |
5 | - on Android: `yarn codegen:android`, the code-generated classes should be available under the package's `//android/build/generated/source/codegen` directory
6 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/_complete-file.mdx:
--------------------------------------------------------------------------------
1 | import CodeBlock from '@theme/CodeBlock';
2 |
3 |
4 | Complete {props.filename} file
5 |
{props.children}
6 |
7 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/_exporting-objc-info.mdx:
--------------------------------------------------------------------------------
1 | :::info
2 |
3 | To make Swift elements accessible to Objective-C world, we have to do 4 things:
4 |
5 | - make class extending `NSObject`
6 | - mark class and its methods (at least those methods that are meant to be exposed) as public
7 | - mark class with `@objc(exported-objc-name)` decorator
8 | - mark exposed methods with `@objc` decorator
9 |
10 | :::
11 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/_old-arch-android-module-file.mdx:
--------------------------------------------------------------------------------
1 | import CodeBlock from '@theme/CodeBlock';
2 |
3 |
4 | Old architecture module
5 |
6 | The implementation of old architecture module won't be visible in Android Studio when you have new architecture enabled.
7 | To handle that, you can open {props.filename} at other text editor and paste following content:
6 | The implementation of old architecture view manager won't be visible in Android Studio when you have new architecture enabled.
7 | To handle that, you can open {props.filename} at other text editor and paste following content:
8 | {props.children}
9 |
10 |
11 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/_android-java-impl.mdx:
--------------------------------------------------------------------------------
1 | import AndroidTurboPackage from '../_android-turbo-package.mdx';
2 |
3 | import AndroidJavaModule from './_android-java-module.mdx';
4 | import AndroidJavaModuleImpl from './_android-java-moduleimpl.mdx';
5 |
6 |
7 |
8 |
9 |
10 |
16 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/_android-kotlin-impl.mdx:
--------------------------------------------------------------------------------
1 | import AndroidTurboPackage from '../_android-turbo-package.mdx';
2 |
3 | import AndroidKotlinModule from './_android-kotlin-module.mdx';
4 | import AndroidKotlinModuleImpl from './_android-kotlin-moduleimpl.mdx';
5 |
6 |
7 |
8 |
9 |
10 |
16 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "position": 2,
3 | "label": "AppInfo module"
4 | }
5 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/_ios-objc-impl.mdx:
--------------------------------------------------------------------------------
1 | import IosObjCModule from './_ios-objc-module.mdx';
2 | import IosObjCModuleImpl from './_ios-objc-moduleimpl.mdx';
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/_ios-swift-impl.mdx:
--------------------------------------------------------------------------------
1 | import IosSwiftModule from './_ios-swift-module.mdx';
2 | import IosSwiftModuleImpl from './_ios-swift-moduleimpl.mdx';
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/_ios-swift-moduleimpl.mdx:
--------------------------------------------------------------------------------
1 | import ExportingObjCInfo from '../_exporting-objc-info.mdx';
2 |
3 | #### `AppInfoModuleImpl.swift`
4 |
5 | Let's start by creating a small pure Swift class that will directly retrieve all application informations:
6 |
7 | ```swift title="ios/AppInfoModuleImpl.swift"
8 | import Foundation
9 |
10 | @objc(AppInfoModuleImpl)
11 | public class AppInfoModuleImpl : NSObject {
12 | @objc public func getAppBuildNumber() -> String {
13 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String
14 | }
15 |
16 | @objc public func getAppBundleId() -> String {
17 | return Bundle.main.bundleIdentifier!
18 | }
19 |
20 | @objc public func getAppVersion() -> String {
21 | return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
22 | }
23 | }
24 | ```
25 |
26 | Here, we declare `AppInfoModuleImpl` class, which has 3 synchronous methods.
27 |
28 |
29 |
30 | Methods in the class are using `Bundle` class, for the reference, check out Apple's [dedicated docs section](https://developer.apple.com/documentation/foundation/bundle).
31 |
32 | We will use main `Bundle` instance to [retrieve some information about the app](https://developer.apple.com/documentation/foundation/bundle#1652578).
33 |
34 | In case of `getAppBundleId` method, we will use `bundleIdentifier` property, for other methods we use _generic_ `object(forInfoDictionaryKey:)` method, where the argument is a key from `Info.plist`.
35 | For possible `Info.plist` keys, visit ["About Info.plist keys and values"](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html).
36 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/_result.mdx:
--------------------------------------------------------------------------------
1 | import appInfoResult from '/img/appinfo-result.png';
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/android-impl.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_label: Android implementation
3 | sidebar_position: 5
4 | title: Android implementation
5 | ---
6 |
7 | import Tabs from '@theme/Tabs';
8 | import TabItem from '@theme/TabItem';
9 |
10 | import AndroidJavaImpl from './_android-java-impl.mdx'
11 | import AndroidKotlinImpl from './_android-kotlin-impl.mdx'
12 |
13 | Let's use Android Studio to write Android code. Launch Android Studio and open the project under `/android` path.
14 | When the project is opened, find `app-info-package` inside project-tree.
15 |
16 | The `app-info-package` contains 3 packages with the same name `com.appinfopackage`. After expanding them, you'll notice that these contain following things:
17 |
18 | - code-generated Java spec files
19 | - `AppInfoModule` class stub files
20 | - `AppInfoModuleImpl` class stub file
21 | - `AppInfoTurboPackage` class stub file
22 |
23 | Let's start implementing!
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | You can check training repo for Kotlin implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/app-info-package) and Java implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/app-info-package-classic).
39 |
40 | That's Android part, now let's wrap things up and try to [use AppInfo module](./usage) in action!
41 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/intro.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_label: Intro
3 | sidebar_position: 1
4 | title: Intro
5 | ---
6 |
7 | import Result from './_result.mdx';
8 |
9 | In this guide, you'll learn how to create a simple module with 3 synchronous methods.
10 |
11 | ### Difficulty
12 |
13 | Kids' stuff 👶
14 |
15 | ### Task
16 |
17 | As a user, I want to see the package name and version, so that I know if I use test or live version of the app.
18 |
19 | ### What's the plan?
20 |
21 | - create module's boilerplate
22 | - create JS spec
23 | - iOS implementation
24 | - Android implementation
25 | - use the module in action
26 |
27 | ### Result?
28 |
29 |
30 |
31 | Can't wait? Let's set up [module boilerplate](./setup).
32 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/ios-impl.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_label: iOS implementation
3 | sidebar_position: 4
4 | title: iOS implementation
5 | ---
6 |
7 | import Tabs from '@theme/Tabs';
8 | import TabItem from '@theme/TabItem';
9 |
10 | import IosObjCImpl from './_ios-objc-impl.mdx';
11 | import IosSwiftImpl from './_ios-swift-impl.mdx';
12 |
13 | Let's use XCode, to write iOS code. Open XCode, by running this command from the root directory of your app:
14 |
15 | ```sh
16 | xed ios
17 | ```
18 |
19 | When workspace is opened, locate `Pods` project and expand it. Search for `Development Pods` and find `AppInfoPackage` inside. When it's expanded, it will show all files that we created under `app-info-package/ios` directory.
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | You can check training repo for Objective-C & Swift implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/app-info-package) and Objective-C-only implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/app-info-package-classic).
35 |
36 | That's iOS part, now let's go to [Android](./android-impl)!
37 |
38 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/app-info-module/js-spec.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_label: JS specification
3 | sidebar_position: 3
4 | title: JS specification
5 | ---
6 |
7 | import CodegenSpec from '../_codegen-spec.mdx';
8 |
9 | When all boilerplate is ready, let's navigate to `src/NativeAppInfoModule.ts`. To declare module spec, let's paste following content:
10 |
11 | ```tsx title="src/NativeAppInfoModule.ts"
12 | import type { TurboModule } from 'react-native';
13 | import { TurboModuleRegistry } from 'react-native';
14 |
15 | export interface Spec extends TurboModule {
16 | getAppBuildNumber(): string
17 | getAppBundleId(): string
18 | getAppVersion(): string
19 | }
20 |
21 | export default TurboModuleRegistry.getEnforcing('AppInfoModule');
22 | ```
23 |
24 | This does 2 things:
25 | - declares module specification with 3 synchronous methods, each one returning a string value
26 | - declares that module, should be available under `AppInfoModule` name
27 |
28 |
29 |
30 | After that, let's finalize JS part by exporting module from `index.ts`
31 |
32 | ```tsx title="src/index.ts"
33 | export { default as AppInfoModule } from './NativeAppInfoModule';
34 | ```
35 |
36 | JS part finished! Let's jump to [iOS implementation](./ios-impl).
37 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/conic-gradient-view/_android-java-impl.mdx:
--------------------------------------------------------------------------------
1 | import AndroidTurboPackage from '../_android-turbo-package.mdx';
2 |
3 | import AndroidJavaView from './_android-java-view.mdx';
4 | import AndroidJavaViewManager from './_android-java-viewmanager.mdx';
5 |
6 |
7 |
8 |
9 |
10 |
16 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/conic-gradient-view/_android-kotlin-impl.mdx:
--------------------------------------------------------------------------------
1 | import AndroidTurboPackage from '../_android-turbo-package.mdx';
2 |
3 | import AndroidKotlinView from './_android-kotlin-view.mdx'
4 | import AndroidKotlinViewManager from './_android-kotlin-viewmanager.mdx'
5 |
6 |
7 |
8 |
9 |
10 |
16 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/conic-gradient-view/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "position": 3,
3 | "label": "Conic gradient view"
4 | }
5 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/conic-gradient-view/_ios-objc-impl.mdx:
--------------------------------------------------------------------------------
1 | import IosObjCComponentView from './_ios-objc-componentview.mdx'
2 | import IosObjCView from './_ios-objc-view.mdx'
3 | import IosObjCViewManager from './_ios-objc-viewmanager.mdx'
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/conic-gradient-view/_ios-objc-viewmanager.mdx:
--------------------------------------------------------------------------------
1 | #### `ConicGradientViewManager.h`
2 |
3 | Let's navigate to `ios/ConicGradientViewManager.h` - the header file for the `ConicGradientViewManager` view manager class. It will extend `RCTViewManager` class.
4 |
5 | ```objc title="ios/ConicGradientViewManager.h
6 | #import
7 |
8 | /**
9 | * Declare the ObjC interface for that view manager class.
10 | *
11 | * It must extend RCTViewManager
12 | */
13 | @interface ConicGradientViewManager : RCTViewManager
14 |
15 | @end
16 | ```
17 |
18 | #### `ConicGradientViewManager.mm`
19 |
20 | Wrap everything up in `ios/ConicGradientViewManager.mm`
21 |
22 | ```objc title="ios/ConicGradientViewManager.mm"
23 | #import "ConicGradientViewManager.h"
24 |
25 | #if RCT_NEW_ARCH_ENABLED
26 | #else
27 | #import "ConicGradientView.h"
28 | #endif
29 |
30 | @implementation ConicGradientViewManager
31 |
32 | RCT_EXPORT_MODULE(ConicGradientView)
33 |
34 | RCT_EXPORT_VIEW_PROPERTY(colors, NSArray)
35 | RCT_EXPORT_VIEW_PROPERTY(locations, NSArray)
36 | RCT_EXPORT_VIEW_PROPERTY(centerPoint, CGPoint)
37 |
38 | #if RCT_NEW_ARCH_ENABLED
39 | #else
40 | - (UIView *)view
41 | {
42 | ConicGradientView *view = [ConicGradientView new];
43 | return view;
44 | }
45 | #endif
46 |
47 | @end
48 | ```
49 |
50 | In the implementation file for `ConicGradientViewManager` class we use `RCT_EXPORT_MODULE` macro with the `ConicGradientView` name that will be accessed on the JS side.
51 | The props are declared with `RCT_EXPORT_VIEW_PROPERTY` macro (1st arg - name of the prop; 2nd arg - its native type).
52 | Additionally, we are declaring managed view for the old architecture mode - for the new architecture mode, we just need to register the name of our module and the props it accepts.
53 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/conic-gradient-view/_result.mdx:
--------------------------------------------------------------------------------
1 | import conicGradientResult from '/img/conicgradient-result.png';
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/conic-gradient-view/android-impl.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_label: Android implementation
3 | sidebar_position: 5
4 | title: Android implementation
5 | ---
6 |
7 | import Tabs from '@theme/Tabs';
8 | import TabItem from '@theme/TabItem';
9 |
10 | import AndroidJavaImpl from './_android-java-impl.mdx';
11 | import AndroidKotlinImpl from './_android-kotlin-impl.mdx';
12 |
13 | Let's use Android Studio for writing Android code. Launch Android Studio and open the project under `/android` path
14 | When the project is opened, find `conic-gradient-package` inside project-tree
15 |
16 | The `conic-gradient-package` contains 3 packages with the same name `com.conicgradientpackage`. After expanding them, you'll notice that these contain following things:
17 |
18 | - code-generated Java spec files
19 | - `ConicGradientViewManager` view manager class stub files
20 | - `ConicGradientView` class stub file
21 | - `ConicGradientTurboPackage` class stub file
22 |
23 | Let's begin!
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | You can check training repo for Kotlin implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/conic-gradient-package) and Java implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/conic-gradient-package-classic).
39 |
40 | That's Android part, now let's wrap things up and try to [use Conic gradient](./usage) in action!
41 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/conic-gradient-view/intro.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_label: Intro
3 | sidebar_position: 1
4 | title: Intro
5 | ---
6 |
7 | import Result from './_result.mdx'
8 |
9 | In this guide, you'll learn how to extend `` with [conic gradient](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/conic-gradient) background functionality.
10 |
11 | ### Difficulty
12 |
13 | Easier than you thought 🧑🎓
14 |
15 | ### Task
16 |
17 | As a user, I want to see the gradient background for the screen.
18 |
19 | ### What's the plan?
20 |
21 | - create view's boilerplate
22 | - creating JS spec
23 | - iOS implementation
24 | - Android implementation
25 | - using the view in action
26 |
27 | ### Result?
28 |
29 |
30 |
31 | Can't wait? Let's set up [view boilerplate](./setup).
32 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/conic-gradient-view/ios-impl.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_label: iOS implementation
3 | sidebar_position: 4
4 | title: iOS implementation
5 | ---
6 |
7 | import Tabs from '@theme/Tabs';
8 | import TabItem from '@theme/TabItem';
9 |
10 | import IosObjCImpl from './_ios-objc-impl.mdx'
11 |
12 | Let's use XCode, to write iOS code. Open XCode, by running this command from the root directory of your app:
13 |
14 | ```sh
15 | xed ios
16 | ```
17 |
18 | When workspace is opened, locate `Pods` project and expand it. Search for `Development Pods` and find `ConicGradientPackage` inside. When it's expanded, it will show all files that we created under `conic-gradient-package/ios` directory.
19 |
20 | :::info
21 |
22 | Extending the `` is available only in Objective-C
23 |
24 | :::
25 |
26 |
27 |
28 | You can check training repo for Objective-C-only implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/conic-gradient-package).
29 |
30 | That's iOS part, now let's go to [Android](./android-impl)!
31 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/guides-intro.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_label: Introduction
3 | sidebar_position: 1
4 | title: Introduction
5 | ---
6 |
7 | Following guides will showcase how to bring multiple platform features to a React Native application, from querying basic application information, through simple UI elements and interactions with the device, ending with complex layouts.
8 |
9 | Each guide is written in a way, that lets you consume them separately, without knowledge from the previous one, so you can just jump to any that you're interested in.
10 |
11 | However, if you're a total beginner in that topic, it's recommended to go in the order these are listed.
12 |
13 | For more reference on how to "translate" features like methods, events, view props, etc. defined in JS code to the platform-specific code, visit [module's reference](../module-reference/module-intro) and [view's reference](../view-reference/view-intro) sections.
14 |
15 | Available guides:
16 |
17 | - [app info module](./app-info-module/intro) - a simple module with synchronous methods
18 |
19 | - [conic gradient view](./conic-gradient-view/intro) - extended `` with custom gradient background
20 |
21 | - [save file picker module](./save-file-picker-module/intro) - a module that calls platform APIs and returns response via callback or promise method
22 |
23 | - [range slider view](./range-slider-view/intro) - a custom native component that wraps 3rd party native library
24 |
25 | - [screen orientation module](./screen-orientation-module/intro) - a simple module that emits events based on data from platform APIs
26 |
27 | - [AVAILABLE SOON] native list view - Android's Fragment & iOS UIViewController integration
28 |
29 | If you have any idea on additional guides, share it on [Bridging Tutorial's Github](https://github.com/mateusz1913/rnbridgingtutorial/discussions).
30 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_android-fragment-list-layout.mdx:
--------------------------------------------------------------------------------
1 | #### `fragment_list.xml`
2 |
3 | Open `android/src/main/res/layout/fragment_list.xml` file in Android Studio and paste the following code:
4 |
5 | ```xml title="android/src/main/res/layout/fragment_list.xml"
6 |
7 |
10 |
11 |
15 |
16 |
17 | ```
18 |
19 | Here we're wrapping `RecyclerView` (the native list element) inside a `ConstraintLayout` and make it fill parent's size.
20 | As in the card item layout, we declare `android:id` attribute, to reference the `RecyclerView` later inside the code.
21 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_android-java-data-item.mdx:
--------------------------------------------------------------------------------
1 | #### `DataItem.java`
2 |
3 | After defining the layouts, let's jump to code and start by defining Java class `DataItem` which will be used to hold items passed from JS code:
4 |
5 | ```java title="android/src/main/java/com/nativelistpackage/DataItem.java"
6 | package com.nativelistpackage;
7 |
8 | public class DataItem {
9 | public String imageUrl;
10 | public String description;
11 |
12 | public DataItem(String imageUrl, String description) {
13 | this.imageUrl = imageUrl;
14 | this.description = description;
15 | }
16 | }
17 | ```
18 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_android-java-impl.mdx:
--------------------------------------------------------------------------------
1 | import AndroidTurboPackage from '../_android-turbo-package.mdx';
2 |
3 | import AndroidAddLibraryInGradle from './_android-add-library-in-gradle.mdx';
4 | import AndroidCardItemLayout from './_android-card-item-layout.mdx';
5 | import AndroidFragmentListLayout from './_android-fragment-list-layout.mdx';
6 | import AndroidJavaDataItem from './_android-java-data-item.mdx';
7 | import AndroidJavaListAdapter from './_android-java-list-adapter.mdx';
8 | import AndroidJavaListFragment from './_android-java-list-fragment.mdx';
9 | import AndroidJavaListViewHolder from './_android-java-list-viewholder.mdx';
10 | import AndroidJavaViewManager from './_android-java-viewmanager.mdx';
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
34 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_android-java-list-viewholder.mdx:
--------------------------------------------------------------------------------
1 | #### `NativeListViewHolder.java`
2 |
3 | Now, we need to define the view holder class that will be used by `RecyclerView` to keep reference to the UI elements inside single list item
4 |
5 | ```java title="android/src/main/java/com/nativelistpackage/NativeListViewHolder.java"
6 | package com.nativelistpackage;
7 |
8 | import android.view.View;
9 | import android.widget.ImageView;
10 | import android.widget.TextView;
11 | import androidx.recyclerview.widget.RecyclerView;
12 |
13 | public class NativeListViewHolder extends RecyclerView.ViewHolder {
14 | public ImageView imageView;
15 | public TextView label;
16 |
17 | public NativeListViewHolder(View itemView) {
18 | super(itemView);
19 | this.imageView = itemView.findViewById(R.id.list_card_image);
20 | this.label = itemView.findViewById(R.id.list_card_label);
21 | }
22 | }
23 | ```
24 |
25 | Each class needs to extend base [`RecyclerView.ViewHolder`](https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.ViewHolder) class.
26 | Additionally we declare properties for image and text views, to make it easier later to interact with them.
27 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_android-kotlin-data-item.mdx:
--------------------------------------------------------------------------------
1 | #### `DataItem.kt`
2 |
3 | After defining the layouts, let's jump to code and start by defining Kotlin data class `DataItem` which will be used to hold items passed from JS code:
4 |
5 | ```kotlin title="android/src/main/java/com/nativelistpackage/DataItem.kt"
6 | package com.nativelistpackage
7 |
8 | data class DataItem(
9 | val imageUrl: String,
10 | val description: String,
11 | )
12 | ```
13 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_android-kotlin-impl.mdx:
--------------------------------------------------------------------------------
1 | import AndroidTurboPackage from '../_android-turbo-package.mdx';
2 |
3 | import AndroidAddLibraryInGradle from './_android-add-library-in-gradle.mdx';
4 | import AndroidCardItemLayout from './_android-card-item-layout.mdx';
5 | import AndroidFragmentListLayout from './_android-fragment-list-layout.mdx';
6 | import AndroidKotlinDataItem from './_android-kotlin-data-item.mdx';
7 | import AndroidKotlinListAdapter from './_android-kotlin-list-adapter.mdx';
8 | import AndroidKotlinListFragment from './_android-kotlin-list-fragment.mdx';
9 | import AndroidKotlinListViewHolder from './_android-kotlin-list-viewholder.mdx';
10 | import AndroidKotlinViewManager from './_android-kotlin-viewmanager.mdx';
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
34 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_android-kotlin-list-viewholder.mdx:
--------------------------------------------------------------------------------
1 | #### `NativeListViewHolder.kt`
2 |
3 | Now, we need to define the view holder class that will be used by `RecyclerView` to keep reference to the UI elements inside single list item
4 |
5 | ```kotlin title="android/src/main/java/com/nativelistpackage/NativeListViewHolder.kt"
6 | package com.nativelistpackage
7 |
8 | import android.view.View
9 | import android.widget.ImageView
10 | import android.widget.TextView
11 | import androidx.recyclerview.widget.RecyclerView
12 |
13 | class NativeListViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
14 | var imageView: ImageView
15 | var label: TextView
16 |
17 | init {
18 | imageView = itemView.findViewById(R.id.list_card_image)
19 | label = itemView.findViewById(R.id.list_card_label)
20 | }
21 | }
22 | ```
23 |
24 | Each class needs to extend base [`RecyclerView.ViewHolder`](https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/RecyclerView.ViewHolder) class.
25 | Additionally we declare properties for image and text views, to make it easier later to interact with them.
26 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_category_.json:
--------------------------------------------------------------------------------
1 | {
2 | "position": 7,
3 | "label": "Native list viewcontroller/fragment"
4 | }
5 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_ios-objc-data-item.mdx:
--------------------------------------------------------------------------------
1 | #### `DataItem.h`
2 |
3 | ```objc title="DataItem.h"
4 | #import
5 |
6 | @interface DataItem : NSObject
7 |
8 | @property (nonatomic, copy) NSString * _Nonnull imageUrl;
9 | @property (nonatomic, copy) NSString * _Nonnull itemDescription;
10 |
11 | - (instancetype)initWithImageUrl:(NSString * _Nonnull)imageUrl itemDescription:(NSString * _Nonnull)itemDescription;
12 |
13 | @end
14 | ```
15 |
16 | We start by defining `DataItem` object's interface - it extends `NSObject` and declares two properties (`imageUrl` & `itemDescription`).
17 |
18 | #### `DataItem.mm`
19 |
20 | ```swift title="ios/DataItem.swift"
21 | #import "DataItem.h"
22 |
23 | @implementation DataItem
24 |
25 | - (instancetype)initWithImageUrl:(NSString *)imageUrl itemDescription:(NSString *)itemDescription
26 | {
27 | self = [super init];
28 | if (self) {
29 | _imageUrl = imageUrl;
30 | _itemDescription = itemDescription;
31 | }
32 | return self;
33 | }
34 |
35 | @end
36 | ```
37 |
38 | Next step is declaring implementation for the object.
39 | We will use it later when parsing `data` prop in Objective-C++ code
40 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_ios-objc-impl.mdx:
--------------------------------------------------------------------------------
1 | import IosObjCComponentView from './_ios-objc-componentview.mdx';
2 | import IosObjCContainerView from './_ios-objc-containerview.mdx';
3 | import IosObjCDataItem from './_ios-objc-data-item.mdx';
4 | import IosObjCListCell from './_ios-objc-list-cell.mdx';
5 | import IosObjCViewController from './_ios-objc-viewcontroller.mdx';
6 | import IosObjCViewManager from './_ios-objc-viewmanager.mdx';
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_ios-swift-data-item.mdx:
--------------------------------------------------------------------------------
1 | #### `DataItem.swift`
2 |
3 | Let's start by defining `DataItem` object which will be used to hold items passed from JS code:
4 |
5 | ```swift title="ios/DataItem.swift"
6 | import Foundation
7 |
8 | @objc(DataItem)
9 | public class DataItem: NSObject {
10 | @objc public var imageUrl: String = ""
11 | @objc public var itemDescription: String = ""
12 |
13 | @objc public init(imageUrl: String, itemDescription: String) {
14 | self.imageUrl = imageUrl
15 | self.itemDescription = itemDescription
16 | }
17 | }
18 | ```
19 |
20 | The class (that extends from `NSObject`) defines two string fields and is exported to Objective-C - we will use it later when parsing `data` prop in Objective-C++ code.
21 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_ios-swift-impl.mdx:
--------------------------------------------------------------------------------
1 | import IosSwiftComponentView from './_ios-swift-componentview.mdx';
2 | import IosSwiftContainerView from './_ios-swift-containerview.mdx';
3 | import IosSwiftDataItem from './_ios-swift-data-item.mdx';
4 | import IosSwiftListCell from './_ios-swift-list-cell.mdx';
5 | import IosSwiftViewController from './_ios-swift-viewcontroller.mdx';
6 | import IosSwiftViewManager from './_ios-swift-viewmanager.mdx';
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/_result.mdx:
--------------------------------------------------------------------------------
1 | import nativeListAndroidResult from '/video/native-list-android-result.mp4';
2 | import nativeListIosResult from '/video/native-list-ios-result.mp4';
3 |
4 |
5 |
6 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/native-list-view/ios-impl.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | sidebar_label: iOS implementation
3 | sidebar_position: 4
4 | title: iOS implementation
5 | ---
6 |
7 | import Tabs from '@theme/Tabs';
8 | import TabItem from '@theme/TabItem';
9 |
10 | import IosObjCImpl from './_ios-objc-impl.mdx';
11 | import IosSwiftImpl from './_ios-swift-impl.mdx';
12 |
13 | Let's use XCode, to write iOS code. Open XCode, by running this command from the root directory of your app:
14 |
15 | ```sh
16 | xed ios
17 | ```
18 |
19 | When workspace is opened, locate `Pods` project and expand it. Search for `Development Pods` and find `NativeListPackage` inside. When it's expanded, it will show all files that we created under `native-list-package/ios` directory.
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | You can check training repo for Objective-C & Swift implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/native-list-package) and Objective-C-only implementation [here](https://github.com/mateusz1913/rnbridgingtutorial/tree/main/native-list-package-classic).
35 |
36 | That's iOS part, now let's go to [Android](./android-impl)!
37 |
--------------------------------------------------------------------------------
/bridging-tutorial-website/docs/guides/range-slider-view/_android-change-theme-to-material-3.mdx:
--------------------------------------------------------------------------------
1 | #### Change Android theme to `Material3`
2 |
3 | To use `MaterialComponents` library, we need to change the Android app's theme to the Material theme.
4 | To do that, let's navigate to our tutorial app and go to `styles.xml` in Android resources directory:
5 |
6 | ```diff title="android/app/src/main/res/values/styles.xml"
7 | -