Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Expo plugin props #589

Merged
merged 39 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1e468a6
feat: add GoogleLocationEngineImpl
KiwiKilian Nov 27, 2024
8e08e7c
Merge branch 'beta' into feat/google-location-engine
KiwiKilian Dec 2, 2024
9132058
fix: locatin package names
KiwiKilian Dec 2, 2024
0febd9a
Merge branch 'beta' into feat/google-location-engine
KiwiKilian Dec 28, 2024
94adc62
chore: remove debug
KiwiKilian Dec 28, 2024
f6dd68e
feat: use namespace prefix for gradle properties
KiwiKilian Dec 30, 2024
6a26674
feat: configure locationEngine via gradle.properties and sourceSets
KiwiKilian Dec 30, 2024
50f0fcb
refactor: split out ios plugin code
KiwiKilian Dec 30, 2024
4407821
test: update Podfile fixtures
KiwiKilian Dec 30, 2024
ea53e6d
test: apply mods to snapshots
KiwiKilian Dec 30, 2024
ec8e304
feat: add android expo plugin for location engine
KiwiKilian Jan 2, 2025
1052747
fix: use PropertiesItem from @expo/config-plugins
KiwiKilian Jan 2, 2025
2890d72
style: fix type import
KiwiKilian Jan 2, 2025
bd6b68a
test: improve ios fixtures
KiwiKilian Jan 2, 2025
92ac844
feat: revert plugin
KiwiKilian Jan 2, 2025
cd79948
feat: remove all new plugin files
KiwiKilian Jan 2, 2025
40d0dcb
style: remove unused import
KiwiKilian Jan 2, 2025
b6a2e8c
feat: use customizable properties with prefix
KiwiKilian Jan 2, 2025
1d239d2
feat: use withPodfile instead of withDangerousMod
KiwiKilian Jan 2, 2025
4aff753
test: use snapshot-diff for better plugin snapshots
KiwiKilian Jan 2, 2025
684b6f5
test: use snapshotDiff.getSnapshotDiffSerializer
KiwiKilian Jan 2, 2025
ae80f42
test: add Podfile fixture sources
KiwiKilian Jan 2, 2025
33f4288
Merge branch 'feat/expo-ios-plugin-clean' into feat/expo-android-plugin
KiwiKilian Jan 3, 2025
d884c88
feat: add locationEngine to Android plugin
KiwiKilian Jan 3, 2025
e22cfd5
feat: add configurable versions on Android
KiwiKilian Jan 3, 2025
69928a5
feat: add Android properties to Expo plugin
KiwiKilian Jan 3, 2025
f04adb8
docs: add doc comments to MapLibrePluginProps
KiwiKilian Jan 3, 2025
6484405
feat: allow more Podfile customization
KiwiKilian Jan 3, 2025
b24a238
feat: add iOS properties to Expo plugin
KiwiKilian Jan 3, 2025
0b79091
Merge branch 'beta' into feat/expo-plugin-props
KiwiKilian Jan 3, 2025
a9aff35
style: fix typo
KiwiKilian Jan 3, 2025
9f048ca
style: use slash regex
KiwiKilian Jan 3, 2025
eac7bb8
test: fix applyPodfileConstants behavior
KiwiKilian Jan 3, 2025
28e815d
fix: update iOS native version regex
KiwiKilian Jan 3, 2025
620153b
style: fix linting import type
KiwiKilian Jan 3, 2025
82daefc
refactor: rename constants to global variables
KiwiKilian Jan 4, 2025
2a5216b
docs: add customization docs
KiwiKilian Jan 4, 2025
a2c87ca
docs: improve customization wordings
KiwiKilian Jan 4, 2025
d29f652
docs: customization wording
KiwiKilian Jan 4, 2025
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ diverged, it has become necessary to separate the projects into specific wrapper
- Installation
- [Expo](/docs/guides/setup/Expo.md)
- [React Native](/docs/guides/setup/React-Native.md)
- [Customization](/docs/guides/setup/Customization.md)
- Migrations
- [Migrating to v10](/docs/guides/migrations/v10.md)

Expand Down
22 changes: 11 additions & 11 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -116,24 +116,24 @@ dependencies {
implementation "com.facebook.react:react-native:+"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

// MapLibre SDK
implementation "org.maplibre.gl:android-sdk:11.7.1"
implementation "org.maplibre.gl:android-sdk-turf:6.0.1"
// MapLibre Native
implementation "org.maplibre.gl:android-sdk:${getConfigurableExtOrDefault('nativeVersion')}"

// MapLibre Plugins
implementation "org.maplibre.gl:android-plugin-localization-v9:${getConfigurableExtOrDefault('pluginVersion')}"
implementation "org.maplibre.gl:android-plugin-annotation-v9:${getConfigurableExtOrDefault('pluginVersion')}"
implementation "org.maplibre.gl:android-plugin-markerview-v9:${getConfigurableExtOrDefault('pluginVersion')}"

// Dependencies
implementation "org.maplibre.gl:android-sdk-turf:${getConfigurableExtOrDefault('turfVersion')}"
implementation "com.squareup.okhttp3:okhttp:${getConfigurableExtOrDefault('okhttpVersion')}"
implementation "com.squareup.okhttp3:okhttp-urlconnection:${getConfigurableExtOrDefault('okhttpVersion')}"
implementation "androidx.vectordrawable:vectordrawable:1.1.0"
implementation "androidx.annotation:annotation:1.7.0"
implementation "androidx.appcompat:appcompat:1.6.1"
implementation "com.squareup.okhttp3:okhttp:${getConfigurableExtOrDefault('okhttpVersion')}"
implementation "com.squareup.okhttp3:okhttp-urlconnection:${getConfigurableExtOrDefault('okhttpVersion')}"

// MapLibre Plugins
implementation ("org.maplibre.gl:android-plugin-localization-v9:3.0.1")
implementation ("org.maplibre.gl:android-plugin-annotation-v9:3.0.1")
implementation ("org.maplibre.gl:android-plugin-markerview-v9:3.0.1")

// Dependencies for Google Location Engine
if (getConfigurableExtOrDefault("locationEngine") == "google") {
implementation "com.google.android.gms:play-services-location:21.3.0"
implementation "com.google.android.gms:play-services-location:${getConfigurableExtOrDefault('googlePlayServicesLocationVersion')}"
}
}
9 changes: 6 additions & 3 deletions android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ org.maplibre.reactnative.targetSdkVersion=31
org.maplibre.reactnative.compileSdkVersion=31
org.maplibre.reactnative.ndkVersion=21.4.7075529

# MapLibre React Native Customizations

# MapLibre React Native
org.maplibre.reactnative.nativeVersion=11.7.1
org.maplibre.reactnative.pluginVersion=3.0.1
org.maplibre.reactnative.turfVersion=6.0.1
org.maplibre.reactnative.okhttpVersion=4.9.0

# Available values: default, google
org.maplibre.reactnative.locationEngine=default
# Only applied if locationEngine=google
org.maplibre.reactnative.googlePlayServicesLocationVersion=21.3.0
101 changes: 101 additions & 0 deletions docs/guides/setup/Customization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Setup Customization

It's possible to customize the native setup of the library. These props must be applied differently, based on
the project setup.

## Expo

When using Expo, simply add the customizations in the projects `app.json` or `app.config.{js,ts}`. Here is an
example customization for in a `app.config.ts`:

```ts
import type { MapLibrePluginProps } from "@maplibre/maplibre-react-native";

export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
plugins: [
[
"@maplibre/maplibre-react-native",
{
android: {
nativeVersion: "x.x.x",
},
ios: {
nativeVersion: "x.x.x",
},
} as MapLibrePluginProps,
],
],
});
```

## React Native

When using React Native, the customizations have to be applied differently for each platform.

On Android they are set in the `gradle.properties`, each of them prefixed with `org.maplibre.reactnative`. Example:

```diff
+ org.maplibre.reactnative.nativeVersion=x.x.x
```

On iOS global variables in the `Podfile` are used, prefixed with `$MLRN`.

```diff
+ $MLRN_NATIVE_VERSION="x.x.x"

target "AppName" do
```

## Available Customizations

### Android

| Prop Key | Type | Description |
| ----------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------- |
| `nativeVersion` | `VersionString` | Version for [`org.maplibre.gl:android-sdk`](https://mvnrepository.com/artifact/org.maplibre.gl/android-sdk) |
| `pluginVersion` | `VersionString` | Version for `org.maplibre.gl:android-plugin-*-v9` |
| `turfVersion` | `VersionString` | Version for `org.maplibre.gl:android-sdk-turf` |
| `okhttpVersion` | `VersionString` | Version for `com.squareup.okhttp3:okhttp` |
| `locationEngine` | `"default" \| "google"` | [Location engine to be used](#location-engine) |
| `googlePlayServicesLocationVersion` | `VersionString` | Version for `com.google.android.gms:play-services-location`, only used with `locationEngine: "google"` |

For default values see [`gradle.properties` of the library](/android/gradle.properties).

#### Location Engine

Two location engines are available on Android:

- `default`
- Default location engine provided by the device
- Doesn't work with emulator
- F-Droid compatible
- `google`
- Google Play Services Location Engine
- Possibly more accurate
- Works with emulator
- Not F-Droid compatible

### iOS

| Prop Key | `Podfile` Global Variable | Type | Description |
| --------------- | ------------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------- |
| `nativeVersion` | `$MLRN_NATIVE_VERSION` | `VersionString` | Version for [`maplibre-gl-native-distribution`](https://github.com/maplibre/maplibre-gl-native-distribution/releases) |
| `spmSpec` | `$MLRN_SPM_SPEC` | `string` | [Swift Package Manager Spec](#spm-spec) |

For default values see [`maplibre-react-native.podspec` of the library](/maplibre-react-native.podspec).

#### SPM Spec

Setting a Swift Package Manager Spec allows further customization over setting the native version:

```rb
$MLRN_SPM_SPEC = {
url: "https://github.com/maplibre/maplibre-gl-native-distribution",
requirement: {
kind: "upToNextMajorVersion",
minimumVersion: "x.x.x"
},
product_name: "MapLibre"
}
```
16 changes: 10 additions & 6 deletions docs/guides/setup/Expo.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,19 @@ After installing the package, add the [config plugin](https://docs.expo.io/guide
```json
{
"expo": {
"plugins": ["@maplibre/maplibre-react-native"]
"plugins": [
"@maplibre/maplibre-react-native"
]
}
}
```

Next, rebuild your app as described in the ["Adding custom native code"](https://docs.expo.io/workflow/customizing/)
guide.
Next, rebuild your app as described in the ["Add custom native code"](https://docs.expo.io/workflow/customizing/) guide.

## Plugin Properties
The plugin is required to properly install MapLibre Native on iOS, where it adds `$MLRN.post_install(installer)` to the
`post_install` block in the `ios/Podfile`. On Android it only serves customizations.

This plugin doesn't currently provide any additional properties for customization. The plugin simply generates the
post-install block in the `ios/Podfile`. No additional changes are done on Android.
## Plugin Props

The plugin allows to customize the setup of MapLibre React Native through plugin props. Find out more in
the [customization guide](/docs/guides/setup/Customization.md).
18 changes: 4 additions & 14 deletions docs/guides/setup/React-Native.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,7 @@ pod install

Now rebuild your app.

### Installing a specific version

If you want to modify the MapLibre Native iOS version, you can override as follows in your `Podfile`:

```rb
$MLRN_SPM_Spec = {
url: "https://github.com/maplibre/maplibre-gl-native-distribution",
requirement: {
kind: "upToNextMajorVersion",
minimumVersion: "<Set your version here>"
},
product_name: "MapLibre"
}
```
## Customzations

You can customize the setup of MapLibre React Native through `gradle.properties` on Android or global variables in the
`Podfile` on iOS. Find out more in the [customization guide](/docs/guides/setup/Customization.md).
29 changes: 15 additions & 14 deletions maplibre-react-native.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@ require 'json'

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

# Global Variable Defaults
$MLRN_NATIVE_VERSION ||= "6.9.0"
$MLRN_SPM_SPEC ||= {
url: "https://github.com/maplibre/maplibre-gl-native-distribution",
requirement: {
kind: "exactVersion",
version: $MLRN_NATIVE_VERSION
},
product_name: "MapLibre"
}

$MLRN = Object.new

def $MLRN._add_spm_to_target(project, target, url, requirement, product_name)
Expand All @@ -24,18 +35,8 @@ def $MLRN._add_spm_to_target(project, target, url, requirement, product_name)
end

def $MLRN.post_install(installer)
spm_spec = {
url: "https://github.com/maplibre/maplibre-gl-native-distribution",
requirement: {
kind: "exactVersion",
version: "6.9.0"
},
product_name: "MapLibre"
}
spm_spec = $MLRN_SPM_SPEC

if $MLRN_SPM_Spec.is_a?(Hash)
spm_spec = $MLRN_SPM_Spec
end
project = installer.pods_project
self._add_spm_to_target(
project,
Expand All @@ -61,9 +62,9 @@ def $MLRN.post_install(installer)
end

Pod::Spec.new do |s|
s.name = "maplibre-react-native"
s.summary = "React Native library for creating maps with MapLibre Native"
s.version = package['version']
s.name = "maplibre-react-native"
s.summary = "React Native library for creating maps with MapLibre Native"
s.version = package['version']
s.authors = { "MapLibre" => "" }
s.homepage = "https://github.com/maplibre/maplibre-react-native"
s.source = { :git => "https://github.com/maplibre/maplibre-react-native.git" }
Expand Down
12 changes: 11 additions & 1 deletion packages/expo-app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import "ts-node/register";
import { type ExpoConfig, type ConfigContext } from "expo/config";

import type { MapLibrePluginProps } from "../../src";

export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
name: "Expo App",
Expand Down Expand Up @@ -33,5 +35,13 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
backgroundColor: "#285daa",
translucent: false,
},
plugins: ["../../src/plugin/withMapLibre.ts"],
plugins: [
[
"../../src/plugin/withMapLibre.ts",
{
android: {},
ios: {},
} as MapLibrePluginProps,
],
],
});
6 changes: 3 additions & 3 deletions scripts/utils/getNativeVersion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ let cachedIosVersion: string;
export const getAndroidVersion = async () => {
if (!cachedAndroidVersion) {
cachedAndroidVersion = await getNativeVersion(
["android", "build.gradle"],
/^\s+implementation\s+"org.maplibre.gl:android-sdk:(\d+\.\d+\.\d+)"$/,
["android", "gradle.properties"],
/^org\.maplibre\.reactnative\.nativeVersion=(\d+\.\d+\.\d+)$/,
);
}

Expand All @@ -32,7 +32,7 @@ export const getIosVersion = async () => {
if (!cachedIosVersion) {
cachedIosVersion = await getNativeVersion(
["maplibre-react-native.podspec"],
/^\s+version:\s*"(\d+\.\d+\.\d+)"$/,
/^\$MLRN_NATIVE_VERSION \|\|= "(\d+\.\d+\.\d+)"$/,
);
}

Expand Down
2 changes: 2 additions & 0 deletions src/MapLibreRN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,5 @@ export type {
BackgroundLayerStyle,
LightLayerStyle,
} from "./types/MapLibreRNStyles";

export type { MapLibrePluginProps } from "./plugin/MapLibrePluginProps";
41 changes: 41 additions & 0 deletions src/__tests__/plugin/android/getGradleProperties.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { getGradleProperties } from "../../../plugin/android";

describe("Expo Plugin Android – getGradleProperties", () => {
it("removes empty property keys", () => {
const result = getGradleProperties({
android: {
// @ts-expect-error
"": "default",
},
});

expect(result).toEqual([]);
});

it("removes empty property values", () => {
const result = getGradleProperties({
android: {
// @ts-expect-error
locationEngine: "",
},
});

expect(result).toEqual([]);
});

it("adds valid properties", () => {
const result = getGradleProperties({
android: {
locationEngine: "google",
},
});

expect(result).toEqual([
{
type: "property",
key: "org.maplibre.reactnative.locationEngine",
value: "google",
},
]);
});
});
37 changes: 37 additions & 0 deletions src/__tests__/plugin/android/mergeGradleProperties.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { mergeGradleProperties } from "../../../plugin/android";

const PROPERTY = {
type: "property",
key: "exampleProperty",
value: "value",
} as const;

const NEW_PROPERTY = {
type: "property",
key: "newProperty",
value: "new",
} as const;

describe("Expo Plugin Android – mergeGradleProperties", () => {
it("replaces duplicate property", () => {
expect(
mergeGradleProperties(
[
PROPERTY,
{
...NEW_PROPERTY,
value: "old",
},
],
[NEW_PROPERTY],
),
).toEqual([PROPERTY, NEW_PROPERTY]);
});

it("adds new property", () => {
expect(mergeGradleProperties([PROPERTY], [NEW_PROPERTY])).toEqual([
PROPERTY,
NEW_PROPERTY,
]);
});
});
Loading
Loading