1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! The Apple (iOS) backend: TWO Rust `define_class!` Objective-C classes,
//! and nothing else — the whole platform surface this plugin will ever need
//! on Apple, however many controls [`crate::runtime`] grows.
//!
//! The Android arm's mirror image, minus the glue. Android needs two Kotlin
//! classes (a factory, a listener) and four JNI exports because a Java
//! factory has to call *into* Rust; on iOS both the factory and the listener
//! **are** Rust — the factory ([`factory`]) registered directly with the
//! Objective-C runtime and looked up by name, the listener's target-action
//! counterpart ([`events`]) constructed straight from live Rust code — **zero
//! Swift** (proven in a signed release build). Read
//! [`factory`]'s module doc for the frozen protocol contract, the two
//! load-bearing name pins, the non-nil failure contract, and why no
//! `ios_exports!`/`#[used]` static is needed here; read [`events`]'s module
//! doc for the target-action attach/detach contract and the per-slot
//! retention story.
//!
//! # iOS only, not `target_vendor = "apple"`
//!
//! Unlike `plugins/camera`/`plugins/shared-preferences`/
//! `plugins/secure-storage`, this plugin's Apple surface is UIKit, which does
//! not exist on macOS — gating on `target_vendor = "apple"` makes a macOS
//! desktop-preview build try to link the `UIKit` framework and fail. See
//! `Cargo.toml`'s comment on the same gate.
//!
//! # Threading
//!
//! Every entry point runs on the platform main thread: the host drives the
//! factory from its post-frame command poll (`FrustViewHost`, itself driven
//! from `FrustViewController`'s `CADisplayLink`), and a `UIControl`'s
//! target-action ([`events`]) fires there too. Unlike the Android arm, that is
//! not a `debug_assert` — both classes are `#[thread_kind = MainThreadOnly]`,
//! so their methods can only be entered with a [`MainThreadMarker`] in hand,
//! and [`NativeCtx`] carries that proof into every control call.
//!
//! [`MainThreadMarker`]: objc2::MainThreadMarker
// Theme ladder L3: resolving the embedded Glyph font bytes to a
// process-cached `CTFontDescriptor` via CoreText. `pub(crate)`, not private
// like `ctx`/`events`: `controls::platform`'s `resolve_font` (theme ladder
// L3's per-size `CTFont` construction) needs `fonts::descriptor_for` from
// OUTSIDE this module's own subtree — the same reason
// `crate::android::fonts` is `pub(crate)`.
pub
// Theme ladder L1: the night-qualified-`Context` mirror through
// `overrideUserInterfaceStyle`. Private — its only caller, `create_control`
// below, lives inside this same module tree (unlike `fonts`, nothing outside
// `apple` needs it: L2's corner radius needs no density conversion on this
// arm, see `theme`'s own module doc).
pub use NativeCtx;
pub use FrustNativeControlTarget;
pub use ensure_registered;
use crate;
use crate;
use crateNativeRuntime;
/// A control's retained native reference — on Apple that is exactly the
/// registry's [`AppleHandle`], an ARC-managed `Retained<UIView>` behind a
/// [`MainThreadMarker`](objc2::MainThreadMarker) gate.
///
/// No paired-delete discipline is needed on this arm (`Retained`'s own `Drop`
/// releases the object), which is the one structural difference from
/// `crate::android`'s `NativeView` and its `extra` global-ref list.
///
/// [`AppleHandle`]: crate::registry::apple::AppleHandle
pub type NativeView = crateAppleHandle;
/// Register every control kind this backend serves, once, when the thread's
/// runtime is first touched (`crate::runtime`'s `seeded_runtime`) — the Apple
/// mirror of `crate::android::register_controls`, **line for line** for the
/// shared kinds, then the Apple-only ones, then the iOS-only ones.
///
/// The controls live in the shared `crate::controls`, where the props/plan
/// half is platform-neutral and host-tested and only the platform half is a
/// per-target `mod platform` inside each control file. So every backend
/// registers by the same `KIND` consts — never a literal here — and by its
/// arm's tables: `crate::controls::SHARED_KINDS` (all three arms), then
/// `crate::controls::APPLE_KINDS` (iOS + macOS only; `Segmented`,
/// `Stepper`), then `crate::controls::IOS_ONLY_KINDS` (this arm alone;
/// `TabBar` — `crate::appkit::register_controls` does **not** register it,
/// the first asymmetry between the two Apple arms, recorded in that table's
/// doc). The
/// `debug_assert!` below checks this registration against all three tables at
/// runtime; `crate::controls::tests`'
/// `every_register_controls_registers_exactly_its_kind_tables` is the
/// host-visible half, reading all three arms' sources.
///
/// Registration stays explicit and central by design: `inventory`-style
/// link-time discovery is banned here, which matters even more on this
/// arm, where `lto = "fat"` +
/// `strip = "symbols"` is the shipping configuration.
pub