Skip to content

Commit a780cfb

Browse files
daniel-beardmgod
authored andcommitted
Add badges and try in playground code
1 parent 43405ec commit a780cfb

2 files changed

Lines changed: 138 additions & 1 deletion

File tree

.arena-sample.swift

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// Playground generated with 🏟 Arena (https://github.com/finestructure/arena)
2+
// ℹ️ If running the playground fails with an error "no such module ..."
3+
// go to Product -> Build to re-trigger building the SPM package.
4+
// ℹ️ Please restart Xcode if autocomplete is not working.
5+
6+
import Foundation
7+
import URLMatcher
8+
9+
enum URLAction {
10+
case login, signup, invite(key: String)
11+
}
12+
13+
// Quick start example
14+
var matcher = URLMatcher<URLAction>()
15+
16+
try matcher.add(path: "user/login") { .login }
17+
try matcher.add(path: "user/signup") { .signup }
18+
try matcher.add(path: "user/invite/<key: String>") {(_, values) in
19+
.invite(key: values["key"] as! String)
20+
}
21+
22+
// Grab your url from your web view or app delegate method
23+
let url = URL(string:"http://mydomain.com/user/invite/y78gyug76g")!
24+
25+
if let action = matcher.matchURL(url) {
26+
switch action {
27+
case .login, .signup:
28+
print("Show welcome form")
29+
case .invite(let key):
30+
// Show loading overlay
31+
// Look up invite from the server
32+
// Dismiss the loading overlay
33+
// If available, show the accept invite flow
34+
// If not, show an error alert
35+
print("Load invite: \(key)")
36+
}
37+
} else {
38+
// We don't know what to do with this URL, fallback on the system
39+
}
40+
41+
// Matching example
42+
struct UserAction {
43+
let userId: Int64?
44+
let action: String
45+
}
46+
extension UserAction: CustomDebugStringConvertible {
47+
var debugDescription: String {
48+
if let userId = userId {
49+
return "\(action) user \(userId)"
50+
} else {
51+
return "\(action) user"
52+
}
53+
}
54+
}
55+
56+
var userMatcher = URLMatcher<UserAction>()
57+
58+
try userMatcher.add(path: "user/<userId:Int64>/edit") { (_, values: [String : Any]) -> UserAction in
59+
return UserAction(userId: values["userId"] as? Int64, action: "edit")
60+
}
61+
62+
try userMatcher.add(path: "user/<userId:Int64>/<*>") { (query: [String: String], values: [String : Any]) -> UserAction in
63+
if query["force_update"] == "true" {
64+
return UserAction(userId: values["userId"] as? Int64, action: "update app")
65+
} else {
66+
return UserAction(userId: values["userId"] as? Int64, action: "show")
67+
}
68+
}
69+
70+
try userMatcher.add(path: "user/<+>/<*>") { return UserAction(userId: nil, action: "unknown") }
71+
72+
var action = userMatcher.matchURL(URL(string:"user/6578/edit")!)
73+
print(action!)
74+
75+
action = userMatcher.matchURL(URL(string:"user/890822/verify/email")!)
76+
print(action!)
77+
78+
action = userMatcher.matchURL(URL(string:"user/890822/verify/email?force_update=true")!)
79+
print(action!)
80+
81+
action = userMatcher.matchURL(URL(string:"user/an.email@example.com/verify/email")!)
82+
print(action!)
83+
84+
85+
// Wildcard example
86+
var wildcardMatcher = URLMatcher<String>()
87+
88+
try wildcardMatcher.add(path: "a/<+>") { "a" }
89+
try wildcardMatcher.add(path: "<+>/b") { "b" }
90+
91+
var wildcard = wildcardMatcher.matchURL(URL(string:"a/b")!)
92+
wildcard = wildcardMatcher.matchURL(URL(string: "c/b")!)
93+
94+
95+
// Custom components example
96+
struct Commit : ComponentMatchable {
97+
func matches(urlComponent: String) -> Bool {
98+
return "c" == urlComponent || "commit" == urlComponent
99+
}
100+
}
101+
102+
struct HashId: ComponentParseable {
103+
let label: String
104+
105+
func matches(urlComponent: String) -> Bool {
106+
return valueOf(urlComponent: urlComponent) != nil
107+
}
108+
109+
func valueOf(urlComponent: String) -> Any? {
110+
// Should actually validate more completely, not great string handling
111+
if 7 == urlComponent.count || 40 == urlComponent.count {
112+
return String(urlComponent.prefix(7))
113+
} else {
114+
return nil
115+
}
116+
}
117+
}
118+
119+
var commitMatcher = URLMatcher<String>()
120+
121+
commitMatcher.registerType(name: "Commit") { (_) in Commit() }
122+
commitMatcher.registerType(name: "HashId") { HashId(label: $0) }
123+
124+
try commitMatcher.add(path: "<Commit>/<commitId:HashId>") { (_, values: [String : Any]) -> String in
125+
return values["commitId"] as! String
126+
}
127+
128+
var commit = commitMatcher.matchURL(URL(string:"/c/7h1uh89")!)
129+
print(commit!)
130+
131+
commit = commitMatcher.matchURL(URL(string:"/commit/7h1uh8927e39434ae8da5fuy6c1de98c56c09410")!)
132+
print(commit!)
133+
134+
135+

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# URLMatcher
22

3+
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fsplitwise%2FURLMatcher%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/splitwise/URLMatcher) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fsplitwise%2FURLMatcher%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/splitwise/URLMatcher)
4+
35
URLMatcher is a flexible url matching library intended to handle the problem of what a URL is for without specifying how to handle it.
46

57
Similar libraries assume you'll be binding data to a view controller, then displaying it. This makes them hard to test well and awkward to use if your behavior is different. Maybe you need to select a specific tab, push a navigation controller, then show an alert or do different data binding depending on your local state. URLMatcher leaves this up to you while making it easy to test that you're matching and parsing all the URLs you expect to handle.
@@ -49,7 +51,7 @@ The URLMatcher will find the path that matches the URL and then execute the prov
4951

5052
## Matching
5153

52-
NOTE: the code samples here are based on the [Examples/Readme/main.swift](Examples/Readme/main.swift) code if you'd like the try it out.
54+
NOTE: the code samples here are based on the [Examples/Readme/main.swift](Examples/Readme/main.swift) code if you'd like the try it out. You can also click on `Try in a playground` on the [Swift Package Index page](https://swiftpackageindex.com/splitwise/URLMatcher) to get a generated playground containing this code.
5355

5456
### Basic matching
5557

0 commit comments

Comments
 (0)