iOS
An Objective-C library for iOS 15 and later that works with and without ARC. Source: iOS/StashNative/Sources.
Structure
flowchart TB
Facade[StashNative] --> Session[StashCardSession]
Session --> Card[Card view controller]
Session --> Web[WKWebView]
Session --> Safari[SFSafariViewController]
Card --> Module[Module content]
The facade owns the active session. The session owns presentation state, the WebView, Safari, and event delivery; view controllers handle layout. Events from a closed session are ignored.
| File | Responsibility |
|---|---|
include/StashNative.h | Public API |
StashNative.m | Facade and open checks |
StashNativeInternal.m | Session, bridge messages, events, loading timers |
StashNativeCard*.m | Card layout, sheet detents, keyboard, gestures |
StashNativeOrientation.m | Portrait presentation |
StashNativeViewUtils.m | Injected scripts and URL checks |
Presentation
- Every card is a form sheet from one
UISheetPresentationController, on iPhone, iPhone Duo, and iPad. - Compact layouts switch between resting and expanded detents; iOS 15 uses the system medium and large detents. Regular layouts on iPad use one centered form sheet.
- The keyboard expands the card until it closes.
- If the game dismisses the view controller that presented the card or Safari, the session ends with the matching dismissal event.
Portrait presentation
- iPhone only. The card opens in an SDK-owned window in the game’s scene.
- The SDK rotates that window and restores the game’s orientation before returning control and sending events.
- On first use, the SDK adds an orientation method to the app delegate, and on iOS 27+ to the scene delegate. The game’s orientation settings stay unchanged.
Modules
- Each optional module is its own target and Swift package product.
- A module implements a content contract that the core finds at runtime, so the core never links the module’s frameworks.
WebView
- Bridge calls arrive as WebKit script messages, from the top frame only.
- Handler names such as
stashNativementSuccessare compatibility names; pages depend on them. - Link previews, swipe navigation, pinch zoom, and bounce are off.
Threading and memory
- Open calls copy their arguments and continue on the main thread.
isCurrentlyPresentedandisPurchaseProcessingread main-thread state, so query them on the main thread.- The delegate is
weakunder ARC andassignwithout ARC, so the game keeps it alive. - Events that end a presentation run after teardown, so the game can open again from the callback. Payment events with
autoCloseoff run while the card stays open.