Skip to content

Commit 8c84fc3

Browse files
author
wxlpp
committed
WIP: 弃用 URLError 实现自定义 Error 和 Error 处理器
1 parent f8e30c9 commit 8c84fc3

14 files changed

+254
-235
lines changed

RouteError.swift

Lines changed: 0 additions & 8 deletions
This file was deleted.

RouteResponse.swift

Lines changed: 0 additions & 8 deletions
This file was deleted.

RouterParameters.swift

Lines changed: 0 additions & 8 deletions
This file was deleted.

Source/RouteErrorHandling.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// RouteErrorHandler.swift
2+
// RouteErrorHandling.swift
33
// UIRouter
44
//
55
// Created by wxlpp on 2021/5/1.
@@ -13,7 +13,7 @@ public protocol RouteErrorHandling {
1313
func handleCustomError(_ error: Error)
1414
}
1515

16-
extension RouteErrorHandling {
16+
public extension RouteErrorHandling {
1717
func handle(error: Error) {
1818
switch error {
1919
case let rooError as RouteError:

Source/RouteInterceptor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// InterceptorType.swift
2+
// RouteInterceptor.swift
33
// UIRouter
44
//
55
// Created by wxlpp on 2021/5/1.

Source/RouteResponse.swift

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//
2+
// RouteResponse.swift
3+
// UIRouter
4+
//
5+
// Created by wxlpp on 2021/5/2.
6+
//
7+
8+
import UIKit
9+
10+
public final class RouteResponse {
11+
var viewController: UIViewController?
12+
13+
private let url: URLComponentsConvertible
14+
15+
init(url: URLComponentsConvertible) {
16+
self.url = url
17+
}
18+
19+
func asyncGetViewController(_ completionHandler: @escaping RouteCompletionHandler<UIViewController>) {
20+
if let vc = viewController {
21+
completionHandler(.success(vc))
22+
return
23+
}
24+
UIViewControllerRouter.shared.route(url: url) { result in
25+
switch result {
26+
case .success(let vc):
27+
self.viewController = vc
28+
case .failure(let error):
29+
UIViewControllerRouter.shared.errorHandler?.handle(error: error)
30+
}
31+
completionHandler(result)
32+
}
33+
}
34+
35+
private func getVisibleViewController() -> UIViewController? {
36+
let keyWindow: UIWindow?
37+
if #available(iOS 13.0.0, *) {
38+
keyWindow = UIApplication.shared.connectedScenes
39+
.filter({$0.activationState == .foregroundActive})
40+
.map({$0 as? UIWindowScene})
41+
.compactMap({$0})
42+
.first?.windows
43+
.filter(\.isKeyWindow).first
44+
} else {
45+
keyWindow = UIApplication.shared.keyWindow
46+
}
47+
return keyWindow?.rootViewController?.visibleViewController()
48+
}
49+
50+
public func push(by root: UIViewController? = nil, animated: Bool = true, completionHandler: RouteCompletionHandler<UIViewController>? = nil) {
51+
if let vc = self.viewController {
52+
let root = root ?? self.getVisibleViewController()
53+
root?.navigationController?.pushViewController(vc, animated: animated)
54+
completionHandler?(.success(vc))
55+
return
56+
}
57+
asyncGetViewController { result in
58+
switch result {
59+
case .success(let vc):
60+
let root = root ?? self.getVisibleViewController()
61+
root?.navigationController?.pushViewController(vc, animated: animated)
62+
completionHandler?(.success(vc))
63+
case .failure(let error):
64+
completionHandler?(.failure(error))
65+
}
66+
}
67+
}
68+
69+
public func present(by root: UIViewController? = nil, animated: Bool = true, completionHandler: RouteCompletionHandler<UIViewController>? = nil) {
70+
if let vc = self.viewController {
71+
let root = root ?? self.getVisibleViewController()
72+
root?.present(vc, animated: animated, completion: {
73+
completionHandler?(.success(vc))
74+
})
75+
return
76+
}
77+
asyncGetViewController { result in
78+
switch result {
79+
case .success(let vc):
80+
let root = root ?? self.getVisibleViewController()
81+
root?.present(vc, animated: animated, completion: {
82+
completionHandler?(.success(vc))
83+
})
84+
case .failure(let error):
85+
completionHandler?(.failure(error))
86+
}
87+
}
88+
}
89+
90+
public func presentWithNavigationController<N: UINavigationController>(_ type: N.Type, by root: UIViewController? = nil, animated: Bool = true, completionHandler: RouteCompletionHandler<UIViewController>? = nil) {
91+
if let vc = self.viewController {
92+
let root = root ?? self.getVisibleViewController()
93+
root?.present(type.init(rootViewController: vc), animated: animated, completion: {
94+
completionHandler?(.success(vc))
95+
})
96+
return
97+
}
98+
asyncGetViewController { result in
99+
switch result {
100+
case .success(let vc):
101+
let root = root ?? self.getVisibleViewController()
102+
root?.present(type.init(rootViewController: vc), animated: animated, completion: {
103+
completionHandler?(.success(vc))
104+
})
105+
case .failure(let error):
106+
completionHandler?(.failure(error))
107+
}
108+
}
109+
}
110+
}

Source/Router.swift

Lines changed: 7 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ public class UIViewControllerRouter {
4242

4343
static let shared = UIViewControllerRouter()
4444
private let urlRouter = URLRouter<UIViewController>()
45-
private var interceptors: [InterceptorType] = []
46-
private(set) var errorInterceptor = ErrorInterceptor()
45+
private var interceptors: [RouteInterceptor] = []
46+
private(set) var errorHandler: RouteErrorHandling?
4747
private var lock = pthread_rwlock_t()
4848

4949
init() {
@@ -57,7 +57,7 @@ public class UIViewControllerRouter {
5757

5858
func autoRegisterIfNeed() {
5959
if isNeedAutoRegister {
60-
DispatchQueue.init(label: "com.router.register").async {
60+
DispatchQueue(label: "com.router.register").async {
6161
self.registerIfNeed()
6262
}
6363
}
@@ -88,7 +88,7 @@ public class UIViewControllerRouter {
8888
pthread_rwlock_unlock(&lock)
8989
}
9090

91-
func handleInterceptor(interceptors: [InterceptorType], components: URLComponents, completionHandler: @escaping RouteCompletionHandler<UIViewController>) {
91+
func handleInterceptor(interceptors: [RouteInterceptor], components: URLComponents, completionHandler: @escaping RouteCompletionHandler<UIViewController>) {
9292
if interceptors.isEmpty {
9393
return
9494
}
@@ -129,125 +129,13 @@ public class UIViewControllerRouter {
129129
}
130130
}
131131

132-
public func register<T: InterceptorType>(interceptors: [T]) {
132+
public func register(interceptors: [RouteInterceptor]) {
133133
let last = self.interceptors.removeLast()
134134
self.interceptors.append(contentsOf: interceptors)
135135
self.interceptors.append(last)
136136
}
137-
138-
public func registerErrorInterceptors(_ interceptor: ErrorInterceptor) {
139-
self.errorInterceptor = interceptor
140-
}
141-
}
142-
143-
public final class UIRouter {
144-
private var viewController: UIViewController?
145-
146-
private let url: URLComponentsConvertible
147-
148-
init(url: URLComponentsConvertible) {
149-
self.url = url
150-
}
151-
152-
func asyncGetViewController(_ completionHandler: @escaping RouteCompletionHandler<UIViewController>) {
153-
if let vc = viewController {
154-
completionHandler(.success(vc))
155-
return
156-
}
157-
UIViewControllerRouter.shared.route(url: url) { result in
158-
switch result {
159-
case .success(let vc):
160-
self.viewController = vc
161-
case .failure(let error):
162-
UIViewControllerRouter.shared.errorInterceptor.handle(error: error)
163-
}
164-
completionHandler(result)
165-
}
166-
}
167-
168-
private func getVisibleViewController() -> UIViewController? {
169-
let keyWindow: UIWindow?
170-
if #available(iOS 13.0.0, *) {
171-
keyWindow = UIApplication.shared.connectedScenes
172-
.filter({$0.activationState == .foregroundActive})
173-
.map({$0 as? UIWindowScene})
174-
.compactMap({$0})
175-
.first?.windows
176-
.filter(\.isKeyWindow).first
177-
} else {
178-
keyWindow = UIApplication.shared.keyWindow
179-
}
180-
return keyWindow?.rootViewController?.visibleViewController()
181-
}
182-
183-
public func push(by root: UIViewController? = nil, animated: Bool = true, completionHandler: RouteCompletionHandler<UIViewController>? = nil) {
184-
asyncGetViewController { result in
185-
switch result {
186-
case .success(let vc):
187-
let root = root ?? self.getVisibleViewController()
188-
root?.navigationController?.pushViewController(vc, animated: animated)
189-
completionHandler?(.success(vc))
190-
case .failure(let error):
191-
completionHandler?(.failure(error))
192-
}
193-
}
194-
}
195-
196-
public func present(by root: UIViewController? = nil, animated: Bool = true, completionHandler: RouteCompletionHandler<UIViewController>? = nil) {
197-
asyncGetViewController { result in
198-
switch result {
199-
case .success(let vc):
200-
let root = root ?? self.getVisibleViewController()
201-
root?.present(vc, animated: animated, completion: {
202-
completionHandler?(.success(vc))
203-
})
204-
case .failure(let error):
205-
completionHandler?(.failure(error))
206-
}
207-
}
208-
}
209-
210-
public func presentWithNavigationController<N: UINavigationController>(_ type: N.Type, by root: UIViewController? = nil, animated: Bool = true, completionHandler: RouteCompletionHandler<UIViewController>? = nil) {
211-
asyncGetViewController { result in
212-
switch result {
213-
case .success(let vc):
214-
let root = root ?? self.getVisibleViewController()
215-
root?.present(type.init(rootViewController: vc), animated: animated, completion: {
216-
completionHandler?(.success(vc))
217-
})
218-
case .failure(let error):
219-
completionHandler?(.failure(error))
220-
}
221-
}
222-
}
223-
}
224-
225-
public extension UIApplication {
226-
227-
var router: UIViewControllerRouter {
228-
.shared
229-
}
230-
231-
@inline(__always)
232-
func route(url: URLComponentsConvertible) -> UIRouter {
233-
UIRouter(url: url)
234-
}
235-
}
236137

237-
extension UIViewController {
238-
func visibleViewController() -> UIViewController? {
239-
if let presentedViewController = self.presentedViewController {
240-
return presentedViewController.visibleViewController()
241-
}
242-
if let navigationController = self as? UINavigationController {
243-
return navigationController.visibleViewController
244-
}
245-
if let tabBarController = self as? UITabBarController {
246-
return tabBarController.selectedViewController?.visibleViewController()
247-
}
248-
if isViewLoaded {
249-
return self
250-
}
251-
return nil
138+
public func registerErrorHandler(_ handler: RouteErrorHandling) {
139+
errorHandler = handler
252140
}
253141
}

Source/RouterParameters.swift

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//
2+
// RouterParameters.swift
3+
// UIRouter
4+
//
5+
// Created by wxlpp on 2021/5/2.
6+
//
7+
8+
import Foundation
9+
/// 路由参数集合
10+
///
11+
///
12+
/// let parameters: RouterParameters = [URLQueryItem(name: "id", value: "0123456"),
13+
/// URLQueryItem(name: "name", value: "wxlpp")]
14+
/// let id: Int! = parameters.get("id")
15+
/// print(id)
16+
/// // Prints "0123456"
17+
/// let name = parameters.get("name", as: String.self)
18+
/// print(name)
19+
/// // Prints "wxlpp"
20+
///
21+
public typealias RouterParameters = [URLQueryItem]
22+
23+
public extension RouterParameters {
24+
25+
/// 将路由参数转为字典集合
26+
func toDictionary() -> [String: String] {
27+
var dic: [String: String] = [:]
28+
for parameter in self {
29+
dic.updateValue(parameter.value ?? "", forKey: parameter.name)
30+
}
31+
return dic
32+
}
33+
34+
/// 获取
35+
/// - Parameters:
36+
/// - name: 参数名称
37+
/// - : 参数类型,需要符合`LosslessStringConvertible`协议
38+
/// - Returns: 返回找到的参数,不存在返回 nil
39+
func get<T>(_ name: String, as _: T.Type = T.self) -> T? where T: LosslessStringConvertible {
40+
first(where: { $0.name == name })?.value.flatMap(T.init)
41+
}
42+
43+
/// 添加参数
44+
/// - Parameters:
45+
/// - value: 参数
46+
/// - name: 名称
47+
mutating func set<T>(_ value: T?, to name: String) where T: CustomStringConvertible {
48+
append(URLQueryItem(name: name, value: value?.description))
49+
}
50+
}

0 commit comments

Comments
 (0)