-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Permission, Building Blocks for Native APIs #4842
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
base: main
Are you sure you want to change the base?
Conversation
packages/mobile-geolocation/src/sys/android/LocationCallback.java
Outdated
Show resolved
Hide resolved
Improves code formatting in has_location_permission and check_permission functions by splitting long lines and updating function signatures for better readability. No functional changes were made.
The java_plugin macro now accepts full relative paths for Java files instead of assuming a fixed directory structure. Documentation and usage examples have been updated to reflect this change, improving flexibility and clarity for specifying file locations.
Added checks for authorization status before requesting location permissions and retrieving location data. Now only requests permission if not determined, and attempts to retrieve cached location before starting location updates, improving efficiency and user experience.
Introduces the ios_plugin! macro in mobile-core-macro for declarative iOS framework metadata embedding. Updates mobile-core to re-export the macro and refactors mobile-geolocation to use ios_plugin! instead of manual linker attributes.
|
I think i am able to package swift files as swift package and package it and run. (Like how tauri does for swift files) |
|
I am also able to build each android plugin as a gradle submodule and can be tested like this inside each plugin ./gradlew assembleRelease --no-daemon --warning-mode all-Oops i broke it lol- my bad it worked |
|
Running gradle assembly takes time now, And i expect with the number of apis you add, it will grow exponentially |
Here is a breakdown of how things are working for now.Android (Kotlin / Gradle)Source layout
build.rs responsibilities
Metadata embedded in the Rust binaryIn #[cfg(all(feature = "metadata", target_os = "android"))]
dioxus_platform_bridge::android_plugin!(
plugin = "geolocation",
aar = { env = "DIOXUS_ANDROID_ARTIFACT" },
deps = ["implementation(\"com.google.android.gms:play-services-location:21.3.0\")"]
);The The macro serializes:
The metadata is wrapped in What the CLI does (
|
| Platform | Native sources live | Compiled by | Metadata stored | CLI responsibilities |
|---|---|---|---|---|
| Android | packages/geolocation/android (Gradle lib) |
build.rs running gradlew assembleRelease |
SymbolData::AndroidArtifact (plugin, path, deps) |
Copy .aar into app/libs, append Gradle dependencies |
| iOS/macOS | packages/geolocation/ios (SwiftPM) |
build.rs running xcrun swift build |
SymbolData::SwiftPackage (plugin, package path, product) |
Embed Swift stdlibs when Swift metadata is present |
This setup keeps each plugin self-contained:
- All native code + build tooling stays inside the crate.
build.rsproduces platform artifacts and emits env vars for linker metadata.- The Dioxus CLI only needs the linker symbols to know what to copy/embed when bundling user apps.
|
I have added the geolocation package + example for geolocation in for easy testing so the diff is huge as of now. I need to delete them before we upstream it. |
|
@jkelleyrtp I am sorry for a large diff atm, it has changes from #4932 as well as package/geolocation and example inside. So its easier for you to check. I am going out for few weeks after 2-3 days so i wanted to make sure this PR is in good shape before that. A small review on the build process would be really appreciated. I think the way it turned out is really interesting + approach is something that can be shared across other rust UI projects (I wonder someone can fork tauri plugins and make it compatiable with dioxus as this opens the door for that as well) |
Awesome! Will try to get it in next week and then hopefully in a patch release soon after that |





This PR introduces a comprehensive linker-based permission management for automatic update of manifest files and android native plugin building foundation for Dioxus. The implementation is inspired by Manganis's linker-based asset collection approach.
Build on top of #4932 so diff is huge for now
Two main motivation for this PR
Currently packages/geolocation and geolocation example resides within this PR, its just for the ease of testing, and will not be upstreamed
Here is a breakdown of how things are working for now.
Android (Kotlin / Gradle)
Source layout
packages/geolocation/android/.aar:android/build/outputs/aar/geolocation-plugin-release.aarbuild.rs responsibilities
packages/geolocation/build.rsbuilds the Gradle module whenever the target triple containsandroid:DX_ANDROID_JAVA_HOME,DX_ANDROID_SDK_ROOT,DX_ANDROID_NDK_HOME,DX_ANDROID_ARTIFACT_DIR). If those are absent (non-dxbuilds) it fallsback to
ANDROID_*orJAVA_HOME../gradlew assembleReleaseinsidepackages/geolocation/android..aarinto the CLI-provided artifact staging dir(
$DX_ANDROID_ARTIFACT_DIR/geolocation-plugin-release.aaror$OUT_DIR/android-artifacts/...as a fallback).cargo:rustc-env=DIOXUS_ANDROID_ARTIFACT=<absolute path>so the Rust macro can referencethe built artifact.
Metadata embedded in the Rust binary
In
packages/geolocation/src/lib.rswe declare the Android artifact like this:The
aarblock only needs a stable way to refer to the file thatbuild.rsproduced. Emitting acargo:rustc-env=...from the build script is the idiomatic Rust approach for passing data frombuild.rsto the crate being compiled, which is why each plugin publishes its own environmentvariable. Nothing prevents you from using unique names—
DIOXUS_GEO_ANDROID_ARTIFACT,DIOXUS_CAMERA_ANDROID_ARTIFACT, etc.—as long as your macro invocation references the same key thatyour build script sets. Automatically inferring the path from the plugin name is brittle because the
artifact location lives in
target/(or another$OUT_DIR) that onlybuild.rsknows about afterrunning Gradle, so the build script remains the single source of truth.
The macro serializes:
pluginnameaarpath (resolved via the env var emitted bybuild.rs)depsThe metadata is wrapped in
SymbolData::AndroidArtifactand stored under the shared__ASSETS__*symbol prefix (the same one used for assets and permissions). Nothing runs at runtime—the symbols are just scanned later by the CLI.
What the CLI does (
dx serve --android)dxwalks every__ASSETS__*symbol once. When it encounters aSymbolData::AndroidArtifact, it adds it to the manifest alongside assets and permissions.install_android_artifacts()(inpackages/cli/src/build/request.rs) copies each.aarintotarget/dx/.../app/libs/in the generated Gradle project.implementation(files("libs/<artifact>.aar"))deps(e.g. the Play Services location runtime)app/build.gradle.kts, so they get packaged automatically.iOS / macOS (Swift Package)
Source layout
Package.swiftlive underpackages/geolocation/ios/GeolocationPluginbuild.rs responsibilities
For Apple targets,
build.rs:aarch64-apple-ios,aarch64-apple-ios-sim,x86_64-apple-ios) andfinds the matching SDK via
xcrun --show-sdk-path.xcrun swift build --package-path ios --configuration <debug|release> --triple <...> --sdk <...> --product GeolocationPlugin.libGeolocationPlugin.a) and emits:cargo:rustc-link-searchfor both the Swift build output and the Xcode toolchain Swift libscargo:rustc-link-lib=static=GeolocationPlugincargo:rustc-link-lib=swiftCompatibility*+-force_loadflags so the ObjC runtime sees theplugin class
cargo:rustc-link-lib=framework=CoreLocation/FoundationAt this point the Swift code is already linked into the Mach-O produced by Rust; no additional build
steps are required later.
Metadata embedded in the Rust binary
In
packages/geolocation/src/lib.rswe declare the Swift package via:This writes an entry into the shared
__ASSETS__*stream asSymbolData::SwiftPackage. Again,nothing is executed at runtime; it is just discoverable metadata alongside assets and permissions.
What the CLI does (
dx serve --ios/--macos)SymbolData::SwiftPackageentries while it’s already processing the assetstream.
embed_swift_stdlibs()runs (seepackages/cli/src/build/request.rs). This invokesxcrun swift-stdlib-tool --scan-executableonthe final app binary and copies the required Swift runtime libraries into the bundle’s
Frameworks/folder (iOS) orContents/Frameworks/(macOS).Because the Swift package was linked during the Rust build, the CLI’s only job is to make sure the
Swift runtime ships alongside the executable.
Summary table
packages/geolocation/android(Gradle lib)build.rsrunninggradlew assembleReleaseSymbolData::AndroidArtifact(plugin, path, deps).aarintoapp/libs, append Gradle dependenciespackages/geolocation/ios(SwiftPM)build.rsrunningxcrun swift buildSymbolData::SwiftPackage(plugin, package path, product)This setup keeps each plugin self-contained:
build.rsproduces platform artifacts and emits env vars for linker metadata.New crates: (Please suggest the names as i am bad at naming stuff)