Application setup and DI
Configure services, configuration, logging, the root shell, lifecycle callbacks, and app-wide appearance.
Every SkeleKit app starts with SkeleApplication.CreateBuilder(). The builder collects services, page registrations, app-wide settings, and exactly one root shell before creating the application.
Build() is supplied by the page source generator. It applies generated [Page] registrations, then creates the application and service provider. Run(args) starts the native iOS main loop.
Choose a shell
Configure one of the following:
SinglePage<TView>()hosts one page without navigation chrome.Stack<TView>()creates a navigation controller with the given root page.Tabs(...)gives every primary tab its own navigation stack.SplitView(...)arranges two or three navigation stacks in a native split view.
Calling none of them is an error. The shell is app-level structure; individual pages can still present modals and use the system services.
See tabs and sidebar for the tab-shell builder, split views for column layouts, and navigation stacks for page-to-page navigation.
Services
UseServices exposes the normal Microsoft.Extensions.DependencyInjection service collection. Use singleton and transient registrations as usual. SkeleKit does not create a dependency-injection scope per page or navigation operation, so a scoped service resolved from the app's root provider effectively lives with that provider; do not use scoped lifetime when you expect page-local state.
SkeleKit adds these services when the application is built:
INavigatorfor navigation stacks, modals and Safari, tabs, and dialogs.ISplitViewfor split view column visibility and collapse state.ISharerfor the system share sheet.ISystemPickerfor photos and files.IHapticsfor impact, selection, notification, and custom feedback.IMailerfor the system mail composer.
Every View exposes the same services through its protected Navigator, Sharer, SystemPicker, Haptics, and Mailer properties. Use those when an interaction belongs to view code, including custom controls, collection templates, and tab accessories.
Registered ViewModels receive their dependencies through ordinary constructors. A typed page then receives its ViewModel:
The built provider is available through SkeleApplication.Current.Services after startup. Prefer the protected View properties in view code and constructor injection everywhere else. Resolve application-specific services directly when app-level accessory views or callbacks are created outside page construction.
Configuration and options
ConfigureAppConfiguration adds providers to one shared IConfiguration instance. SkeleKit does not choose a source; the app can use JSON, in-memory values, remote configuration, or any other Microsoft configuration provider.
Application services should normally consume the typed options:
Inject IConfiguration directly only when a service needs arbitrary sections or keys. Configuration providers and options binding extensions come from their corresponding Microsoft packages; for the example above, those are Microsoft.Extensions.Configuration.Json and Microsoft.Extensions.Options.ConfigurationExtensions.
Logging
SkeleKit registers Microsoft logging and sends its own diagnostics through ILogger. Add the providers and filters the app needs with ConfigureLogging:
SkeleKit does not add an output provider by default. AddSimpleConsole requires Microsoft.Extensions.Logging.Console; other providers, including Apple or rolling-file providers, can be added in the same callback. Application services receive ILogger<T> through constructor injection.
Lifecycle
Application lifecycle services complement the per-page appearance callbacks. Their methods are optional and may complete synchronously or asynchronously:
UseLifecycle<T>() registers T as a singleton in the same dependency-injection container used by UseServices. Lifecycle services may use constructor injection and can also be resolved by their concrete type.
StartAsync runs once after SkeleApplication.Current is assigned and completes before UIKit starts. It can load data and set SkeleKit application properties such as Theme.Appearance and Theme.Tint, but it should stay short and must not access UIKit objects. Foreground services run in registration order. Background and stopping services run in reverse registration order.
UIKit does not wait for asynchronous foreground, background, or stopping work. Keep these transitions short, save important state as it changes, and treat StopAsync as best-effort: iOS may terminate a suspended application without sending a stopping notification.
Appearance
Theme.Appearance sets the initial window appearance:
The running app can switch it later through SkeleApplication.Current.Theme.Appearance. System follows the device setting. Light and Dark set UIKit's override on every connected application window. Semantic Colors continue to resolve through UIKit for the selected appearance.
Tint
Theme.Tint supplies the inherited accent color for windows, navigation chrome, and controls:
Changing SkeleApplication.Current.Theme.Tint reapplies it to visible page hosts and app-level tab accessories. The transition animates over a short duration unless the user has enabled Reduce Motion. A view or page can still set a more specific Tint or BarTint.
Theme, styles and image loading
UseTheme also carries the app-wide appearance defaults pages inherit: NavigationTitleStyle, TopScrollEdgeStyle, and TabBarMinimize. UseStyles registers reusable and implicit styles, while UseImageLoader replaces the default remote image loader. See styles and themes, tabs and sidebar, and Image custom loading for their full setup.