diff --git a/.eslintignore b/.eslintignore index a65b41774..7042d2bb2 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ lib +build diff --git a/.eslintrc.js b/.eslintrc.js index 0a3d72c46..53beac497 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,4 @@ module.exports = { root: true, extends: ["universe/native"], - ignorePatterns: ["build"], }; diff --git a/.github/workflows/review-android.yml b/.github/workflows/review-android.yml new file mode 100644 index 000000000..ac91d7800 --- /dev/null +++ b/.github/workflows/review-android.yml @@ -0,0 +1,128 @@ +name: Android + +on: + workflow_call: + # Review calls this Workflow + +jobs: + build-android: + name: Build ${{ matrix.new-arch && 'new' || 'old'}} Arch + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./packages/react-native-app + strategy: + matrix: + new-arch: [false, true] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Setup Azul Zulu OpenJDK + uses: actions/setup-java@v4 + with: + distribution: zulu + java-version: 21 + cache: gradle + + - name: Cache Build + uses: actions/cache@v4 + id: android-build-cache + with: + path: | + ./android/build + ./packages/react-native-app/android/.gradle + ./packages/react-native-app/android/app/build + ./packages/react-native-app/android/build + key: ${{ runner.os }}-android-build-${{ matrix.new-arch && 'new' || 'old' }}-arch-${{ github.workflow }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-android-build-${{ matrix.new-arch && 'new' || 'old' }}-arch-${{ github.workflow }}-${{ github.sha }} + ${{ runner.os }}-android-build-${{ matrix.new-arch && 'new' || 'old' }}-arch-${{ github.workflow }}- + + - name: Build + if: steps.android-build-cache.outputs.cache-hit != 'true' + run: yarn react-native build-android --mode release --tasks assembleRelease --extra-params "-PnewArchEnabled=${{ matrix.new-arch }}" + + - name: Upload App + uses: actions/upload-artifact@v4 + with: + name: android-app-${{ matrix.new-arch && 'new' || 'old' }}-arch + path: ./packages/react-native-app/android/app/build/outputs/apk/release/app-release.apk + + test-android: + name: Test ${{ matrix.new-arch && 'new' || 'old'}} Arch + needs: [build-android] + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./packages/react-native-app + strategy: + matrix: + new-arch: [false, true] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Enable KVM Group Permissions + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Gradle cache + uses: gradle/actions/setup-gradle@v3 + + - name: Cache Virtual Device + uses: actions/cache@v4 + id: android-virtual-device-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: android-virtual-device-api-level-33 + + - name: Create Virtual Device + if: steps.android-virtual-device-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 33 + target: google_apis + arch: x86_64 + force-avd-creation: false + working-directory: ./packages/react-native-app + script: echo "Generated Android Virtual Device Snapshot for Caching" + + - name: Install Maestro + run: | + curl -Ls "https://get.maestro.mobile.dev" | bash + echo "$HOME/.maestro/bin" >> "$GITHUB_PATH" + + - name: Download App + uses: actions/download-artifact@v4 + with: + name: android-app-${{ matrix.new-arch && 'new' || 'old' }}-arch + path: ./packages/react-native-app/android/ + + - name: Run Tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 33 + target: google_apis + arch: x86_64 + force-avd-creation: false + working-directory: ./packages/react-native-app + script: | + adb install ./android/app-release.apk + maestro test ./e2e/show-map.yml --format junit + + - name: Upload Report + if: always() + uses: actions/upload-artifact@v4 + with: + name: Android Report ${{ matrix.new-arch && 'new' || 'old' }} Arch + path: | + ./packages/react-native-app/report.xml + ~/.maestro/tests/**/* diff --git a/.github/workflows/review-ios.yml b/.github/workflows/review-ios.yml new file mode 100644 index 000000000..3f4e68777 --- /dev/null +++ b/.github/workflows/review-ios.yml @@ -0,0 +1,102 @@ +name: iOS + +on: + workflow_call: + # Review calls this Workflow + +jobs: + build-ios: + name: Build ${{ matrix.new-arch && 'new' || 'old'}} Arch + runs-on: macos-latest + defaults: + run: + working-directory: ./packages/react-native-app + strategy: + matrix: + new-arch: [false, true] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Cache Cocoapods + uses: actions/cache@v4 + id: cocoapods-cache + with: + path: ./packages/react-native-app/ios/Pods + key: ${{ runner.os }}-cocoapods-${{ matrix.new-arch && 'new' || 'old' }}-arch-${{ hashFiles('./packages/react-native-app/ios/Podfile.lock') }} + restore-keys: | + ${{ runner.os }}-cocoapods-${{ matrix.new-arch && 'new' || 'old' }}-arch-${{ hashFiles('./packages/react-native-app/ios/Podfile.lock') }} + ${{ runner.os }}-cocoapods-${{ matrix.new-arch && 'new' || 'old' }}-arch- + + - name: Install Cocoapods + # New Arch changes Podfile.lock so it always has to run + if: matrix.new-arch || steps.cocoapods-cache.outputs.cache-hit != 'true' + run: RCT_NEW_ARCH_ENABLED=${{ matrix.new-arch && '1' || '0' }} yarn pod:install + + - name: Cache Build + uses: actions/cache@v4 + id: ios-build-cache + with: + path: ./packages/react-native-app/ios/build + key: ${{ runner.os }}-ios-build-${{ matrix.new-arch && 'new' || 'old' }}-arch-${{ github.workflow }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-ios-build-${{ matrix.new-arch && 'new' || 'old' }}-arch-${{ github.workflow }}-${{ github.sha }} + ${{ runner.os }}-ios-build-${{ matrix.new-arch && 'new' || 'old' }}-arch-${{ github.workflow }}- + + - name: Build + if: steps.ios-build-cache.outputs.cache-hit != 'true' + # Like `react-native build-ios --mode Release` but adapted for simulators + run: xcodebuild -workspace ios/MapLibreReactNativeExample.xcworkspace -scheme MapLibreReactNativeExample -configuration Release -sdk iphonesimulator -derivedDataPath ios/build + + - name: Upload App + uses: actions/upload-artifact@v4 + with: + name: ios-app-${{ matrix.new-arch && 'new' || 'old' }}-arch + # `.app` is a directory, so we have to archive one level above + path: | + ./packages/react-native-app/ios/build/Build/Products/Release-iphonesimulator + !./packages/react-native-app/ios/build/Build/Products/Release-iphonesimulator/** + ./packages/react-native-app/ios/build/Build/Products/Release-iphonesimulator/MapLibreReactNativeExample.app + + test-ios: + name: Test ${{ matrix.new-arch && 'new' || 'old'}} Arch + needs: [build-ios] + runs-on: macos-latest + defaults: + run: + working-directory: ./packages/react-native-app + strategy: + matrix: + new-arch: [false, true] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Maestro + run: | + curl -Ls "https://get.maestro.mobile.dev" | bash + echo "$HOME/.maestro/bin" >> "$GITHUB_PATH" + + - name: Download App + uses: actions/download-artifact@v4 + with: + name: ios-app-${{ matrix.new-arch && 'new' || 'old' }}-arch + path: ./packages/react-native-app/ios + + - name: Run Tests + run: | + xcrun simctl boot "iPhone 15 Pro" + xcrun simctl install booted ./ios/MapLibreReactNativeExample.app + maestro test ./e2e/show-map.yml --format junit + + - name: Upload Report + if: always() + uses: actions/upload-artifact@v4 + with: + name: iOS Report ${{ matrix.new-arch && 'new' || 'old' }} Arch + path: | + ./packages/react-native-app/report.xml + ~/.maestro/tests/**/* diff --git a/.github/workflows/review.yml b/.github/workflows/review.yml index 11a16e11f..75127694b 100644 --- a/.github/workflows/review.yml +++ b/.github/workflows/review.yml @@ -2,7 +2,7 @@ name: Review on: workflow_call: - # Release calls this Workflow + # Release calls this Workflow pull_request: branches: - main @@ -87,56 +87,10 @@ jobs: - name: Build Library run: yarn prepack - build-react-native-android: - name: Build React Native Android - needs: [lint-eslint, lint-tsc, test, codegen, build-library] - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./packages/react-native-app - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup - uses: ./.github/actions/setup - - - name: Setup Azul Zulu OpenJDK - uses: actions/setup-java@v4 - with: - distribution: zulu - java-version: 21 - - - name: Build Android - run: ./gradlew assemble - working-directory: packages/react-native-app/android - - build-react-native-ios: - name: Build React Native iOS & Test with Detox - needs: [lint-eslint, lint-tsc, test, codegen, build-library] - runs-on: macos-latest - timeout-minutes: 30 - defaults: - run: - working-directory: ./packages/react-native-app - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup - uses: ./.github/actions/setup - - - name: Install Pod Dependencies - run: cd ios && pod --version && pod install - - - name: Install Detox Dependencies - run: | - brew tap wix/brew - brew install applesimutils - yarn detox clean-framework-cache && yarn detox build-framework-cache - - - name: Build iOS - run: yarn detox build -c ios.sim.release + review-android: + name: Android + uses: ./.github/workflows/review-android.yml - - name: Test with Detox - run: yarn detox test --debug-synchronization 200 -c ios.sim.release + review-ios: + name: iOS + uses: ./.github/workflows/review-ios.yml diff --git a/.gitignore b/.gitignore index dc89ab1e9..84ba26785 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,6 @@ packages/expo-app/android # Build by bob lib/ + +# Maestro +report.xml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea372b624..e97295848 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ Which means, when you change something within [ `/src/components/UserLocation.tsx`](/src/components/UserLocation.tsx) it will be reflected in any scene in example that uses that component. -TODO: A better overview of how we use jest, detox, etc. (issue #22) +TODO: A better overview of how we use jest, Maestro, etc. (issue #22) ## Optional: Local development with `yalc` diff --git a/__tests__/__mocks__/react-native.mock.js b/__tests__/__mocks__/react-native.mock.ts similarity index 100% rename from __tests__/__mocks__/react-native.mock.js rename to __tests__/__mocks__/react-native.mock.ts diff --git a/jest-setup.ts b/jest-setup.ts index ca21aa835..ee8100e29 100644 --- a/jest-setup.ts +++ b/jest-setup.ts @@ -2,9 +2,6 @@ import "@testing-library/react-native/extend-expect"; import { NativeModules } from "react-native"; -// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing -jest.mock("react-native/Libraries/Animated/NativeAnimatedHelper"); - function keyMirror(keys: string[]) { const obj: Record = {}; keys.forEach((key) => (obj[key] = key)); diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 44283f0d7..000000000 --- a/jest.config.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - preset: "@testing-library/react-native", - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"], - setupFilesAfterEnv: ["./jest-setup.ts"], - setupFiles: ["./__tests__/__mocks__/react-native.mock.js"], - modulePathIgnorePatterns: ["./lib", "__tests__/__mocks__", "fixtures"], - collectCoverageFrom: ["src/**/*.{ts,tsx,js,jsx}"], -}; diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 000000000..c3597ca64 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,20 @@ +import type { Config } from "jest"; + +const config: Config = { + preset: "@testing-library/react-native", + + moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"], + setupFilesAfterEnv: [ + "./jest-setup.ts", + "./__tests__/__mocks__/react-native.mock.ts", + ], + modulePathIgnorePatterns: [ + "/lib", + "/packages/*", + "__tests__/__mocks__", + "fixtures", + ], + collectCoverageFrom: ["src/**/*.{ts,tsx,js,jsx}"], +}; + +module.exports = config; diff --git a/package.json b/package.json index ea0f32cd9..f25802e41 100644 --- a/package.json +++ b/package.json @@ -115,65 +115,58 @@ ] ] }, - "peerDependenciesMeta": { - "@expo/config-plugins": { - "optional": true - } - }, "peerDependencies": { "@expo/config-plugins": ">=7", + "@types/geojson": "^7946.0.0", + "@types/react": ">=16.6.1", "react": ">=16.6.1", "react-native": ">=0.59.9" }, + "peerDependenciesMeta": { + "@expo/config-plugins": { + "optional": true + }, + "@types/geojson": { + "optional": true + }, + "@types/react": { + "optional": true + } + }, "dependencies": { "@turf/distance": "^7.1.0", "@turf/helpers": "^7.1.0", "@turf/length": "^7.1.0", "@turf/nearest-point-on-line": "^7.1.0", - "@types/debounce": "^1.2.1", - "@types/geojson": "^7946.0.14", - "@types/jest": "^29.5.12", - "@types/node": "^18.11.18", - "@types/react": "^18.2.79", - "@types/react-native": "0.67.8", - "debounce": "^2.0.0" + "debounce": "^2.2.0" }, "devDependencies": { - "@babel/core": "^7.20.5", - "@babel/eslint-parser": "^7.22.9", - "@babel/plugin-proposal-class-properties": "7.18.6", - "@babel/runtime": "7.17.2", - "@expo/config-plugins": "^9.0.9", - "@maplibre/maplibre-gl-style-spec": "21.1.0", - "@react-native/babel-preset": "^0.74.88", - "@react-native/metro-config": "^0.74.88", + "@babel/core": "^7.26.0", + "@expo/config-plugins": "^9.0.11", + "@maplibre/maplibre-gl-style-spec": "22.0.1", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", - "@sinonjs/fake-timers": "^11.2.2", - "@testing-library/react-native": "^12.4.3", + "@sinonjs/fake-timers": "^13.0.5", + "@testing-library/react-native": "^12.9.0", "@types/ejs": "^3.1.5", - "@typescript-eslint/eslint-plugin": "^7.18.0", - "@typescript-eslint/parser": "^7.18.0", - "babel-jest": "^29.6.0", + "@types/geojson": "^7946.0.14", + "@types/node": "^22.10.1", + "@types/react": "^18.3.13", "documentation": "^14.0.0", "ejs": "^3.1.10", - "ejs-lint": "^2.0.0", "eslint": "^8.57.1", - "eslint-config-universe": "13.0.0", + "eslint-config-universe": "14.0.0", "expo-module-scripts": "^4.0.2", "jest": "^29.7.0", - "jest-cli": "^29.7.0", - "prettier": "3.3.3", - "react": "18.2.0", + "prettier": "3.4.2", + "react": "18.3.1", "react-docgen": "^7.1.0", - "react-native": "^0.74.6", - "react-native-builder-bob": "^0.32.0", - "react-test-renderer": "18.2.0", + "react-native": "0.75.4", + "react-native-builder-bob": "^0.34.0", + "react-test-renderer": "18.3.1", "semantic-release": "^24.2.0", + "ts-node": "^10.9.2", "tsx": "^4.19.2", - "typescript": "^5.3.3" - }, - "resolutions": { - "typescript": "5.5.3" + "typescript": "^5.7.2" } } diff --git a/packages/examples/MetroWithMonorepoPaths.js b/packages/examples/MetroWithMonorepoPaths.js index 7a27ac887..f981c35ac 100644 --- a/packages/examples/MetroWithMonorepoPaths.js +++ b/packages/examples/MetroWithMonorepoPaths.js @@ -1,5 +1,5 @@ /* eslint-env node */ -const path = require("path"); +const path = require("node:path"); const { getConfig } = require("react-native-builder-bob/metro-config"); const pkg = require("../../package.json"); diff --git a/packages/examples/package.json b/packages/examples/package.json index c2269ca7c..75fdbaa4e 100644 --- a/packages/examples/package.json +++ b/packages/examples/package.json @@ -28,14 +28,12 @@ }, "devDependencies": { "@react-native-masked-view/masked-view": "^0.3.1", - "@types/geojson": "7946.0.14", "@types/mapbox__geo-viewport": "^0.5.3", - "@types/react": "^18.2.61", - "react": "18.2.0", - "react-native": "^0.74.6", + "@types/react": "^18.3.12", + "react": "18.3.1", + "react-native": "^0.76.3", "react-native-gesture-handler": "^2.20.0", "react-native-safe-area-context": "^4.11.1", - "react-native-screens": "^3.34.0", - "typescript": "^5.5.3" + "react-native-screens": "^3.34.0" } } diff --git a/packages/expo-app/babel.config.js b/packages/expo-app/babel.config.js index 4587c554e..ebd1a71fc 100644 --- a/packages/expo-app/babel.config.js +++ b/packages/expo-app/babel.config.js @@ -1,5 +1,5 @@ /* eslint-env node */ -const path = require("path"); +const path = require("node:path"); const { getConfig } = require("react-native-builder-bob/babel-config"); const pkg = require("../../package.json"); diff --git a/packages/expo-app/package.json b/packages/expo-app/package.json index d90e3fe72..febec0ebb 100644 --- a/packages/expo-app/package.json +++ b/packages/expo-app/package.json @@ -13,17 +13,13 @@ "@maplibre-react-native/examples": "workspace:*", "@maplibre/maplibre-react-native": "workspace:*", "@react-native-masked-view/masked-view": "0.3.2", - "expo": "~52.0.11", - "expo-dev-client": "~5.0.4", + "expo": "~52.0.14", + "expo-dev-client": "~5.0.5", "expo-status-bar": "~2.0.0", "react": "18.3.1", "react-native": "0.76.3", "react-native-gesture-handler": "~2.20.2", "react-native-safe-area-context": "4.12.0", "react-native-screens": "~4.1.0" - }, - "devDependencies": { - "@babel/core": "^7.25.8", - "ts-node": "^10.9.2" } } diff --git a/packages/react-native-app/.detoxrc.js b/packages/react-native-app/.detoxrc.js deleted file mode 100644 index 3415d243e..000000000 --- a/packages/react-native-app/.detoxrc.js +++ /dev/null @@ -1,87 +0,0 @@ -/** @type {Detox.DetoxConfig} */ -module.exports = { - testRunner: { - args: { - $0: "jest", - config: "e2e/jest.config.js", - }, - jest: { - setupTimeout: 120000, - }, - }, - apps: { - "ios.debug": { - type: "ios.app", - binaryPath: - "ios/build/Build/Products/Debug-iphonesimulator/MapLibreReactNativeExample.app", - build: - "xcodebuild -workspace ios/MapLibreReactNativeExample.xcworkspace -scheme MapLibreReactNativeExample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", - }, - "ios.release": { - type: "ios.app", - binaryPath: - "ios/build/Build/Products/Release-iphonesimulator/MapLibreReactNativeExample.app", - build: - "xcodebuild -workspace ios/MapLibreReactNativeExample.xcworkspace -scheme MapLibreReactNativeExample -configuration Release -sdk iphonesimulator -derivedDataPath ios/build", - }, - "android.debug": { - type: "android.apk", - binaryPath: "android/app/build/outputs/apk/debug/app-debug.apk", - build: - "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug", - reversePorts: [8081], - }, - "android.release": { - type: "android.apk", - binaryPath: "android/app/build/outputs/apk/release/app-release.apk", - build: - "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release", - }, - }, - devices: { - simulator: { - type: "ios.simulator", - device: { - type: "iPhone 15", - }, - }, - attached: { - type: "android.attached", - device: { - adbName: ".*", - }, - }, - emulator: { - type: "android.emulator", - device: { - avdName: "Pixel_3a_API_30_x86", - }, - }, - }, - configurations: { - "ios.sim.debug": { - device: "simulator", - app: "ios.debug", - }, - "ios.sim.release": { - device: "simulator", - app: "ios.release", - }, - "android.att.debug": { - device: "attached", - app: "android.debug", - }, - "android.att.release": { - device: "attached", - app: "android.release", - }, - "android.emu.debug": { - device: "emulator", - app: "android.debug", - }, - "android.emu.release": { - device: "emulator", - app: "android.release", - }, - }, -}; diff --git a/packages/react-native-app/.gitignore b/packages/react-native-app/.gitignore index c3fa5fb9d..52694ee7f 100644 --- a/packages/react-native-app/.gitignore +++ b/packages/react-native-app/.gitignore @@ -2,12 +2,6 @@ # .DS_Store -# MAPBOX token ENVs -# generated on set-up -# -accesstoken -env.json - # Xcode # build/ @@ -63,10 +57,10 @@ yarn-error.log *.jsbundle # CocoaPods -/ios/Pods/ -/ios/Podfile.lock +ios/Pods/ # Temporary files created by Metro to check the health of the file watcher .metro-health-check* -# testing -/coverage \ No newline at end of file + +# Testing +coverage diff --git a/packages/react-native-app/.watchmannconfig b/packages/react-native-app/.watchmannconfig new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/packages/react-native-app/.watchmannconfig @@ -0,0 +1 @@ +{} diff --git a/packages/react-native-app/Gemfile b/packages/react-native-app/Gemfile new file mode 100644 index 000000000..85d7f6828 --- /dev/null +++ b/packages/react-native-app/Gemfile @@ -0,0 +1,9 @@ +source 'https://rubygems.org' + +# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version +ruby ">= 2.6.10" + +# Exclude problematic versions of cocoapods and activesupport that causes build failures. +gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1' +gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0' +gem 'xcodeproj', '< 1.26.0' diff --git a/packages/react-native-app/android/app/src/main/AndroidManifest.xml b/packages/react-native-app/android/app/src/main/AndroidManifest.xml index 316331636..e1521c0a4 100644 --- a/packages/react-native-app/android/app/src/main/AndroidManifest.xml +++ b/packages/react-native-app/android/app/src/main/AndroidManifest.xml @@ -4,28 +4,27 @@ - + - - - - - - + android:roundIcon="@mipmap/ic_launcher_round" + android:supportsRtl="true" + android:theme="@style/AppTheme"> + + + + + + diff --git a/packages/react-native-app/android/app/src/main/java/com/maplibrereactnativeexample/MainApplication.kt b/packages/react-native-app/android/app/src/main/java/com/maplibrereactnativeexample/MainApplication.kt index 6dc8a933e..c2bdb2f24 100644 --- a/packages/react-native-app/android/app/src/main/java/com/maplibrereactnativeexample/MainApplication.kt +++ b/packages/react-native-app/android/app/src/main/java/com/maplibrereactnativeexample/MainApplication.kt @@ -9,6 +9,7 @@ import com.facebook.react.ReactPackage import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost import com.facebook.react.defaults.DefaultReactNativeHost +import com.facebook.react.soloader.OpenSourceMergedSoMapping import com.facebook.soloader.SoLoader import org.maplibre.reactnative.MLRNPackage; @@ -39,7 +40,7 @@ class MainApplication : Application(), ReactApplication { override fun onCreate() { super.onCreate() - SoLoader.init(this, false) + SoLoader.init(this, OpenSourceMergedSoMapping) if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { // If you opted-in for the New Architecture, we load the native entry point for this app. load() diff --git a/packages/react-native-app/android/build.gradle b/packages/react-native-app/android/build.gradle index df1ce4db3..152214627 100644 --- a/packages/react-native-app/android/build.gradle +++ b/packages/react-native-app/android/build.gradle @@ -1,8 +1,8 @@ buildscript { ext { - buildToolsVersion = "34.0.0" - minSdkVersion = 23 - compileSdkVersion = 34 + buildToolsVersion = "35.0.0" + minSdkVersion = 24 + compileSdkVersion = 35 targetSdkVersion = 34 ndkVersion = "26.1.10909125" kotlinVersion = "1.9.24" @@ -18,4 +18,4 @@ buildscript { } } -apply plugin: "com.facebook.react.rootproject" +apply plugin: "com.facebook.react.rootproject" \ No newline at end of file diff --git a/packages/react-native-app/android/gradle.properties b/packages/react-native-app/android/gradle.properties index 9fb15664b..2b5cf841a 100644 --- a/packages/react-native-app/android/gradle.properties +++ b/packages/react-native-app/android/gradle.properties @@ -36,4 +36,4 @@ newArchEnabled=false # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. -hermesEnabled=true +hermesEnabled=true \ No newline at end of file diff --git a/packages/react-native-app/android/gradle/wrapper/gradle-wrapper.properties b/packages/react-native-app/android/gradle/wrapper/gradle-wrapper.properties index 6f7a6eb33..c0cb293e8 100644 --- a/packages/react-native-app/android/gradle/wrapper/gradle-wrapper.properties +++ b/packages/react-native-app/android/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/packages/react-native-app/android/gradlew b/packages/react-native-app/android/gradlew index b740cf133..b26d41105 100755 --- a/packages/react-native-app/android/gradlew +++ b/packages/react-native-app/android/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -246,4 +249,4 @@ eval "set -- $( tr '\n' ' ' )" '"$@"' -exec "$JAVACMD" "$@" +exec "$JAVACMD" "$@" \ No newline at end of file diff --git a/packages/react-native-app/android/gradlew.bat b/packages/react-native-app/android/gradlew.bat index 25da30dbd..f46bb5271 100644 --- a/packages/react-native-app/android/gradlew.bat +++ b/packages/react-native-app/android/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -89,4 +91,4 @@ exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal -:omega +:omega \ No newline at end of file diff --git a/packages/react-native-app/android/settings.gradle b/packages/react-native-app/android/settings.gradle index b84e6b1b2..6e051a536 100644 --- a/packages/react-native-app/android/settings.gradle +++ b/packages/react-native-app/android/settings.gradle @@ -1,6 +1,6 @@ pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") } plugins { id("com.facebook.react.settings") } -extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() } +extensions.configure(com.facebook.react.ReactSettingsExtension) { ex -> ex.autolinkLibrariesFromCommand() } rootProject.name = 'MapLibreReactNativeExample' include ':mlrn' diff --git a/packages/react-native-app/babel.config.js b/packages/react-native-app/babel.config.js index 0d9d90f71..4739c3acd 100644 --- a/packages/react-native-app/babel.config.js +++ b/packages/react-native-app/babel.config.js @@ -1,5 +1,5 @@ /* eslint-env node */ -const path = require("path"); +const path = require("node:path"); const { getConfig } = require("react-native-builder-bob/babel-config"); const pkg = require("../../package.json"); diff --git a/packages/react-native-app/e2e/firstTest.e2e.js b/packages/react-native-app/e2e/firstTest.e2e.js deleted file mode 100644 index 31022533c..000000000 --- a/packages/react-native-app/e2e/firstTest.e2e.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-disable */ - -describe('Maps Example App', () => { - beforeAll(async () => { - await device.launchApp(); - }); - - afterEach(async () => { - await device.reloadReactNative(); - }); - - it('should show initial screen', async () => { - await expect(element(by.text('Map'))).toBeVisible(); - await expect(element(by.text('Camera'))).toBeVisible(); - await expect(element(by.text('User Location'))).toBeVisible(); - }); -}); diff --git a/packages/react-native-app/e2e/jest.config.js b/packages/react-native-app/e2e/jest.config.js deleted file mode 100644 index 9ae87b59b..000000000 --- a/packages/react-native-app/e2e/jest.config.js +++ /dev/null @@ -1,12 +0,0 @@ -/** @type {import('@jest/types').Config.InitialOptions} */ -module.exports = { - rootDir: "..", - testMatch: ["/e2e/**/*.e2e.js"], - testTimeout: 120000, - maxWorkers: 1, - globalSetup: "detox/runners/jest/globalSetup", - globalTeardown: "detox/runners/jest/globalTeardown", - reporters: ["detox/runners/jest/reporter"], - testEnvironment: "detox/runners/jest/testEnvironment", - verbose: true, -}; diff --git a/packages/react-native-app/e2e/show-map.yml b/packages/react-native-app/e2e/show-map.yml new file mode 100644 index 000000000..1a810e91e --- /dev/null +++ b/packages/react-native-app/e2e/show-map.yml @@ -0,0 +1,20 @@ +appId: org.maplibre.reactnative.example +--- +- launchApp +- tapOn: "Map[,]? ›" +- tapOn: "Show Map[,]? ›" +- assertVisible: "Show Map" + +- runFlow: + when: + platform: Android + commands: + - tapOn: "Attribution icon. Activate to show attribution dialog." + - assertVisible: "MapLibre Maps SDK for Android" + +- runFlow: + when: + platform: iOS + commands: + - tapOn: "About this map" + - assertVisible: "MapLibre Native iOS" diff --git a/packages/react-native-app/ios/MapLibreReactNativeExample.xcodeproj/project.pbxproj b/packages/react-native-app/ios/MapLibreReactNativeExample.xcodeproj/project.pbxproj index d3a4068cc..391442e79 100644 --- a/packages/react-native-app/ios/MapLibreReactNativeExample.xcodeproj/project.pbxproj +++ b/packages/react-native-app/ios/MapLibreReactNativeExample.xcodeproj/project.pbxproj @@ -7,27 +7,27 @@ objects = { /* Begin PBXBuildFile section */ - 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; + 0C80B921A6F3F58F76C31292 /* libPods-MapLibreReactNativeExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-MapLibreReactNativeExample.a */; }; + 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 1DC0AFC22BE58DCE00FBCA80 /* MapLibre in Frameworks */ = {isa = PBXBuildFile; productRef = 1DC0AFC12BE58DCE00FBCA80 /* MapLibre */; }; - 2B603C2EE532BDC98C0C1354 /* libPods-MapLibreReactNativeExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BFD1441A45E7C8246ED3CEDF /* libPods-MapLibreReactNativeExample.a */; }; - 51C0260825301F99008C5283 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 51C0260725301F99008C5283 /* LaunchScreen.storyboard */; }; - ABFF5F20602FA5B9796E966D /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 3AB2AAB6E474104F831A6963 /* PrivacyInfo.xcprivacy */; }; + 519D15602D020E19009F802D /* MapLibre in Frameworks */ = {isa = PBXBuildFile; productRef = 57D38659624A4159F63D7BA4 /* MapLibre */; }; + 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; + A0062AFBABAAC219026F55E2 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 13B07F961A680F5B00A75B9A /* MapLibreReactNativeExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MapLibreReactNativeExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = MapLibreReactNativeExample/AppDelegate.h; sourceTree = ""; }; - 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = MapLibreReactNativeExample/AppDelegate.m; sourceTree = ""; }; + 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = MapLibreReactNativeExample/AppDelegate.mm; sourceTree = ""; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = MapLibreReactNativeExample/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = MapLibreReactNativeExample/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = MapLibreReactNativeExample/main.m; sourceTree = ""; }; - 3AB2AAB6E474104F831A6963 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = MapLibreReactNativeExample/PrivacyInfo.xcprivacy; sourceTree = ""; }; - 51C0260725301F99008C5283 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = MapLibreReactNativeExample/LaunchScreen.storyboard; sourceTree = ""; }; - 6E29023E8B5A6DA540E4474B /* Pods-MapLibreReactNativeExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MapLibreReactNativeExample.release.xcconfig"; path = "Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample.release.xcconfig"; sourceTree = ""; }; - A32049E2AE532B3366AA9311 /* Pods-MapLibreReactNativeExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MapLibreReactNativeExample.debug.xcconfig"; path = "Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample.debug.xcconfig"; sourceTree = ""; }; - BFD1441A45E7C8246ED3CEDF /* libPods-MapLibreReactNativeExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MapLibreReactNativeExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = MapLibreReactNativeExample/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 3B4392A12AC88292D35C810B /* Pods-MapLibreReactNativeExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MapLibreReactNativeExample.debug.xcconfig"; path = "Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample.debug.xcconfig"; sourceTree = ""; }; + 5709B34CF0A7D63546082F79 /* Pods-MapLibreReactNativeExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MapLibreReactNativeExample.release.xcconfig"; path = "Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample.release.xcconfig"; sourceTree = ""; }; + 5DCACB8F33CDC322A6C60F78 /* libPods-MapLibreReactNativeExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MapLibreReactNativeExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = MapLibreReactNativeExample/LaunchScreen.storyboard; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -36,8 +36,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 1DC0AFC22BE58DCE00FBCA80 /* MapLibre in Frameworks */, - 2B603C2EE532BDC98C0C1354 /* libPods-MapLibreReactNativeExample.a in Frameworks */, + 519D15602D020E19009F802D /* MapLibre in Frameworks */, + 0C80B921A6F3F58F76C31292 /* libPods-MapLibreReactNativeExample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -47,29 +47,22 @@ 13B07FAE1A68108700A75B9A /* MapLibreReactNativeExample */ = { isa = PBXGroup; children = ( - 51C0260725301F99008C5283 /* LaunchScreen.storyboard */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */, - 13B07FB01A68108700A75B9A /* AppDelegate.m */, + 13B07FB01A68108700A75B9A /* AppDelegate.mm */, 13B07FB51A68108700A75B9A /* Images.xcassets */, 13B07FB61A68108700A75B9A /* Info.plist */, + 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 13B07FB71A68108700A75B9A /* main.m */, - 3AB2AAB6E474104F831A6963 /* PrivacyInfo.xcprivacy */, + 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */, ); name = MapLibreReactNativeExample; sourceTree = ""; }; - 29082F7A5E3B4C188AA82FB2 /* Resources */ = { - isa = PBXGroup; - children = ( - ); - name = Resources; - sourceTree = ""; - }; 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { isa = PBXGroup; children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - BFD1441A45E7C8246ED3CEDF /* libPods-MapLibreReactNativeExample.a */, + 5DCACB8F33CDC322A6C60F78 /* libPods-MapLibreReactNativeExample.a */, ); name = Frameworks; sourceTree = ""; @@ -88,8 +81,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */, 83CBBA001A601CBA00E9B192 /* Products */, 2D16E6871FA4F8E400B85C8A /* Frameworks */, - EE5EDD88BB42C11717A56BB9 /* Pods */, - 29082F7A5E3B4C188AA82FB2 /* Resources */, + BBD78D7AC51CEA395F1C20DB /* Pods */, ); indentWidth = 2; sourceTree = ""; @@ -104,11 +96,11 @@ name = Products; sourceTree = ""; }; - EE5EDD88BB42C11717A56BB9 /* Pods */ = { + BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( - A32049E2AE532B3366AA9311 /* Pods-MapLibreReactNativeExample.debug.xcconfig */, - 6E29023E8B5A6DA540E4474B /* Pods-MapLibreReactNativeExample.release.xcconfig */, + 3B4392A12AC88292D35C810B /* Pods-MapLibreReactNativeExample.debug.xcconfig */, + 5709B34CF0A7D63546082F79 /* Pods-MapLibreReactNativeExample.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -120,13 +112,13 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "MapLibreReactNativeExample" */; buildPhases = ( - BDA2996983FC83FE8B42398D /* [CP] Check Pods Manifest.lock */, - FD10A7F022414F080027D42C /* Start Packager */, + C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 7BC27FFD4688D6914F2322C7 /* [CP] Copy Pods Resources */, + 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */, + E235C05ADACE081382539298 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -134,7 +126,7 @@ ); name = MapLibreReactNativeExample; packageProductDependencies = ( - 1DC0AFC12BE58DCE00FBCA80 /* MapLibre */, + 57D38659624A4159F63D7BA4 /* MapLibre */, ); productName = MapLibreReactNativeExample; productReference = 13B07F961A680F5B00A75B9A /* MapLibreReactNativeExample.app */; @@ -146,11 +138,19 @@ 83CBB9F71A601CBA00E9B192 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 940; - ORGANIZATIONNAME = Facebook; + LastUpgradeCheck = 1210; + TargetAttributes = { + 00E356ED1AD99517003FC87E = { + CreatedOnToolsVersion = 6.2; + TestTargetID = 13B07F861A680F5B00A75B9A; + }; + 13B07F861A680F5B00A75B9A = { + LastSwiftMigration = 1120; + }; + }; }; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "MapLibreReactNativeExample" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 12.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -159,7 +159,7 @@ ); mainGroup = 83CBB9F61A601CBA00E9B192; packageReferences = ( - DB11E3B9346BB8DFEB4101D5 /* XCRemoteSwiftPackageReference "maplibre-gl-native-distribution" */, + A561C65B7C488474562F962D /* XCRemoteSwiftPackageReference "maplibre-gl-native-distribution" */, ); productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; projectDirPath = ""; @@ -175,9 +175,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, - 51C0260825301F99008C5283 /* LaunchScreen.storyboard in Resources */, - ABFF5F20602FA5B9796E966D /* PrivacyInfo.xcprivacy in Resources */, + A0062AFBABAAC219026F55E2 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -190,41 +190,34 @@ files = ( ); inputPaths = ( + "$(SRCROOT)/.xcode.env.local", + "$(SRCROOT)/.xcode.env", ); name = "Bundle React Native code and images"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; + shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; }; - 7BC27FFD4688D6914F2322C7 /* [CP] Copy Pods Resources */ = { + 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/boost/boost_privacy.bundle", - "${PODS_CONFIGURATION_BUILD_DIR}/glog/glog_privacy.bundle", + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/boost_privacy.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/glog_privacy.bundle", + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - BDA2996983FC83FE8B42398D /* [CP] Check Pods Manifest.lock */ = { + C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -246,23 +239,21 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - FD10A7F022414F080027D42C /* Start Packager */ = { + E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); - name = "Start Packager"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MapLibreReactNativeExample/Pods-MapLibreReactNativeExample-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -272,7 +263,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, + 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 13B07FC11A68108700A75B9A /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -282,23 +273,19 @@ /* Begin XCBuildConfiguration section */ 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A32049E2AE532B3366AA9311 /* Pods-MapLibreReactNativeExample.debug.xcconfig */; + baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-MapLibreReactNativeExample.debug.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = 1; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; - GCC_PREPROCESSOR_DEFINITIONS = ( - "$(inherited)", - "FB_SONARKIT_ENABLED=0", - ); + ENABLE_BITCODE = NO; INFOPLIST_FILE = MapLibreReactNativeExample/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "RN App"; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; + IPHONEOS_DEPLOYMENT_TARGET = 15.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); + MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -306,25 +293,26 @@ ); PRODUCT_BUNDLE_IDENTIFIER = org.maplibre.reactnative.example; PRODUCT_NAME = MapLibreReactNativeExample; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6E29023E8B5A6DA540E4474B /* Pods-MapLibreReactNativeExample.release.xcconfig */; + baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-MapLibreReactNativeExample.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = 1; - "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; INFOPLIST_FILE = MapLibreReactNativeExample/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "RN App"; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; + IPHONEOS_DEPLOYMENT_TARGET = 15.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); + MARKETING_VERSION = 1.0; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -332,6 +320,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = org.maplibre.reactnative.example; PRODUCT_NAME = MapLibreReactNativeExample; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; @@ -340,7 +329,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CC = ""; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++20"; CLANG_CXX_LIBRARY = "libc++"; @@ -360,6 +348,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -367,7 +356,6 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CXX = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; @@ -386,22 +374,26 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; - LD = ""; - LDPLUSPLUS = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.1; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", ); LIBRARY_SEARCH_PATHS = ( - "$(SDKROOT)/usr/lib/swift", + "\"$(SDKROOT)/usr/lib/swift\"", "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = "$(inherited)"; - OTHER_CPLUSPLUSFLAGS = "$(inherited)"; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-DFOLLY_NO_CONFIG", + "-DFOLLY_MOBILE=1", + "-DFOLLY_USE_LIBCPP=1", + "-DFOLLY_CFG_NO_COROUTINES=1", + "-DFOLLY_HAVE_CLOCK_GETTIME=1", + ); OTHER_LDFLAGS = ( "$(inherited)", " ", @@ -409,7 +401,7 @@ REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG"; - USE_HERMES = false; + USE_HERMES = true; }; name = Debug; }; @@ -417,7 +409,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CC = ""; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++20"; CLANG_CXX_LIBRARY = "libc++"; @@ -437,6 +428,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -444,7 +436,6 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; - CXX = ""; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = ""; @@ -456,28 +447,32 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.4; - LD = ""; - LDPLUSPLUS = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.1; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", ); LIBRARY_SEARCH_PATHS = ( - "$(SDKROOT)/usr/lib/swift", + "\"$(SDKROOT)/usr/lib/swift\"", "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = NO; - OTHER_CFLAGS = "$(inherited)"; - OTHER_CPLUSPLUSFLAGS = "$(inherited)"; + OTHER_CPLUSPLUSFLAGS = ( + "$(OTHER_CFLAGS)", + "-DFOLLY_NO_CONFIG", + "-DFOLLY_MOBILE=1", + "-DFOLLY_USE_LIBCPP=1", + "-DFOLLY_CFG_NO_COROUTINES=1", + "-DFOLLY_HAVE_CLOCK_GETTIME=1", + ); OTHER_LDFLAGS = ( "$(inherited)", " ", ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; - USE_HERMES = false; + USE_HERMES = true; VALIDATE_PRODUCT = YES; }; name = Release; @@ -506,20 +501,20 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - DB11E3B9346BB8DFEB4101D5 /* XCRemoteSwiftPackageReference "maplibre-gl-native-distribution" */ = { + A561C65B7C488474562F962D /* XCRemoteSwiftPackageReference "maplibre-gl-native-distribution" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/maplibre/maplibre-gl-native-distribution"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 6.5.4; + kind = exactVersion; + version = 6.5.4; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 1DC0AFC12BE58DCE00FBCA80 /* MapLibre */ = { + 57D38659624A4159F63D7BA4 /* MapLibre */ = { isa = XCSwiftPackageProductDependency; - package = DB11E3B9346BB8DFEB4101D5 /* XCRemoteSwiftPackageReference "maplibre-gl-native-distribution" */; + package = A561C65B7C488474562F962D /* XCRemoteSwiftPackageReference "maplibre-gl-native-distribution" */; productName = MapLibre; }; /* End XCSwiftPackageProductDependency section */ diff --git a/packages/react-native-app/ios/MapLibreReactNativeExample.xcodeproj/xcshareddata/xcschemes/MapLibreReactNativeExample.xcscheme b/packages/react-native-app/ios/MapLibreReactNativeExample.xcodeproj/xcshareddata/xcschemes/MapLibreReactNativeExample.xcscheme index ff2e1de94..b0caf8a28 100644 --- a/packages/react-native-app/ios/MapLibreReactNativeExample.xcodeproj/xcshareddata/xcschemes/MapLibreReactNativeExample.xcscheme +++ b/packages/react-native-app/ios/MapLibreReactNativeExample.xcodeproj/xcshareddata/xcschemes/MapLibreReactNativeExample.xcscheme @@ -3,23 +3,9 @@ LastUpgradeVersion = "1210" version = "1.3"> - - - - - - - - - - - - - - - -#if FB_SONARKIT_ENABLED -#import -#import -#import -#import -#import -#import - -static void InitializeFlipper(UIApplication *application) { - FlipperClient *client = [FlipperClient sharedClient]; - SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; - [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; - [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; - [client addPlugin:[FlipperKitReactPlugin new]]; - [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; - [client start]; -} -#endif - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - #if FB_SONARKIT_ENABLED - InitializeFlipper(application); - #endif - - self.moduleName = @"MapLibreReactNativeExample"; - - // You can add your custom initial props in the dictionary below. - // They will be passed down to the ViewController used by React Native. - self.initialProps = @{}; - - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge -{ - return [self bundleURL]; -} - -- (NSURL *)bundleURL -{ -#if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; -#else - return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; -#endif -} - -@end \ No newline at end of file diff --git a/packages/react-native-app/ios/MapLibreReactNativeExample/AppDelegate.mm b/packages/react-native-app/ios/MapLibreReactNativeExample/AppDelegate.mm new file mode 100644 index 000000000..bbc8b69af --- /dev/null +++ b/packages/react-native-app/ios/MapLibreReactNativeExample/AppDelegate.mm @@ -0,0 +1,31 @@ +#import "AppDelegate.h" + +#import + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.moduleName = @"MapLibreReactNativeExample"; + // You can add your custom initial props in the dictionary below. + // They will be passed down to the ViewController used by React Native. + self.initialProps = @{}; + + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge +{ + return [self bundleURL]; +} + +- (NSURL *)bundleURL +{ +#if DEBUG + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; +#else + return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; +#endif +} + +@end diff --git a/packages/react-native-app/ios/MapLibreReactNativeExample/LaunchScreen.storyboard b/packages/react-native-app/ios/MapLibreReactNativeExample/LaunchScreen.storyboard index d1388d18e..edd46eb15 100644 --- a/packages/react-native-app/ios/MapLibreReactNativeExample/LaunchScreen.storyboard +++ b/packages/react-native-app/ios/MapLibreReactNativeExample/LaunchScreen.storyboard @@ -16,7 +16,7 @@ -