SwiftUI Frontend
MeroKitUI is an optional SwiftUI layer that ships alongside the core SDK — an
@MainActor observable MeroClient plus ready-made views. It’s the native
analog of mero-react’s MeroProvider/useMero + LoginModal: wire it in and
you get login → home routing on auth state for free.
import MeroKit // core SDKimport MeroKitUI // SwiftUI frontend(Add the MeroKitUI library product alongside MeroKit — see install.)
Drop-in app
Section titled “Drop-in app”MeroRootView routes between LoginView and HomeView based on
client.isAuthenticated. Inject a MeroClient via .environmentObject:
import MeroKitUIimport SwiftUI
@mainstruct MyApp: App { @StateObject private var client = MeroClient()
var body: some Scene { WindowGroup { MeroRootView(callbackScheme: "myapp") // Cloud sign-in ⇄ Home .environmentObject(client) } }}MeroClient
Section titled “MeroClient”An @MainActor public final class MeroClient: ObservableObject wrapping a Mero.
Bind its published state directly in your own views.
Published state (read-only from views):
@Published public private(set) var isAuthenticated: Bool@Published public private(set) var isLoading: Bool@Published public private(set) var nodeURL: String@Published public private(set) var username: String@Published public private(set) var errorMessage: String?@Published public private(set) var lastRpcResult: String?// Cloud session@Published public private(set) var account: String?@Published public private(set) var relayURL: String?@Published public private(set) var isSignedInWithoutRelay: Bool@Published public private(set) var cloudNote: String?public private(set) var connection: CloudConnection?Methods (errors surface via errorMessage, so these don’t throw):
public init(session: URLSession? = nil, tokenStore: @escaping @Sendable () -> any TokenStore = { MemoryTokenStore() }, cloud: CloudSignIn? = nil, // Keychain-backed by default webAuthenticator: (any WebAuthenticating)? = nil) // the system auth sheet by default
func signInWithCloud(callbackScheme: String) async // e.g. "myapp" → myapp://enrolfunc signInWithCloud(callback: CloudCallback) async // .https(host:path:) for a Universal Linkfunc handleEnrolmentCallback(_ url: URL) async -> Boolfunc restoreCloudSession() async -> Boolfunc login(nodeURL: String, username: String, password: String) async // development nodes onlyfunc runSampleRpc(contextId: String, method: String) asyncfunc logout() asyncUse it in your own SwiftUI view without the bundled screens:
struct SignInView: View { @EnvironmentObject private var client: MeroClient
var body: some View { VStack { Button("Continue with Calimero") { Task { await client.signInWithCloud(callbackScheme: "myapp") } } if let error = client.errorMessage { Text(error).foregroundStyle(.red) } } .disabled(client.isLoading) }}Bundled views
Section titled “Bundled views”All three are public Views that read the MeroClient from
@EnvironmentObject:
| View | Purpose |
|---|---|
MeroRootView(callbackScheme:) |
restores a stored session; routes LoginView ⇄ HomeView; handles onOpenURL |
LoginView(callbackScheme:) |
one “Continue with Calimero” button → client.signInWithCloud(...) |
HomeView(demoContextId:demoMethod:) |
signed-in screen: session info, demo RPC, logout |