Custom URL SchemeのURL文字列をSwift上で使用できるようにパースするための構造体を考えたのでメモ。
想定URL形式: someApp://home/articleDetail?userId=100&articleId=200&searchText=hoge
Custom URL Scheme自体の実装はこちらを参照。
Custom URL Schemeでアプリ内の任意のページを表示する
// DeepLinkHierarchy.swift
struct DeepLinkHierarchy {
enum TabType: String {
case home // ※サンプルケース
case article // ※サンプルケース
case setting // ※サンプルケース
case myPage // ※サンプルケース
case none // ※サンプルケース
}
enum ScreenNameType: String {
case articleDetail
case archive
case changeAccount
case none
}
var tabType: TabType
var screenNameType: ScreenNameType
var query: DeepLinkQuery
init(host tabText: String, query queryText: String) {
tabType = TabType(rawValue: tabText) ?? .none
screenNameType = ScreenNameType(rawValue: path) ?? .none
query = DeepLinkQuery(queryText)
}
}
struct DeepLinkQuery {
var userId: Int? // ※サンプルプロパティ
var articleId: Int? // ※サンプルプロパティ
var searchText: String? // ※サンプルプロパティ
init(_ query: String) {
if let userIdText = query.getValue(by: "userId") {
userId = Int(userIdText)
}
if let articleIdText = query.getValue(by: "articleIdText") {
articleId = Int(articleIdText)
}
searchText = query.getValue(by: "searchText")
}
}
private extension String {
func getValue(by key: String) -> String? {
return components(separatedBy: "&")
.map({ $0.components(separatedBy: "=") })
.first(where: { $0.first == key })?[1]
}
}
TabType
と命名しているのは、UITabBarを利用している前提のもと、どのタブをルートとしておくかの判定に利用する想定とした。
また、ルートタブを指定しつつ、遷移先画面をScreenNameType
で判別する。
// AppDelegate.swift
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
let deepLinkHierarchy = DeepLinkHierarchy(host: url.host ?? "", query: url.query ?? "")
print("tabType: \(deepLinkHierarchy.tabType)")
print("UserId: \(deepLinkHierarchy.query.userId)")
print("articleId: \(deepLinkHierarchy.query.articleId)")
print("searchText: \(deepLinkHierarchy.query.searchText)")
return true
}
ログアウトプット
tabType: home
UserId: Optional(100)
articleId: Optional(200)
searchText: Optional("hoge")