架构
站内跳转不必先绕一层 URL
URL 是给外部和动态开关用的。App 里面的调用,用带类型的方法更清楚。
很多路由把所有跳转都写成 open("app://detail?id=1")。App 自己调用自己时,多了一次解析,参数还失去类型。详情页要一个字符串 id,编译器看不出来,只能靠文档。
内外分开
内部直接调用一个方法,参数写在方法上。外部链接、推送、活动配置先解析成同样的参数,再调用这个方法。解析只放在入口。按钮和别的模块不走字符串。
enum AppRoute {
case detail(id: String)
}
protocol AppRouting: AnyObject {
func open(_ route: AppRoute)
}
func open(url: URL, router: AppRouting) {
guard let parts = URLComponents(url: url, resolvingAgainstBaseURL: false),
parts.host == "detail",
let id = parts.queryItems?.first(where: { $0.name == "id" })?.value,
!id.isEmpty else { return }
router.open(.detail(id: id))
}
路由方法集中放,会让所有模块都去改同一个类型。可以按模块拆成扩展或各自的路由类型,由 App 组装。这样改详情参数时,编译器能指出调用处。
如果产品要求任意页面都能在原生和网页之间切换,再把 URL 做成统一入口。那是动态路由的需求,不是每个工程的默认形态。没有这个需求时,类型安全的内部路由更不容易把页面调丢。