Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/workflows/android-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Build Android

permissions:
contents: read

on:
push:
branches:
- master
paths:
- '.github/workflows/android-build.yml'
- 'example/android/**'
- 'nitrogen/generated/shared/**'
- 'nitrogen/generated/android/**'
- 'cpp/**'
- 'android/**'
- '**/package-lock.json'
- '**/react-native.config.js'
- '**/nitro.json'
pull_request:
paths:
- '.github/workflows/android-build.yml'
- 'example/android/**'
- '**/nitrogen/generated/shared/**'
- '**/nitrogen/generated/android/**'
- 'cpp/**'
- 'android/**'
- '**/package-lock.json'
- '**/react-native.config.js'
- '**/nitro.json'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build Android Example App
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version

- name: Install dependencies
run: npm ci

- name: Setup JDK 17
uses: actions/setup-java@v5
with:
distribution: 'zulu'
java-version: '17'
cache: 'gradle'

- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('example/android/**/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Run Gradle build
working-directory: example/android
run: ./gradlew assembleDebug --no-daemon --build-cache

- name: Stop Gradle daemon
working-directory: example/android
run: ./gradlew --stop
102 changes: 102 additions & 0 deletions .github/workflows/ios-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Build iOS

permissions:
contents: read

on:
push:
branches:
- master
paths:
- '.github/workflows/ios-build.yml'
- 'example/ios/**'
- 'example/Gemfile'
- 'example/Gemfile.lock'
- '**/nitrogen/generated/shared/**'
- '**/nitrogen/generated/ios/**'
- 'cpp/**'
- 'ios/**'
- '**/Podfile.lock'
- '**/package-lock.json'
- '**/*.podspec'
- '**/react-native.config.js'
- '**/nitro.json'
pull_request:
paths:
- '.github/workflows/ios-build.yml'
- 'example/ios/**'
- 'example/Gemfile'
- 'example/Gemfile.lock'
- '**/nitrogen/generated/shared/**'
- '**/nitrogen/generated/ios/**'
- 'cpp/**'
- 'ios/**'
- '**/Podfile.lock'
- '**/package-lock.json'
- '**/*.podspec'
- '**/react-native.config.js'
- '**/nitro.json'
workflow_dispatch:

env:
USE_CCACHE: 1

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build iOS Example App
runs-on: macOS-15
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
- name: Setup Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16.4

- name: Install dependencies
run: npm ci

- name: Setup Ruby (bundle)
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
working-directory: example/ios

- name: Install xcpretty
run: gem install xcpretty

- name: Cache CocoaPods
uses: actions/cache@v4
with:
path: |
~/.cocoapods/repos
example/ios/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('example/ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-

- name: Install Pods
working-directory: example/ios
run: pod install

- name: Build App
working-directory: example/ios
run: |
set -o pipefail && xcodebuild \
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
-derivedDataPath build -UseModernBuildSystem=YES \
-workspace HapticsExample.xcworkspace \
-scheme HapticsExample \
-sdk iphonesimulator \
-configuration Debug \
-destination 'platform=iOS Simulator,name=iPhone 16' \
build \
CODE_SIGNING_ALLOWED=NO | xcpretty
8 changes: 2 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,11 @@ android/keystores/debug.keystore
!.yarn/releases
!.yarn/sdks
!.yarn/versions
.kotlin

# Expo
.expo/

# Turborepo
.turbo/

# TypeScript
tsconfig.tsbuildinfo

# generated by bob
lib/
tsconfig.tsbuildinfo
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.18.0
22.16.0
5 changes: 0 additions & 5 deletions NitroHaptics.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ Pod::Spec.new do |s|
"cpp/**/*.{hpp,cpp}",
]

s.pod_target_xcconfig = {
# C++ compiler flags, mainly for folly.
"GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES"
}

load 'nitrogen/generated/ios/NitroHaptics+autolinking.rb'
add_nitrogen_files(s)

Expand Down
3 changes: 3 additions & 0 deletions android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ set (PACKAGE_NAME NitroHaptics)
set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_CXX_STANDARD 20)

# Enable Raw Props parsing in react-native (for Nitro Views)
add_compile_options(-DRN_SERIALIZABLE_STATE=1)

# Define C++ library and add all sources
add_library(${PACKAGE_NAME} SHARED
src/main/cpp/cpp-adapter.cpp
Expand Down
46 changes: 27 additions & 19 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ buildscript {
}

dependencies {
classpath "com.android.tools.build:gradle:8.8.1"
classpath "com.android.tools.build:gradle:8.8.0"
}
}

Expand All @@ -21,6 +21,7 @@ def isNewArchitectureEnabled() {
apply plugin: "com.android.library"
apply plugin: 'org.jetbrains.kotlin.android'
apply from: '../nitrogen/generated/android/NitroHaptics+autolinking.gradle'
apply from: "./fix-prefab.gradle"

if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
Expand All @@ -35,7 +36,7 @@ def getExtOrIntegerDefault(name) {
}

android {
namespace "com.margelo.nitro.nitrohaptics"
namespace "com.haptics"

ndkVersion getExtOrDefault("ndkVersion")
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
Expand All @@ -48,7 +49,7 @@ android {
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
arguments "-DANDROID_STL=c++_shared"
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
abiFilters (*reactNativeArchitectures())

buildTypes {
Expand All @@ -71,22 +72,22 @@ android {

packagingOptions {
excludes = [
"META-INF",
"META-INF/**",
"**/libc++_shared.so",
"**/libfbjni.so",
"**/libjsi.so",
"**/libfolly_json.so",
"**/libfolly_runtime.so",
"**/libglog.so",
"**/libhermes.so",
"**/libhermes-executor-debug.so",
"**/libhermes_executor.so",
"**/libreactnative.so",
"**/libreactnativejni.so",
"**/libturbomodulejsijni.so",
"**/libreact_nativemodule_core.so",
"**/libjscexecutor.so"
"META-INF",
"META-INF/**",
"**/libc++_shared.so",
"**/libfbjni.so",
"**/libjsi.so",
"**/libfolly_json.so",
"**/libfolly_runtime.so",
"**/libglog.so",
"**/libhermes.so",
"**/libhermes-executor-debug.so",
"**/libhermes_executor.so",
"**/libreactnative.so",
"**/libreactnativejni.so",
"**/libturbomodulejsijni.so",
"**/libreact_nativemodule_core.so",
"**/libjscexecutor.so"
]
}

Expand Down Expand Up @@ -138,3 +139,10 @@ dependencies {
implementation project(":react-native-nitro-modules")
}

if (isNewArchitectureEnabled()) {
react {
jsRootDir = file("../src/")
libraryName = "NitroHaptics"
codegenJavaPackageName = "com.haptics"
}
}
51 changes: 51 additions & 0 deletions android/fix-prefab.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
tasks.configureEach { task ->
// Make sure that we generate our prefab publication file only after having built the native library
// so that not a header publication file, but a full configuration publication will be generated, which
// will include the .so file

def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
def matcher = task.name =~ prefabConfigurePattern
if (matcher.matches()) {
def variantName = matcher[0][1]
task.outputs.upToDateWhen { false }
task.dependsOn("externalNativeBuild${variantName}")
}
}

afterEvaluate {
def abis = reactNativeArchitectures()
rootProject.allprojects.each { proj ->
if (proj === rootProject) return

def dependsOnThisLib = proj.configurations.findAll { it.canBeResolved }.any { config ->
config.dependencies.any { dep ->
dep.group == project.group && dep.name == project.name
}
}
if (!dependsOnThisLib && proj != project) return

if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
return
}

def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
// Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
// generate a libnameConfig.cmake file that will contain our native library (.so).
// See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue
variants.all { variant ->
def variantName = variant.name
abis.each { abi ->
def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
if (!searchDir.exists()) return
def matches = []
searchDir.eachDir { randomDir ->
def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
if (prefabFile.exists()) matches << prefabFile
}
matches.each { prefabConfig ->
prefabConfig.setLastModified(System.currentTimeMillis())
}
}
}
}
}
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
NitroHaptics_kotlinVersion=2.0.21
NitroHaptics_kotlinVersion=2.1.20
NitroHaptics_minSdkVersion=23
NitroHaptics_targetSdkVersion=35
NitroHaptics_compileSdkVersion=34
Expand Down
20 changes: 20 additions & 0 deletions android/src/main/java/com/haptics/HapticsPackage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.haptics;

import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.TurboReactPackage;
import com.margelo.nitro.haptics.NitroHapticsOnLoad;


public class HapticsPackage : TurboReactPackage() {
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? = null

override fun getReactModuleInfoProvider(): ReactModuleInfoProvider = ReactModuleInfoProvider { emptyMap() }

companion object {
init {
NitroHapticsOnLoad.initializeNative();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.margelo.nitro.haptics
package com.haptics

data class HapticsVibrationType(
val timings: LongArray,
Expand Down
Loading