Skip to content

Commit 20a5fb1

Browse files
committed
Update readme
1 parent 9100025 commit 20a5fb1

File tree

1 file changed

+102
-1
lines changed

1 file changed

+102
-1
lines changed

README.md

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,102 @@
1-
# URLPatternMacro
1+
# URLPattern
2+
[![Swift](https://github.com/heoblitz/URLPattern/actions/workflows/swift.yml/badge.svg?branch=main)](https://github.com/heoblitz/URLPattern/actions/workflows/swift.yml)
3+
4+
A Swift Macro that helps mapping URLs to Enum cases.
5+
6+
## Overview
7+
8+
URL deep linking is a fundamental technology widely used in most services today. However, in Swift environments, implementing deep linking typically requires direct URL path manipulation or regex usage:
9+
10+
```swift
11+
// Traditional approach with manual URL handling
12+
if url.path == "/posts" {
13+
// Handle posts
14+
} else if url.path.matches("^/posts/\\d+$") {
15+
// Handle single post
16+
}
17+
```
18+
19+
This approach reduces code readability and scalability, and importantly, cannot validate incorrect patterns at compile-time.
20+
21+
URLPattern solves these issues by providing compile-time validation and type-safe URL mapping:
22+
23+
```swift
24+
@URLPattern
25+
enum DeepLink {
26+
@URLPath("/home")
27+
case home
28+
29+
@URLPath("/posts/{postId}")
30+
case post(postId: String)
31+
32+
@URLPath("/posts/{postId}/comments/{commentId}")
33+
case postComment(postId: String, commentId: String)
34+
}
35+
```
36+
37+
## Features
38+
39+
- **Compile-time Validation**: Ensures URL patterns and associated values match correctly
40+
- **Automatic Enum Generation**: Creates initializers that map URL components to enum associated values
41+
- **Type Support**:
42+
- Built-in support for `String`, `Int`, `Float`, and `Double`
43+
- Non-String types use their respective String initializers
44+
- Extensible for custom types
45+
46+
## Usage
47+
48+
```swift
49+
@URLPattern
50+
enum DeepLink {
51+
@URLPath("/posts/{postId}")
52+
case post(postId: String)
53+
54+
@URLPath("/posts/{postId}/comments/{commentId}")
55+
case postComment(postId: String, commentId: String)
56+
57+
@URLPath("/f/{first}/s/{second}")
58+
case reverse(second: Int, first: Int)
59+
}
60+
```
61+
62+
1. Declare the `@URLPattern` macro on your enum.
63+
64+
2. Add `@URLPath` macro to enum cases with the desired URL pattern.
65+
66+
3. Use path parameters with `{associated_value_label}` syntax to map URL components to associated values. If mapping code is duplicated, the topmost enum case takes precedence.
67+
68+
69+
```swift
70+
// ✅ Valid URLs
71+
DeepLink(url: URL(string: "/posts/1")!) == .post(postId: "1")
72+
DeepLink(url: URL(string: "/posts/1/comments/2")!) == .postComment(postId: "1", commentId: "2")
73+
DeepLink(url: URL(string: "/f/1/s/2")!) == .postComment(second: 2, first: 1)
74+
75+
// ❌ Invalid URLs
76+
DeepLink(url: URL(string: "/post/1")) == nil
77+
DeepLink(url: URL(string: "/posts/1/comments")) == nil
78+
DeepLink(url: URL(string: "/f/string/s/string")!) == nil
79+
```
80+
4. Use the `Enum.init(url: URL)` generated initializer.
81+
```
82+
if let deepLink = DeepLink(url: incomingURL) {
83+
switch deepLink {
84+
case .post(let postId):
85+
// Handle post
86+
case .postComment(let postId, let commentId):
87+
// Handle comment
88+
}
89+
}
90+
```
91+
5. Implement a deep link using an enum switch statement.
92+
93+
## Rules
94+
95+
- **Unique Enum Case Names**: Enum case names must be unique for better readability of expanded macro code.
96+
- **Unique Associated Value Names**: Associated value names within each case must be unique.
97+
- **Valid URL Patterns**: URL patterns must be valid and match the associated value types.
98+
- **Supported Types**: Only String, Int, Float, and Double are supported.
99+
## Installation
100+
### Swift Package Manager
101+
Project > Project Dependencies > Add   `https://github.com/heoblitz/URLPattern.git`
102+

0 commit comments

Comments
 (0)