├── .gitattributes
├── .gitignore
├── .jazzy.yaml
├── .swiftformat
├── Example
├── .gitignore
├── Example.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── Podfile
├── Podfile.lock
├── Submodule
│ ├── LICENSE
│ ├── Source
│ │ └── SubViewController.swift
│ ├── Submodule.podspec
│ └── UserProfileViewController.swift
├── shell.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── shell.xcscheme
└── shell
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ErrorDetailsViewController.swift
│ ├── Info.plist
│ ├── MainViewController.swift
│ ├── RouteErrorHandler.swift
│ └── SceneDelegate.swift
├── LICENSE
├── Package.swift
├── README.md
├── Source
├── Core
│ ├── PathComponent.swift
│ ├── Routable.swift
│ ├── Route.swift
│ ├── RouteError.swift
│ ├── RouteErrorHandling.swift
│ ├── RouteInterceptor.swift
│ ├── RouteRequest.swift
│ ├── RouterParameters.swift
│ ├── UIApplication[Router].swift
│ ├── UIViewControllerRouter.swift
│ ├── URLComponentsConvertible.swift
│ └── URLRouter.swift
└── Web
│ └── WebInterceptor.swift
├── Tests
└── UIRouterTests
│ └── UIRouterTests.swift
├── UIRouter.podspec
├── docs
├── Classes.html
├── Classes
│ ├── RouteRequest.html
│ ├── UIViewControllerRouter.html
│ ├── URLRouter.html
│ └── WebInterceptor.html
├── Enums.html
├── Enums
│ ├── PathComponent.html
│ └── RouteError.html
├── Extensions.html
├── Extensions
│ ├── Array.html
│ ├── RouterParameters.html
│ ├── String.html
│ ├── UIApplication.html
│ ├── URL.html
│ └── URLComponents.html
├── Protocols.html
├── Protocols
│ ├── Routable.html
│ ├── RouteBase.html
│ ├── RouteErrorHandling.html
│ ├── RouteInterceptor.html
│ └── URLComponentsConvertible.html
├── Typealiases.html
├── badge.svg
├── css
│ ├── highlight.css
│ └── jazzy.css
├── docsets
│ ├── UIRouter.docset
│ │ └── Contents
│ │ │ ├── Info.plist
│ │ │ └── Resources
│ │ │ ├── Documents
│ │ │ ├── Classes.html
│ │ │ ├── Classes
│ │ │ │ ├── RouteRequest.html
│ │ │ │ ├── UIViewControllerRouter.html
│ │ │ │ ├── URLRouter.html
│ │ │ │ └── WebInterceptor.html
│ │ │ ├── Enums.html
│ │ │ ├── Enums
│ │ │ │ ├── PathComponent.html
│ │ │ │ └── RouteError.html
│ │ │ ├── Extensions.html
│ │ │ ├── Extensions
│ │ │ │ ├── Array.html
│ │ │ │ ├── RouterParameters.html
│ │ │ │ ├── String.html
│ │ │ │ ├── UIApplication.html
│ │ │ │ ├── URL.html
│ │ │ │ └── URLComponents.html
│ │ │ ├── Protocols.html
│ │ │ ├── Protocols
│ │ │ │ ├── Routable.html
│ │ │ │ ├── RouteBase.html
│ │ │ │ ├── RouteErrorHandling.html
│ │ │ │ ├── RouteInterceptor.html
│ │ │ │ └── URLComponentsConvertible.html
│ │ │ ├── Typealiases.html
│ │ │ ├── css
│ │ │ │ ├── highlight.css
│ │ │ │ └── jazzy.css
│ │ │ ├── img
│ │ │ │ ├── carat.png
│ │ │ │ ├── dash.png
│ │ │ │ ├── gh.png
│ │ │ │ └── spinner.gif
│ │ │ ├── index.html
│ │ │ ├── js
│ │ │ │ ├── jazzy.js
│ │ │ │ ├── jazzy.search.js
│ │ │ │ ├── jquery.min.js
│ │ │ │ ├── lunr.min.js
│ │ │ │ └── typeahead.jquery.js
│ │ │ └── search.json
│ │ │ └── docSet.dsidx
│ └── UIRouter.tgz
├── img
│ ├── carat.png
│ ├── dash.png
│ ├── gh.png
│ └── spinner.gif
├── index.html
├── js
│ ├── jazzy.js
│ ├── jazzy.search.js
│ ├── jquery.min.js
│ ├── lunr.min.js
│ └── typeahead.jquery.js
├── search.json
└── undocumented.json
└── log.png
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.rb linguist-language=Swift
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | Packages/
41 | Package.pins
42 | Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | # Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # npm
70 | node_modules/
71 | package-lock.json
72 | package.json
73 | .config
74 | # Accio dependency management
75 | Dependencies/
76 | .accio/
77 |
78 | # fastlane
79 | #
80 | # It is recommended to not store the screenshots in the git repo.
81 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
82 | # For more information about the recommended setup visit:
83 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
84 |
85 | fastlane/report.xml
86 | fastlane/Preview.html
87 | fastlane/screenshots/**/*.png
88 | fastlane/test_output
89 |
90 | # Code Injection
91 | #
92 | # After new code Injection tools there's a generated folder /iOSInjectionProject
93 | # https://github.com/johnno1962/injectionforxcode
94 |
95 | iOSInjectionProject/
96 | theme
97 |
--------------------------------------------------------------------------------
/.jazzy.yaml:
--------------------------------------------------------------------------------
1 | module: UIRouter
2 | sdk: iphone
3 | swift_build_tool: xcodebuild
4 | podspec: UIRouter.podspec
5 | module_version: 0.2.0.alpha
6 | clean: true
7 | theme: theme/fullwidth
--------------------------------------------------------------------------------
/.swiftformat:
--------------------------------------------------------------------------------
1 | --allman false
2 | --assetliterals visual-width
3 | --beforemarks
4 | --binarygrouping 4,8
5 | --categorymark "MARK: %c"
6 | --classthreshold 0
7 | --closingparen balanced
8 | --commas always
9 | --conflictmarkers reject
10 | --decimalgrouping 3,6
11 | --elseposition same-line
12 | --emptybraces no-space
13 | --enumthreshold 0
14 | --exponentcase lowercase
15 | --exponentgrouping disabled
16 | --extensionacl on-extension
17 | --extensionlength 0
18 | --extensionmark "MARK: - %t + %c"
19 | --fractiongrouping disabled
20 | --fragment false
21 | --funcattributes preserve
22 | --groupedextension "MARK: %c"
23 | --guardelse auto
24 | --header ignore
25 | --hexgrouping ignore
26 | --hexliteralcase lowercase
27 | --ifdef indent
28 | --importgrouping testable-last
29 | --indent 4
30 | --indentcase true
31 | --lifecycle
32 | --linebreaks lf
33 | --markextensions always
34 | --marktypes always
35 | --maxwidth none
36 | --modifierorder
37 | --nevertrailing
38 | --nospaceoperators
39 | --nowrapoperators
40 | --octalgrouping 4,8
41 | --operatorfunc no-space
42 | --organizetypes class,enum,struct
43 | --patternlet inline
44 | --ranges spaced
45 | --redundanttype inferred
46 | --self init-only
47 | --selfrequired
48 | --semicolons inline
49 | --shortoptionals always
50 | --smarttabs enabled
51 | --stripunusedargs closure-only
52 | --structthreshold 0
53 | --swiftversion 5.3
54 | --tabwidth 2
55 | --trailingclosures
56 | --trimwhitespace always
57 | --typeattributes preserve
58 | --typemark "MARK: - %t"
59 | --varattributes preserve
60 | --voidtype void
61 | --wraparguments preserve
62 | --wrapcollections before-first
63 | --wrapconditions preserve
64 | --wrapparameters preserve
65 | --wrapreturntype preserve
66 | --xcodeindentation disabled
67 | --yodaswap always
68 | --disable andOperator,blankLinesAtStartOfScope,linebreakAtEndOfFile,linebreaks,redundantBackticks,redundantLetError,spaceInsideBraces,spaceInsideGenerics,spaceInsideParens,trailingClosures,trailingCommas,wrap,wrapMultilineStatementBraces
69 | --enable isEmpty
70 |
--------------------------------------------------------------------------------
/Example/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | Packages/
41 | Package.pins
42 | Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # npm
70 | node_modules/
71 | package-lock.json
72 | package.json
73 | .config
74 | # Accio dependency management
75 | Dependencies/
76 | .accio/
77 |
78 | # fastlane
79 | #
80 | # It is recommended to not store the screenshots in the git repo.
81 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
82 | # For more information about the recommended setup visit:
83 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
84 |
85 | fastlane/report.xml
86 | fastlane/Preview.html
87 | fastlane/screenshots/**/*.png
88 | fastlane/test_output
89 |
90 | # Code Injection
91 | #
92 | # After new code Injection tools there's a generated folder /iOSInjectionProject
93 | # https://github.com/johnno1962/injectionforxcode
94 |
95 | iOSInjectionProject/
96 |
--------------------------------------------------------------------------------
/Example/Example.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '14.5'
2 | inhibit_all_warnings!
3 | install! 'cocoapods',
4 |
5 | :generate_multiple_pod_projects => true,
6 | :incremental_installation => true,
7 | :preserve_pod_file_structure => true,
8 | :warn_for_unused_master_specs_repo => false
9 |
10 | project 'shell.xcodeproj'
11 | workspace 'Example.xcworkspace'
12 |
13 | target 'shell' do
14 | use_frameworks!
15 | pod 'UIRouter/Web', :path => '../'
16 | pod 'Submodule', :path => 'Submodule/'
17 | end
18 |
19 | post_install do |installer|
20 | installer.pod_target_subprojects.flat_map { |p| p.targets }.each do |t|
21 | t.build_configurations.each do |c|
22 | if c.build_settings['IPHONEOS_DEPLOYMENT_TARGET'].to_f < 14.5
23 | c.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.5'
24 | end
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/Example/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Submodule (0.1.0):
3 | - UIRouter
4 | - UIRouter (0.2.0.alpha):
5 | - UIRouter/Core (= 0.2.0.alpha)
6 | - UIRouter/Core (0.2.0.alpha)
7 | - UIRouter/Web (0.2.0.alpha):
8 | - UIRouter/Core
9 |
10 | DEPENDENCIES:
11 | - Submodule (from `Submodule/`)
12 | - UIRouter/Web (from `../`)
13 |
14 | EXTERNAL SOURCES:
15 | Submodule:
16 | :path: Submodule/
17 | UIRouter:
18 | :path: "../"
19 |
20 | SPEC CHECKSUMS:
21 | Submodule: 4d6c30b294c43d33503985e348909fd7c4c02353
22 | UIRouter: f0fadcc043f620b846aa1feee97ea8803127f27f
23 |
24 | PODFILE CHECKSUM: 5387537adb0879783c29a9e30e3acc9630837f78
25 |
26 | COCOAPODS: 1.10.1
27 |
--------------------------------------------------------------------------------
/Example/Submodule/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Wang Xiaolong
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Example/Submodule/Source/SubViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SubViewController.swift
3 | // Submodule
4 | //
5 | // Created by wxlpp on 2021/5/1.
6 | //
7 |
8 | import UIKit
9 | import UIRouter
10 |
11 | public final class SubViewController: UIViewController {
12 | override public func viewDidLoad() {
13 | super.viewDidLoad()
14 | view.backgroundColor = .white
15 | }
16 |
17 | override public func viewWillAppear(_ animated: Bool) {
18 | super.viewWillAppear(animated)
19 | title = "Sub"
20 | }
21 | }
22 |
23 | // MARK: 路由
24 |
25 | extension SubViewController: Routable {
26 |
27 | public static func route(parameters: RouterParameters, object: Any?, completion: @escaping RouteCompletionHandler) {
28 | completion(.success(SubViewController()))
29 | }
30 |
31 | public static var paths: [String] {
32 | ["sub"]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Example/Submodule/Submodule.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod lib lint UIRouter.podspec' to ensure this is a
3 | # valid spec before submitting.
4 | #
5 | # Any lines starting with a # are optional, but their use is encouraged
6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
7 | #
8 |
9 | Pod::Spec.new do |s|
10 | s.name = 'Submodule'
11 | s.version = '0.1.0'
12 | s.summary = 'Submodule for Example.'
13 | s.description = <<-DESC
14 | TODO: Add long description of the pod here.
15 | DESC
16 |
17 | s.homepage = 'https://github.com/wxlpp/Submodule'
18 | s.license = { :type => 'MIT', :file => 'LICENSE' }
19 | s.author = { 'wxlpp' => 'wxlpp91@foxmail.com' }
20 | s.source = { :git => 'https://github.com/wxlpp/Submodule.git', :tag => s.version.to_s }
21 |
22 | s.ios.deployment_target = '9.0'
23 |
24 | s.source_files = 'Source/**/*'
25 | s.ios.frameworks = 'UIKit'
26 | s.dependency 'UIRouter'
27 | end
28 |
--------------------------------------------------------------------------------
/Example/Submodule/UserProfileViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserProfileViewController.swift
3 | // Submodule
4 | //
5 | // Created by wxlpp on 2021/5/1.
6 | //
7 |
8 | import UIKit
9 | import UIRouter
10 |
11 | public final class UserProfileViewController: UIViewController {}
12 |
13 | // MARK: 路由
14 |
15 | extension UserProfileViewController: Routable {
16 |
17 | public static var paths: [String] {
18 | ["user/profile/:id"]
19 | }
20 |
21 | public static func route(parameters: RouterParameters, object: Any?, completion: @escaping RouteCompletionHandler) {
22 | if let userID: String = parameters.get("userID") {
23 | completion(.success(UserProfileViewController()))
24 | } else {
25 | completion(.failure(RouteError.parameterValidationFailed(vcType: Self.self, name: "userID")))
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Example/shell.xcodeproj/xcshareddata/xcschemes/shell.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/Example/shell/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Example
4 | //
5 | // Created by wxlpp on 2021/5/1.
6 | //
7 |
8 | import UIKit
9 | import UIRouter
10 |
11 | @main
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
15 | application.router.autoRegisterIfNeed()
16 | application.router.register(interceptors: [WebInterceptor()])
17 | application.router.registerErrorHandler(RouteErrorHandler())
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Example/shell/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Example/shell/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Example/shell/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/shell/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Example/shell/ErrorDetailsViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ErrorDetailsViewController.swift
3 | // shell
4 | //
5 | // Created by wxlpp on 2021/5/1.
6 | //
7 |
8 | import UIKit
9 |
10 | class ErrorDetailsViewController: UITableViewController {
11 | let error: Error
12 | let errorDetails: [(key: String, value: String)]
13 |
14 | init(error: Error) {
15 | self.error = error
16 | if let localizedError = error as? LocalizedError {
17 | var list: [(key: String, value: String)] = []
18 | if let errorDescription = localizedError.errorDescription {
19 | list.append(("简述", errorDescription))
20 | }
21 | if let failureReason = localizedError.failureReason {
22 | list.append(("原因", failureReason))
23 | }
24 | if let helpAnchor = localizedError.helpAnchor {
25 | list.append(("解决", helpAnchor))
26 | }
27 | if let recoverySuggestion = localizedError.recoverySuggestion {
28 | list.append(("恢复", recoverySuggestion))
29 | }
30 | self.errorDetails = list
31 | } else {
32 | self.errorDetails = [("错误", error.localizedDescription)]
33 | }
34 | super.init(style: .insetGrouped)
35 | }
36 |
37 | @available(*, unavailable)
38 | required init?(coder: NSCoder) {
39 | fatalError("init(coder:) has not been implemented")
40 | }
41 |
42 | override func viewWillAppear(_ animated: Bool) {
43 | super.viewWillAppear(animated)
44 | title = "错误信息"
45 | }
46 |
47 | override func viewDidLoad() {
48 | super.viewDidLoad()
49 | tableView.allowsSelection = false
50 | tableView.register(UITableViewCell.classForCoder(), forCellReuseIdentifier: "cell")
51 | }
52 |
53 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
54 | errorDetails.count
55 | }
56 |
57 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
58 | let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
59 | var contentConfiguration = UIListContentConfiguration.subtitleCell()
60 | contentConfiguration.text = errorDetails[indexPath.row].key
61 | contentConfiguration.secondaryText = errorDetails[indexPath.row].value
62 | cell.contentConfiguration = contentConfiguration
63 | return cell
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Example/shell/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UIApplicationSupportsIndirectInputEvents
41 |
42 | UILaunchStoryboardName
43 | LaunchScreen
44 | UIRequiredDeviceCapabilities
45 |
46 | armv7
47 |
48 | UISupportedInterfaceOrientations
49 |
50 | UIInterfaceOrientationPortrait
51 | UIInterfaceOrientationLandscapeLeft
52 | UIInterfaceOrientationLandscapeRight
53 |
54 | UISupportedInterfaceOrientations~ipad
55 |
56 | UIInterfaceOrientationPortrait
57 | UIInterfaceOrientationPortraitUpsideDown
58 | UIInterfaceOrientationLandscapeLeft
59 | UIInterfaceOrientationLandscapeRight
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/Example/shell/MainViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainViewController.swift
3 | // shell
4 | //
5 | // Created by wxlpp on 2021/5/1.
6 | //
7 |
8 | import UIKit
9 | import UIRouter
10 | class MainViewController: UITableViewController {
11 | let routes = [
12 | (name: "SubModule", path: "sub"),
13 | (name: "Baidu", path: "https://www.baidu.com"),
14 | (name: "用户简介", path: "user/profile")
15 | ]
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 | tableView.register(UITableViewCell.classForCoder(), forCellReuseIdentifier: "cell")
20 | }
21 |
22 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
23 | routes.count
24 | }
25 |
26 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
27 | let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
28 | var contentConfiguration = UIListContentConfiguration.cell()
29 | contentConfiguration.text = routes[indexPath.row].name
30 | cell.contentConfiguration = contentConfiguration
31 | return cell
32 | }
33 |
34 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
35 | tableView.deselectRow(at: indexPath, animated: true)
36 | UIApplication.shared.route(url: routes[indexPath.row].path).push()
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Example/shell/RouteErrorHandler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RouteErrorHandler.swift
3 | // shell
4 | //
5 | // Created by wxlpp on 2021/5/1.
6 | //
7 |
8 | import UIRouter
9 |
10 | class RouteErrorHandler: RouteErrorHandling {
11 | func handleRouteError(_ error: RouteError) {
12 | #if DEBUG
13 | let vc = ErrorDetailsViewController(error: error)
14 | UIApplication.shared.route(viewcontroller: vc).presentWithNavigationController(UINavigationController.self)
15 | #else
16 | debugPrint(error.errorDescription)
17 | #endif
18 | }
19 |
20 | func handleCustomError(_ error: Error) {}
21 | }
22 |
--------------------------------------------------------------------------------
/Example/shell/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // Example
4 | //
5 | // Created by wxlpp on 2021/5/1.
6 | //
7 |
8 | import SwiftUI
9 | import UIKit
10 |
11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
12 |
13 | var window: UIWindow?
14 |
15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
16 | if let windowScene = scene as? UIWindowScene {
17 | let window = UIWindow(windowScene: windowScene)
18 | window.rootViewController = UINavigationController(rootViewController: MainViewController())
19 | self.window = window
20 | window.makeKeyAndVisible()
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Wang Xiaolong
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.4
2 | //
3 | // Package.swift
4 | // Copyright (c) 2021 Wang Xiaolong
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in all
14 | // copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | // SOFTWARE.
23 |
24 | import PackageDescription
25 |
26 | let package = Package(
27 | name: "UIRouter",
28 | platforms: [.iOS(.v9)],
29 | products: [
30 | .library(
31 | name: "UIRouter",
32 | targets: ["UIRouter"]
33 | ),
34 | ],
35 | targets: [
36 | .target(
37 | name: "UIRouter", path: "Source"
38 | ),
39 | .testTarget(
40 | name: "UIRouterTests",
41 | dependencies: ["UIRouter"]
42 | ),
43 | ],
44 | swiftLanguageVersions: [.v5]
45 | )
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | [](https://img.shields.io/cocoapods/v/UIRouter.svg)
3 | 
4 | 
5 | 
6 |
7 | UIRouter 是一个用Swift实现的路由解耦框架.
8 | [API文档](https://wxlpp.github.io/UIRouter/)
9 | ## 安装
10 |
11 | ### CocoaPods
12 |
13 | ```ruby
14 | pod 'UIRouter', '~> 0.2.0.alpha'
15 | ```
16 |
17 | ### Swift Package Manager
18 |
19 | ```swift
20 | dependencies: [
21 | .package(url: "https://github.com/wxlpp/UIRouter", .upToNextMajor(from: "0.2.0"))
22 | ]
23 | ```
24 | ## 使用
25 |
26 | ### 页面注册
27 |
28 | ```swift
29 | import UIKit
30 | import UIRouter
31 |
32 | @main
33 | class AppDelegate: UIResponder, UIApplicationDelegate {
34 |
35 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
36 | // 可以在此调用 autoRegisterIfNeed 进行页面预注册,否则会在第一次页面路由发生时进行注册
37 | application.router.autoRegisterIfNeed()
38 | // 注册拦截器,WebInterceptor 是一个默认实现的 htttp 协议拦截器
39 | application.router.register(interceptors: [WebInterceptor()])
40 | // 注册错误处理器进行错误处理
41 | application.router.registerErrorHandler(RouteErrorHandler())
42 | return true
43 | }
44 | }
45 |
46 | ```
47 |
48 | ```swift
49 | import UIKit
50 | import UIRouter
51 |
52 | public final class UserProfileViewController: UIViewController {}
53 |
54 | // MARK: 路由
55 |
56 | extension UserProfileViewController: Routable {
57 | public static var paths: [String] {
58 | ["user/profile/:id"]
59 | }
60 |
61 | public static func route(parameters: RouterParameters, object: Any?, completion: @escaping RouteCompletionHandler) {
62 | if let userID: String = parameters.get("userID") {
63 | completion(.success(UserProfileViewController()))
64 | } else {
65 | completion(.failure(RouteError.parameterValidationFailed(vcType: Self.self, name: "userID")))
66 | }
67 | }
68 | }
69 | ```
70 | ### 页面路由
71 | ```swift
72 | UIApplication.shared.route(url: "user/profile/123456?name=wxlpp").push()
73 | UIApplication.shared.route(url: "https://github.com/wxlpp/UIRouter").present()
74 | UIApplication.shared.route(url: "flutter://shop.com/home").presentWithNavigationController(UINavigationController.self)
75 | ```
76 | ### 错误拦截
77 | ```swift
78 | import UIRouter
79 |
80 | class RouteErrorHandler: RouteErrorHandling {
81 | func handleRouteError(_ error: RouteError) {
82 | #if DEBUG
83 | let vc = ErrorDetailsViewController(error: error)
84 | UIApplication.shared.route(viewcontroller: vc).presentWithNavigationController(UINavigationController.self)
85 | #else
86 | debugPrint(error.errorDescription)
87 | #endif
88 | }
89 |
90 | func handleCustomError(_ error: Error) {
91 | //这里对业务错误信息进行处理,比如用户鉴权失败弹出登录页面
92 | }
93 | }
94 | ```
--------------------------------------------------------------------------------
/Source/Core/PathComponent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PathComponent.swift
3 | //
4 | // Created by wxlpp on 2021/5/1.
5 | // Copyright © 2021 Wang Xiaolong. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | public enum PathComponent: ExpressibleByStringLiteral, CustomStringConvertible {
11 |
12 | case constant(String)
13 |
14 | case parameter(String)
15 |
16 | case anything
17 |
18 | case catchall
19 |
20 | public init(stringLiteral value: String) {
21 | if value.hasPrefix(":") {
22 | self = .parameter(.init(value.dropFirst()))
23 | } else if value == ":" {
24 | self = .anything
25 | } else if value == "*" {
26 | self = .catchall
27 | } else {
28 | self = .constant(value)
29 | }
30 | }
31 |
32 | public var description: String {
33 | switch self {
34 | case .anything: return ":"
35 | case .catchall: return "*"
36 | case .parameter(let name): return ":" + name
37 | case .constant(let constant): return constant
38 | }
39 | }
40 | }
41 |
42 | public extension Array where Element == PathComponent {
43 |
44 | var string: String {
45 | map(\.description).joined(separator: "/")
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Source/Core/Routable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Routable.swift
3 | // UIRouter
4 | //
5 | // Created by wxlpp on 2021/5/3.
6 | // Copyright © 2021 Wang Xiaolong. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public protocol RouteBase: UIViewController {
12 | static var paths: [String] { get }
13 | static func routeVC(parameters: RouterParameters, object: Any?, completion: @escaping RouteCompletionHandler)
14 | }
15 |
16 | /// 需要通过路由解耦的 `UIViewController` 实现此协议后,路由中心将会自动完成组件的注册
17 | public protocol Routable: RouteBase {
18 |
19 | /// 路由中心通过路由链接到指定 `UIViewController` 后由此回调进行页面构造
20 | /// - Parameters:
21 | /// - parameters: 由路由 `URL` 解析后传递的参数
22 | /// - object: 业务对象
23 | /// - completion: 验证参数后构造页面通过回调返回结果
24 | static func route(parameters: RouterParameters, object: Any?, completion: @escaping RouteCompletionHandler)
25 | }
26 |
27 | public extension Routable {
28 | static func routeVC(parameters: RouterParameters, object: Any?, completion: @escaping RouteCompletionHandler) {
29 | route(parameters: parameters, object: object) { result in
30 | completion(result.map { $0 as UIViewController })
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Source/Core/Route.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Route.swift
3 | //
4 | // Created by wxlpp on 2021/5/1.
5 | // Copyright © 2021 Wang Xiaolong. All rights reserved.
6 | //
7 |
8 | import UIKit
9 |
10 | /// 路由结果回调闭包
11 | public typealias RouteCompletionHandler = (Result) -> Void
12 | /// 路由处理闭包
13 | public typealias RouterHandler = (RouterParameters, Any?, @escaping RouteCompletionHandler) -> Void
14 |
15 | struct Route
34 |
35 |
36 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | Array Extension Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
Array
139 |
140 |
141 |
142 |
public extension Array where Element == PathComponent
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
162 |
163 | -
164 |
165 |
166 |
167 |
168 | string
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
Undocumented
177 |
178 |
179 |
180 |
Declaration
181 |
182 |
Swift
183 |
var string: String { get }
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/docs/Extensions/String.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | String Extension Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | String Extension Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
String
139 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | -
155 |
162 |
163 |
164 |
165 |
166 |
167 |
如果构造成功则返回一个 URLComponents
,否则抛出异常.
168 |
173 |
174 |
175 |
176 |
Declaration
177 |
178 |
Swift
179 |
public func asURLComponents() throws -> URLComponents
180 |
181 |
182 |
183 |
184 |
Return Value
185 |
构造成功的URLComponents
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/docs/Extensions/URL.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | URL Extension Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | URL Extension Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
URL
139 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | -
155 |
162 |
163 |
164 |
165 |
166 |
167 |
如果构造成功则返回一个 URLComponents
,否则抛出异常.
168 |
173 |
174 |
175 |
176 |
Declaration
177 |
178 |
Swift
179 |
public func asURLComponents() throws -> URLComponents
180 |
181 |
182 |
183 |
184 |
Return Value
185 |
构造成功的URLComponents
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/docs/Extensions/URLComponents.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | URLComponents Extension Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | URLComponents Extension Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
URLComponents
139 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | -
155 |
162 |
163 |
164 |
165 |
166 |
167 |
如果构造成功则返回一个 URLComponents
,否则抛出异常.
168 |
173 |
174 |
175 |
176 |
Declaration
177 |
178 |
Swift
179 |
public func asURLComponents() throws -> URLComponents
180 |
181 |
182 |
183 |
184 |
Return Value
185 |
构造成功的URLComponents
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/docs/Protocols/RouteInterceptor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | RouteInterceptor Protocol Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | RouteInterceptor Protocol Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
RouteInterceptor
139 |
140 |
141 |
142 |
public protocol RouteInterceptor
143 |
144 |
145 |
146 |
Undocumented
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 | -
156 |
163 |
164 |
165 |
166 |
167 |
168 |
Undocumented
169 |
170 |
171 |
172 |
Declaration
173 |
174 |
Swift
175 |
func handle(components: URLComponents, object: Any, completionHandler: @escaping RouteCompletionHandler<UIViewController?>)
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
193 |
194 |
195 |
196 |
--------------------------------------------------------------------------------
/docs/Protocols/URLComponentsConvertible.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | URLComponentsConvertible Protocol Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | URLComponentsConvertible Protocol Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
URLComponentsConvertible
139 |
140 |
141 |
142 |
public protocol URLComponentsConvertible
143 |
144 |
145 |
146 |
Types adopting the URLComponentsConvertible
protocol can be used to construct URLComponents
s, which can then be used to route.
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 | -
156 |
163 |
164 |
165 |
166 |
167 |
168 |
如果构造成功则返回一个 URLComponents
,否则抛出异常.
169 |
174 |
175 |
176 |
177 |
Declaration
178 |
179 |
Swift
180 |
func asURLComponents() throws -> URLComponents
181 |
182 |
183 |
184 |
185 |
Return Value
186 |
构造成功的URLComponents
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
202 |
203 |
204 |
205 |
--------------------------------------------------------------------------------
/docs/badge.svg:
--------------------------------------------------------------------------------
1 |
29 |
--------------------------------------------------------------------------------
/docs/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/docs/css/jazzy.css:
--------------------------------------------------------------------------------
1 | *, *:before, *:after {
2 | box-sizing: inherit; }
3 |
4 | body {
5 | margin: 0;
6 | background: #fff;
7 | color: #333;
8 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
9 | letter-spacing: .2px;
10 | -webkit-font-smoothing: antialiased;
11 | box-sizing: border-box; }
12 |
13 | h1 {
14 | font-size: 2rem;
15 | font-weight: 700;
16 | margin: 1.275em 0 0.6em; }
17 |
18 | h2 {
19 | font-size: 1.75rem;
20 | font-weight: 700;
21 | margin: 1.275em 0 0.3em; }
22 |
23 | h3 {
24 | font-size: 1.5rem;
25 | font-weight: 700;
26 | margin: 1em 0 0.3em; }
27 |
28 | h4 {
29 | font-size: 1.25rem;
30 | font-weight: 700;
31 | margin: 1.275em 0 0.85em; }
32 |
33 | h5 {
34 | font-size: 1rem;
35 | font-weight: 700;
36 | margin: 1.275em 0 0.85em; }
37 |
38 | h6 {
39 | font-size: 1rem;
40 | font-weight: 700;
41 | margin: 1.275em 0 0.85em;
42 | color: #777; }
43 |
44 | p {
45 | margin: 0 0 1em; }
46 |
47 | ul, ol {
48 | padding: 0 0 0 2em;
49 | margin: 0 0 0.85em; }
50 |
51 | blockquote {
52 | margin: 0 0 0.85em;
53 | padding: 0 15px;
54 | color: #858585;
55 | border-left: 4px solid #e5e5e5; }
56 |
57 | img {
58 | max-width: 100%; }
59 |
60 | a {
61 | color: #1890ff;
62 | text-decoration: none; }
63 | a:hover, a:focus {
64 | outline: 0;
65 | text-decoration: underline; }
66 | a.discouraged {
67 | text-decoration: line-through; }
68 | a.discouraged:hover, a.discouraged:focus {
69 | text-decoration: underline line-through; }
70 |
71 | table {
72 | background: #fff;
73 | width: 100%;
74 | border-collapse: collapse;
75 | border-spacing: 0;
76 | overflow: auto;
77 | margin: 0 0 0.85em; }
78 |
79 | tr:nth-child(2n) {
80 | background-color: #fbfbfb; }
81 |
82 | th, td {
83 | padding: 6px 13px;
84 | border: 1px solid #ddd; }
85 |
86 | pre {
87 | margin: 0 0 1.275em;
88 | padding: .85em 1em;
89 | overflow: auto;
90 | background: #f7f7f7;
91 | font-size: .85em;
92 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
93 |
94 | code {
95 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; }
96 |
97 | .item-container p > code, .item-container li > code, .top-matter p > code, .top-matter li > code {
98 | background: #f7f7f7;
99 | padding: .2em; }
100 | .item-container p > code:before, .item-container p > code:after, .item-container li > code:before, .item-container li > code:after, .top-matter p > code:before, .top-matter p > code:after, .top-matter li > code:before, .top-matter li > code:after {
101 | letter-spacing: -.2em;
102 | content: "\00a0"; }
103 |
104 | pre code {
105 | padding: 0;
106 | white-space: pre; }
107 |
108 | .content-wrapper {
109 | display: flex;
110 | flex-direction: column; }
111 | @media (min-width: 768px) {
112 | .content-wrapper {
113 | flex-direction: row; } }
114 | .header {
115 | display: flex;
116 | padding: 8px;
117 | font-size: 0.875em;
118 | background: #fff;
119 | color: #fff; }
120 |
121 | .header-col {
122 | margin: 0;
123 | padding: 0 8px; }
124 |
125 | .header-col--primary {
126 | flex: 1; }
127 |
128 | .header-link {
129 | color: #000000d9; }
130 |
131 | .header-icon {
132 | padding-right: 6px;
133 | vertical-align: -4px;
134 | height: 16px; }
135 |
136 | .breadcrumbs {
137 | font-size: 0.875em;
138 | padding: 8px 16px;
139 | margin: 0;
140 | background: #fbfbfb;
141 | border-bottom: 1px solid #ddd; }
142 |
143 | .carat {
144 | height: 10px;
145 | margin: 0 5px; }
146 |
147 | .navigation {
148 | order: 2; }
149 | @media (min-width: 768px) {
150 | .navigation {
151 | order: 1;
152 | width: 25%;
153 | max-width: 300px;
154 | padding-bottom: 64px;
155 | overflow: hidden;
156 | word-wrap: normal;
157 | background: #fff; } }
158 | .nav-groups {
159 | list-style-type: none;
160 | padding-left: 0; }
161 |
162 | .nav-group-name {
163 | padding: 8px 0 8px 16px; }
164 |
165 | .nav-group-name-link {
166 | color: #000000d9; }
167 |
168 | .nav-group-tasks {
169 | margin: 8px 0;
170 | padding: 0 0 0 8px; }
171 |
172 | .nav-group-task {
173 | font-size: 1em;
174 | list-style-type: none;
175 | white-space: nowrap; }
176 |
177 | .nav-group-task-link {
178 | color: #808080; }
179 |
180 | .main-content {
181 | order: 1; }
182 | @media (min-width: 768px) {
183 | .main-content {
184 | order: 2;
185 | flex: 1;
186 | padding-bottom: 60px; } }
187 | .section {
188 | padding: 0 32px; }
189 |
190 | .section-content {
191 | max-width: 834px;
192 | margin: 0 auto;
193 | padding: 16px 0; }
194 |
195 | .section-name {
196 | color: #666;
197 | display: block; }
198 | .section-name p {
199 | margin-bottom: inherit; }
200 |
201 | .declaration .highlight {
202 | overflow-x: initial;
203 | padding: 8px 0;
204 | margin: 0;
205 | background-color: transparent;
206 | border: none; }
207 |
208 | .task-group-section {
209 | border-top: 1px solid #ddd; }
210 |
211 | .task-group {
212 | padding-top: 0px; }
213 |
214 | .task-name-container a[name]:before {
215 | content: "";
216 | display: block; }
217 |
218 | .section-name-container {
219 | position: relative; }
220 | .section-name-container .section-name-link {
221 | position: absolute;
222 | top: 0;
223 | left: 0;
224 | bottom: 0;
225 | right: 0;
226 | margin-bottom: 0; }
227 | .section-name-container .section-name {
228 | position: relative;
229 | pointer-events: none;
230 | z-index: 1; }
231 | .section-name-container .section-name a {
232 | pointer-events: auto; }
233 |
234 | .item-container {
235 | padding: 0; }
236 |
237 | .item {
238 | padding-top: 8px;
239 | width: 100%;
240 | list-style-type: none; }
241 | .item a[name]:before {
242 | content: "";
243 | display: block; }
244 | .item .token, .item .direct-link {
245 | display: inline-block;
246 | text-indent: -20px;
247 | padding-left: 3px;
248 | margin-left: 20px;
249 | font-size: 1rem; }
250 | .item .declaration-note {
251 | font-size: .85em;
252 | color: #808080;
253 | font-style: italic; }
254 |
255 | .pointer-container {
256 | border-bottom: 1px solid #ddd;
257 | left: -23px;
258 | padding-bottom: 13px;
259 | position: relative;
260 | width: 110%; }
261 |
262 | .pointer {
263 | left: 21px;
264 | top: 7px;
265 | display: block;
266 | position: absolute;
267 | width: 12px;
268 | height: 12px;
269 | border-left: 1px solid #ddd;
270 | border-top: 1px solid #ddd;
271 | background: #fff;
272 | transform: rotate(45deg); }
273 |
274 | .height-container {
275 | display: none;
276 | position: relative;
277 | width: 100%;
278 | overflow: hidden; }
279 | .height-container .section {
280 | background: #fff;
281 | border: 1px solid #ddd;
282 | border-top-width: 0;
283 | padding-top: 10px;
284 | padding-bottom: 5px;
285 | padding: 8px 16px; }
286 |
287 | .aside, .language {
288 | padding: 6px 12px;
289 | margin: 12px 0;
290 | border-left: 5px solid #dddddd;
291 | overflow-y: hidden; }
292 | .aside .aside-title, .language .aside-title {
293 | font-size: 9px;
294 | letter-spacing: 2px;
295 | text-transform: uppercase;
296 | padding-bottom: 0;
297 | margin: 0;
298 | color: #aaa;
299 | -webkit-user-select: none; }
300 | .aside p:last-child, .language p:last-child {
301 | margin-bottom: 0; }
302 |
303 | .language {
304 | border-left: 5px solid #cde9f4; }
305 | .language .aside-title {
306 | color: #4183c4; }
307 |
308 | .aside-warning, .aside-deprecated, .aside-unavailable {
309 | border-left: 5px solid #ff6666; }
310 | .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title {
311 | color: #ff0000; }
312 |
313 | .graybox {
314 | border-collapse: collapse;
315 | width: 100%; }
316 | .graybox p {
317 | margin: 0;
318 | word-break: break-word;
319 | min-width: 50px; }
320 | .graybox td {
321 | border: 1px solid #ddd;
322 | padding: 5px 25px 5px 10px;
323 | vertical-align: middle; }
324 | .graybox tr td:first-of-type {
325 | text-align: right;
326 | padding: 7px;
327 | vertical-align: top;
328 | word-break: normal;
329 | width: 40px; }
330 |
331 | .slightly-smaller {
332 | font-size: 0.9em; }
333 |
334 | .footer {
335 | padding: 8px 16px;
336 | background: #444;
337 | color: #ddd;
338 | font-size: 0.8em; }
339 | .footer p {
340 | margin: 8px 0; }
341 | .footer a {
342 | color: #fff; }
343 |
344 | html.dash .header, html.dash .breadcrumbs, html.dash .navigation {
345 | display: none; }
346 |
347 | html.dash .height-container {
348 | display: block; }
349 |
350 | form[role=search] input {
351 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
352 | font-size: 14px;
353 | line-height: 24px;
354 | padding: 0 10px;
355 | margin: 0;
356 | border: none;
357 | border-radius: 1em; }
358 | .loading form[role=search] input {
359 | background: white url(../img/spinner.gif) center right 4px no-repeat; }
360 |
361 | form[role=search] .tt-menu {
362 | margin: 0;
363 | min-width: 300px;
364 | background: #fff;
365 | color: #333;
366 | border: 1px solid #ddd; }
367 |
368 | form[role=search] .tt-highlight {
369 | font-weight: bold; }
370 |
371 | form[role=search] .tt-suggestion {
372 | font: 16px/1.7 "Helvetica Neue", Helvetica, Arial, sans-serif;
373 | padding: 0 8px; }
374 | form[role=search] .tt-suggestion span {
375 | display: table-cell;
376 | white-space: nowrap; }
377 | form[role=search] .tt-suggestion .doc-parent-name {
378 | width: 100%;
379 | text-align: right;
380 | font-weight: normal;
381 | font-size: 0.9em;
382 | padding-left: 16px; }
383 |
384 | form[role=search] .tt-suggestion:hover,
385 | form[role=search] .tt-suggestion.tt-cursor {
386 | cursor: pointer;
387 | background-color: #1890ff;
388 | color: #fff; }
389 |
390 | form[role=search] .tt-suggestion:hover .doc-parent-name,
391 | form[role=search] .tt-suggestion.tt-cursor .doc-parent-name {
392 | color: #fff; }
393 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | com.jazzy.uirouter
7 | CFBundleName
8 | UIRouter
9 | DocSetPlatformFamily
10 | uirouter
11 | isDashDocset
12 |
13 | dashIndexFilePath
14 | index.html
15 | isJavaScriptEnabled
16 |
17 | DashDocSetFamily
18 | dashtoc
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/Extensions/Array.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Array Extension Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | Array Extension Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
Array
139 |
140 |
141 |
142 |
public extension Array where Element == PathComponent
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
162 |
163 | -
164 |
165 |
166 |
167 |
168 | string
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
Undocumented
177 |
178 |
179 |
180 |
Declaration
181 |
182 |
Swift
183 |
var string: String { get }
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/Extensions/String.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | String Extension Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | String Extension Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
String
139 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | -
155 |
162 |
163 |
164 |
165 |
166 |
167 |
如果构造成功则返回一个 URLComponents
,否则抛出异常.
168 |
173 |
174 |
175 |
176 |
Declaration
177 |
178 |
Swift
179 |
public func asURLComponents() throws -> URLComponents
180 |
181 |
182 |
183 |
184 |
Return Value
185 |
构造成功的URLComponents
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/Extensions/URL.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | URL Extension Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | URL Extension Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
URL
139 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | -
155 |
162 |
163 |
164 |
165 |
166 |
167 |
如果构造成功则返回一个 URLComponents
,否则抛出异常.
168 |
173 |
174 |
175 |
176 |
Declaration
177 |
178 |
Swift
179 |
public func asURLComponents() throws -> URLComponents
180 |
181 |
182 |
183 |
184 |
Return Value
185 |
构造成功的URLComponents
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/Extensions/URLComponents.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | URLComponents Extension Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | URLComponents Extension Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
URLComponents
139 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | -
155 |
162 |
163 |
164 |
165 |
166 |
167 |
如果构造成功则返回一个 URLComponents
,否则抛出异常.
168 |
173 |
174 |
175 |
176 |
Declaration
177 |
178 |
Swift
179 |
public func asURLComponents() throws -> URLComponents
180 |
181 |
182 |
183 |
184 |
Return Value
185 |
构造成功的URLComponents
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/Protocols/RouteInterceptor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | RouteInterceptor Protocol Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | RouteInterceptor Protocol Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
RouteInterceptor
139 |
140 |
141 |
142 |
public protocol RouteInterceptor
143 |
144 |
145 |
146 |
Undocumented
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 | -
156 |
163 |
164 |
165 |
166 |
167 |
168 |
Undocumented
169 |
170 |
171 |
172 |
Declaration
173 |
174 |
Swift
175 |
func handle(components: URLComponents, object: Any, completionHandler: @escaping RouteCompletionHandler<UIViewController?>)
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
193 |
194 |
195 |
196 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/Protocols/URLComponentsConvertible.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | URLComponentsConvertible Protocol Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
37 |
38 |
39 | UIRouter Reference
40 |
41 | URLComponentsConvertible Protocol Reference
42 |
43 |
44 |
45 |
134 |
135 |
136 |
137 |
138 |
URLComponentsConvertible
139 |
140 |
141 |
142 |
public protocol URLComponentsConvertible
143 |
144 |
145 |
146 |
Types adopting the URLComponentsConvertible
protocol can be used to construct URLComponents
s, which can then be used to route.
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 | -
156 |
163 |
164 |
165 |
166 |
167 |
168 |
如果构造成功则返回一个 URLComponents
,否则抛出异常.
169 |
174 |
175 |
176 |
177 |
Declaration
178 |
179 |
Swift
180 |
func asURLComponents() throws -> URLComponents
181 |
182 |
183 |
184 |
185 |
Return Value
186 |
构造成功的URLComponents
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
202 |
203 |
204 |
205 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/img/carat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/docsets/UIRouter.docset/Contents/Resources/Documents/img/carat.png
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/img/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/docsets/UIRouter.docset/Contents/Resources/Documents/img/dash.png
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/img/gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/docsets/UIRouter.docset/Contents/Resources/Documents/img/gh.png
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/img/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/docsets/UIRouter.docset/Contents/Resources/Documents/img/spinner.gif
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | function toggleItem($link, $content) {
12 | var animationDuration = 300;
13 | $link.toggleClass('token-open');
14 | $content.slideToggle(animationDuration);
15 | }
16 |
17 | function itemLinkToContent($link) {
18 | return $link.parent().parent().next();
19 | }
20 |
21 | // On doc load + hash-change, open any targetted item
22 | function openCurrentItemIfClosed() {
23 | if (window.jazzy.docset) {
24 | return;
25 | }
26 | var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token');
27 | $content = itemLinkToContent($link);
28 | if ($content.is(':hidden')) {
29 | toggleItem($link, $content);
30 | }
31 | }
32 |
33 | $(openCurrentItemIfClosed);
34 | $(window).on('hashchange', openCurrentItemIfClosed);
35 |
36 | // On item link ('token') click, toggle its discussion
37 | $('.token').on('click', function(event) {
38 | if (window.jazzy.docset) {
39 | return;
40 | }
41 | var $link = $(this);
42 | toggleItem($link, itemLinkToContent($link));
43 |
44 | // Keeps the document from jumping to the hash.
45 | var href = $link.attr('href');
46 | if (history.pushState) {
47 | history.pushState({}, '', href);
48 | } else {
49 | location.hash = href;
50 | }
51 | event.preventDefault();
52 | });
53 |
54 | // Clicks on links to the current, closed, item need to open the item
55 | $("a:not('.token')").on('click', function() {
56 | if (location == this.href) {
57 | openCurrentItemIfClosed();
58 | }
59 | });
60 |
61 | // KaTeX rendering
62 | if ("katex" in window) {
63 | $($('.math').each( (_, element) => {
64 | katex.render(element.textContent, element, {
65 | displayMode: $(element).hasClass('m-block'),
66 | throwOnError: false,
67 | trust: true
68 | });
69 | }))
70 | }
71 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/Documents/js/jazzy.search.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | var $typeahead = $('[data-typeahead]');
3 | var $form = $typeahead.parents('form');
4 | var searchURL = $form.attr('action');
5 |
6 | function displayTemplate(result) {
7 | return result.name;
8 | }
9 |
10 | function suggestionTemplate(result) {
11 | var t = '';
12 | t += '' + result.name + '';
13 | if (result.parent_name) {
14 | t += '' + result.parent_name + '';
15 | }
16 | t += '
';
17 | return t;
18 | }
19 |
20 | $typeahead.one('focus', function() {
21 | $form.addClass('loading');
22 |
23 | $.getJSON(searchURL).then(function(searchData) {
24 | const searchIndex = lunr(function() {
25 | this.ref('url');
26 | this.field('name');
27 | this.field('abstract');
28 | for (const [url, doc] of Object.entries(searchData)) {
29 | this.add({url: url, name: doc.name, abstract: doc.abstract});
30 | }
31 | });
32 |
33 | $typeahead.typeahead(
34 | {
35 | highlight: true,
36 | minLength: 3,
37 | autoselect: true
38 | },
39 | {
40 | limit: 10,
41 | display: displayTemplate,
42 | templates: { suggestion: suggestionTemplate },
43 | source: function(query, sync) {
44 | const lcSearch = query.toLowerCase();
45 | const results = searchIndex.query(function(q) {
46 | q.term(lcSearch, { boost: 100 });
47 | q.term(lcSearch, {
48 | boost: 10,
49 | wildcard: lunr.Query.wildcard.TRAILING
50 | });
51 | }).map(function(result) {
52 | var doc = searchData[result.ref];
53 | doc.url = result.ref;
54 | return doc;
55 | });
56 | sync(results);
57 | }
58 | }
59 | );
60 | $form.removeClass('loading');
61 | $typeahead.trigger('focus');
62 | });
63 | });
64 |
65 | var baseURL = searchURL.slice(0, -"search.json".length);
66 |
67 | $typeahead.on('typeahead:select', function(e, result) {
68 | window.location = baseURL + result.url;
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.docset/Contents/Resources/docSet.dsidx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/docsets/UIRouter.docset/Contents/Resources/docSet.dsidx
--------------------------------------------------------------------------------
/docs/docsets/UIRouter.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/docsets/UIRouter.tgz
--------------------------------------------------------------------------------
/docs/img/carat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/img/carat.png
--------------------------------------------------------------------------------
/docs/img/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/img/dash.png
--------------------------------------------------------------------------------
/docs/img/gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/img/gh.png
--------------------------------------------------------------------------------
/docs/img/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/docs/img/spinner.gif
--------------------------------------------------------------------------------
/docs/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | function toggleItem($link, $content) {
12 | var animationDuration = 300;
13 | $link.toggleClass('token-open');
14 | $content.slideToggle(animationDuration);
15 | }
16 |
17 | function itemLinkToContent($link) {
18 | return $link.parent().parent().next();
19 | }
20 |
21 | // On doc load + hash-change, open any targetted item
22 | function openCurrentItemIfClosed() {
23 | if (window.jazzy.docset) {
24 | return;
25 | }
26 | var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token');
27 | $content = itemLinkToContent($link);
28 | if ($content.is(':hidden')) {
29 | toggleItem($link, $content);
30 | }
31 | }
32 |
33 | $(openCurrentItemIfClosed);
34 | $(window).on('hashchange', openCurrentItemIfClosed);
35 |
36 | // On item link ('token') click, toggle its discussion
37 | $('.token').on('click', function(event) {
38 | if (window.jazzy.docset) {
39 | return;
40 | }
41 | var $link = $(this);
42 | toggleItem($link, itemLinkToContent($link));
43 |
44 | // Keeps the document from jumping to the hash.
45 | var href = $link.attr('href');
46 | if (history.pushState) {
47 | history.pushState({}, '', href);
48 | } else {
49 | location.hash = href;
50 | }
51 | event.preventDefault();
52 | });
53 |
54 | // Clicks on links to the current, closed, item need to open the item
55 | $("a:not('.token')").on('click', function() {
56 | if (location == this.href) {
57 | openCurrentItemIfClosed();
58 | }
59 | });
60 |
61 | // KaTeX rendering
62 | if ("katex" in window) {
63 | $($('.math').each( (_, element) => {
64 | katex.render(element.textContent, element, {
65 | displayMode: $(element).hasClass('m-block'),
66 | throwOnError: false,
67 | trust: true
68 | });
69 | }))
70 | }
71 |
--------------------------------------------------------------------------------
/docs/js/jazzy.search.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | var $typeahead = $('[data-typeahead]');
3 | var $form = $typeahead.parents('form');
4 | var searchURL = $form.attr('action');
5 |
6 | function displayTemplate(result) {
7 | return result.name;
8 | }
9 |
10 | function suggestionTemplate(result) {
11 | var t = '';
12 | t += '' + result.name + '';
13 | if (result.parent_name) {
14 | t += '' + result.parent_name + '';
15 | }
16 | t += '
';
17 | return t;
18 | }
19 |
20 | $typeahead.one('focus', function() {
21 | $form.addClass('loading');
22 |
23 | $.getJSON(searchURL).then(function(searchData) {
24 | const searchIndex = lunr(function() {
25 | this.ref('url');
26 | this.field('name');
27 | this.field('abstract');
28 | for (const [url, doc] of Object.entries(searchData)) {
29 | this.add({url: url, name: doc.name, abstract: doc.abstract});
30 | }
31 | });
32 |
33 | $typeahead.typeahead(
34 | {
35 | highlight: true,
36 | minLength: 3,
37 | autoselect: true
38 | },
39 | {
40 | limit: 10,
41 | display: displayTemplate,
42 | templates: { suggestion: suggestionTemplate },
43 | source: function(query, sync) {
44 | const lcSearch = query.toLowerCase();
45 | const results = searchIndex.query(function(q) {
46 | q.term(lcSearch, { boost: 100 });
47 | q.term(lcSearch, {
48 | boost: 10,
49 | wildcard: lunr.Query.wildcard.TRAILING
50 | });
51 | }).map(function(result) {
52 | var doc = searchData[result.ref];
53 | doc.url = result.ref;
54 | return doc;
55 | });
56 | sync(results);
57 | }
58 | }
59 | );
60 | $form.removeClass('loading');
61 | $typeahead.trigger('focus');
62 | });
63 | });
64 |
65 | var baseURL = searchURL.slice(0, -"search.json".length);
66 |
67 | $typeahead.on('typeahead:select', function(e, result) {
68 | window.location = baseURL + result.url;
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wxlpp/UIRouter/758210a642f5252fca54b12737b9a7cb9ed6d37b/log.png
--------------------------------------------------------------------------------