You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS中Voyager KMP的DeepLink实现:Swift代码关联及导航问询

iOS中URL Scheme与Voyager导航的整合方案

一、创建并关联AppDelegate到SwiftUI应用

由于你使用的是SwiftUI的@main入口结构,需要通过UIApplicationDelegateAdaptor将自定义的AppDelegate与应用关联,从而处理URL Scheme的回调:

  1. 创建AppDelegate类
import UIKit

class AppDelegate: UIResponder, UIApplicationDelegate {
    // 用于和Voyager通信的桥接实例
    private let navigationBridge = VoyagerNavigationBridge()

    func application(
        _ app: UIApplication,
        open url: URL,
        options: [UIApplication.OpenURLOptionsKey : Any] = [:]
    ) -> Bool {
        guard let scheme = url.scheme,
              scheme.localizedCaseInsensitiveCompare("com.myApp") == .orderedSame,
              let screenKey = url.host else {
            return false
        }

        // 解析URL中的参数
        var parameters: [String: String] = [:]
        URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.forEach {
            parameters[$0.name] = $0.value
        }

        // 触发Voyager导航
        navigationBridge.navigateToScreen(screenKey, parameters: parameters)
        return true
    }
}
  1. 在SwiftUI入口中关联AppDelegate
    修改你的iOSApp结构,添加UIApplicationDelegateAdaptor属性:
@main
struct iOSApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

二、实现Swift与Voyager的导航通信

Voyager的导航逻辑在Kotlin Compose中,需要建立跨语言通信桥接,将Swift侧的导航指令传递到Voyager的Navigator:

1. 在Kotlin中创建导航管理类

创建一个全局可访问的导航管理器,用于持有Voyager的Navigator实例,并提供可被Swift调用的导航方法:

import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.Navigator

// 全局导航管理器,负责处理跨语言导航请求
object VoyagerNavigationManager {
    private var navigator: Navigator? = null

    // 保存Voyager的Navigator实例
    fun attachNavigator(nav: Navigator) {
        navigator = nav
    }

    // 根据屏幕标识和参数执行导航
    fun navigateTo(screenKey: String, parameters: Map<String, String>) {
        val targetScreen = when(screenKey) {
            "list" -> ListScreen() // 你的初始列表页
            "detail" -> DetailScreen(itemId = parameters["id"] ?: "") // 示例详情页,根据参数传递数据
            // 在这里添加其他屏幕的映射关系
            else -> ListScreen() // 默认 fallback 页面
        }
        navigator?.push(targetScreen)
    }
}

// 桥接类,提供Objective-C兼容的接口,让Swift可以调用
import Foundation

@ObjC
class VoyagerNavigationBridge: NSObject {
    @ObjC
    func navigateToScreen(_ screenKey: String, parameters: [String: String]) {
        VoyagerNavigationManager.navigateTo(screenKey, parameters)
    }
}

2. 在Compose App中关联Navigator

修改你的App Composable,将Voyager的Navigator实例绑定到导航管理器:

import cafe.adriel.voyager.navigator.Navigator
import cafe.adriel.voyager.navigator.currentScreen

@Composable 
fun App() {
    Navigator(ListScreen()) { navigator ->
        // 将Navigator实例绑定到全局管理器
        VoyagerNavigationManager.attachNavigator(navigator)
        // 渲染当前屏幕
        currentScreen()
    }
}

3. 更新MainViewController

调整Kotlin的MainViewController,确保Compose环境正确初始化:

import androidx.compose.ui.platform.ComposeUIViewController

fun MainViewController() = ComposeUIViewController {
    App()
}

关键说明

  • 屏幕映射:在VoyagerNavigationManager的navigateTo方法中,你需要根据实际的业务场景,补充screenKey到对应Screen类的映射逻辑,确保参数正确传递到目标页面。
  • 线程安全:由于导航操作必须在主线程执行,Voyager内部已经处理了主线程调度,无需额外处理。
  • 参数解析:Swift侧解析URL参数后,会以字典形式传递到Kotlin,你可以根据页面需求提取并使用这些参数。

内容的提问来源于stack exchange,提问作者Ghasem Shirdel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:09:56