Skip to content

Conversation

@theocalmes
Copy link
Contributor

This PR introduces a self contained "cross platform" plugin system for maplibre.

At its core, the CrossPlatformPlugin system simply punches a tiny hole through the iOS and Android platforms, allowing plugins to access mbgl::Map and other core objects directly. Each plugin is itself an mbgl::MapObserver allowing them to respond to map events (like onCameraChange, onStyleImageMissing etc), essentially behaving like a platform MapView.

This combo allows complex map features to be built targeting the native core that will run on both iOS and Android while not breaking any of the current API contracts or contributing to any binary size increase to the main library. This means that plugins can live right alongside existing iOS and Android platform APIs and be integrated into existing mobile apps as is.

NOTE: The plugin system is not opinionated about:

  • ios/android platform glue for bi-directional communication with the plugins themselves (you can use JNI, C, Objc++, whatever)
  • build systems (while the examples I provide show how one might implement plugin incorporation and distribution, the goal is simply to introduce the API layer)

While the plugin system is itself very simple, integration into build systems, tooling and creating ios/android platform glue is not. To that end I have provided two plugin examples which are integrated into the android and ios test apps.

Example Plugins

On iOS, the plugins are built using the bazel system, while on android they make use of cmake. I am not an expert in any of these systems and the build setup is for demonstration only. At meta we use BUCK, which is bazel like and enables advanced features like so merging on Android, and mixed objc/swift which works well for this kind of system.

On Android, plugins are built via CMake and are inserted directly into the Maplibre.so to avoid issues with symbol visibility and complex merging. Maplibre Android defaults to private visibility which would make merging .so from 3rd parties difficult.

Basic Plugin using Objc++ and Maplibre's JNI system for glue

This plugin shows how to setup the plugin c++ core and one approach to "hand rolling" platform bindings. On iOS we can simply use Objc++ and get swift integration via objc interop. On Android, I've provided a convenience hook into Maplibre's own JNI setup.

This plugin simply calls into the camera and zooms to sf bay area.

Advanced Plugin using HereMaps Gluecodium for platfrom glue

Gluecodium is a system developed by HereMaps to generate C++ code and language bindings in Swift/Java/Kotlin and Dart. You program your interface via an IDL called Lime and it will generate native c++ interfaces and platform glue to bind it.

platform/plugins/arrow-polyline-example-plugin/api/ArrowPolylineExample.lime shows our interface definitions and all the code under /generated is what gluecodium outputs.

With a system like gluecodium, you can write your plugins in C++ and expose APIs via the lime interface (like functions, structures, classes etc). This gives a stable API to the platforms and keeps the implementation in C++. However the tradeoff is going to be binary size and complexity of your build system.

I've attached screen recordings of a small plugin that draws polyline arrows with arrow pixel respecting arrow heads. This makes use of the Camera MapObserver callback and of mbgl::Style.

https://github.com/user-attachments/assets/399c8753-3228-4fce-91e5-0acab487888b
https://github.com/user-attachments/assets/b7302914-a2e1-4144-b3eb-2cb335f7d8d1

@github-actions github-actions bot added build Related to build, configuration or CI/CD android iOS cpp-core labels Dec 10, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Dec 10, 2025

Bloaty Results 🐋

Compared to main

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  [ = ]       0  [ = ]       0    TOTAL

Full report: https://maplibre-native.s3.eu-central-1.amazonaws.com/bloaty-results/pr-3999-compared-to-main.txt

Compared to d387090 (legacy)

    FILE SIZE        VM SIZE    
 --------------  -------------- 
   +47% +54.9Mi  +451% +26.9Mi    TOTAL

Full report: https://maplibre-native.s3.eu-central-1.amazonaws.com/bloaty-results/pr-3999-compared-to-legacy.txt

@github-actions
Copy link
Contributor

Bloaty Results (iOS) 🐋

Compared to main

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.0% +1.32Ki  [ = ]       0    TOTAL

Full report: https://maplibre-native.s3.eu-central-1.amazonaws.com/bloaty-results-ios/pr-3999-compared-to-main.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

android build Related to build, configuration or CI/CD cpp-core iOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants