跳到主要内容

设计路由框架

问题

如何设计一个 iOS 路由框架?

答案

架构

核心实现

class Router {
static let shared = Router()
private var routes: [String: (RouteParams) -> UIViewController?] = [:]
private var interceptors: [RouteInterceptor] = []

// 注册
func register(_ pattern: String, handler: @escaping (RouteParams) -> UIViewController?) {
routes[pattern] = handler
}

// 跳转
func navigate(to url: String, from: UIViewController? = nil) {
guard let parsed = parse(url) else { return }

// 执行拦截器
for interceptor in interceptors {
if !interceptor.shouldProceed(route: parsed) {
interceptor.onIntercept(route: parsed, from: from)
return
}
}

guard let handler = routes[parsed.pattern],
let vc = handler(parsed.params) else { return }

let source = from ?? topViewController()
source?.navigationController?.pushViewController(vc, animated: true)
}
}

// 登录拦截器
struct LoginInterceptor: RouteInterceptor {
func shouldProceed(route: ParsedRoute) -> Bool {
if route.requiresAuth && !UserManager.shared.isLoggedIn {
return false
}
return true
}

func onIntercept(route: ParsedRoute, from: UIViewController?) {
Router.shared.navigate(to: "myapp://login", from: from)
}
}

注册方式

方式说明
手动注册Router.register(...)
自动注册(ObjC)+load 中注册
注解 + 代码生成Swift Macro / SourceKit

常见面试问题

Q1: 路由框架如何支持 SwiftUI?

答案:SwiftUI 使用 NavigationStack + NavigationPath,路由框架返回 AnyView 而非 UIViewController,或者通过枚举 Route 类型驱动导航。

相关链接