cranpose_storekit/lib.rs
1#![deny(missing_docs)]
2#![deny(unsafe_code)]
3
4//! StoreKit 2 backend for [`cranpose_services::purchases`].
5//!
6//! StoreKit 2 has no Objective-C surface — `Product`, `Transaction` and the
7//! on-device JWS verification are Swift-only — so this crate compiles a small
8//! Swift shim (`swift/storekit.swift`) in its build script and links it
9//! statically. Apple recommends StoreKit 2 for anything that can require
10//! iOS 15; StoreKit 1 (`SKPaymentQueue`) is the Objective-C fallback and is
11//! deliberately not used here.
12//!
13//! On non-Apple targets the build script is a no-op and every entry point
14//! compiles away, so this crate can sit in an Android/Linux/web dependency
15//! graph unnoticed.
16//!
17//! ```no_run
18//! # #[cfg(any(target_os = "ios", target_os = "macos"))]
19//! # fn demo() {
20//! cranpose_storekit::register();
21//! cranpose_services::purchases::configure(&["com.example.app.pro"]);
22//! # }
23//! ```
24//!
25//! # Threading
26//!
27//! StoreKit answers on Swift concurrency executors, so the Swift shim calls
28//! back from arbitrary threads. All state therefore lives behind a
29//! [`std::sync::Mutex`] here, and [`cranpose_services::purchases::Purchases`]
30//! reads a clone of it from the UI thread.
31
32// The crate root denies unsafe code; `apple` is the one boundary module that
33// opts back in, and it is the only place FFI lives. Same shape as cranpose's
34// own platform modules, and
35// `crates/cranpose/tests/platform_scheduling_static.rs` holds the workspace
36// list of modules allowed to do this.
37#[cfg(any(target_os = "ios", target_os = "macos"))]
38mod apple;
39
40#[cfg(any(target_os = "ios", target_os = "macos"))]
41pub use apple::{register, StoreKitPurchases};
42
43/// Installs the StoreKit backend — a no-op on targets without an App Store.
44///
45/// Call it before
46/// [`configure`](cranpose_services::purchases::configure); apps that also run
47/// on Android or desktop can call it unconditionally.
48#[cfg(not(any(target_os = "ios", target_os = "macos")))]
49pub fn register() {}