|
1 | | -# URLPatternMacro |
| 1 | +# URLPattern |
| 2 | + |
| 3 | +A Swift Macro that helps mapping URLs to Enum cases. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +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: |
| 8 | + |
| 9 | +```swift |
| 10 | +// Traditional approach with manual URL handling |
| 11 | +if url.path == "/posts" { |
| 12 | + // Handle posts |
| 13 | +} else if url.path.matches("^/posts/\\d+$") { |
| 14 | + // Handle single post |
| 15 | +} |
| 16 | +``` |
| 17 | + |
| 18 | +This approach lacks visibility and scalability, and importantly, cannot validate incorrect patterns at compile-time. |
| 19 | + |
| 20 | +URLPattern solves these issues by providing compile-time validation and type-safe URL mapping: |
| 21 | + |
| 22 | +```swift |
| 23 | +@URLPattern |
| 24 | +enum DeepLink { |
| 25 | + @URLPath("/home") |
| 26 | + case home |
| 27 | + |
| 28 | + @URLPath("/posts/{postId}") |
| 29 | + case post(postId: String) |
| 30 | + |
| 31 | + @URLPath("/posts/{postId}/comments/{commentId}") |
| 32 | + case postComment(postId: String, commentId: String) |
| 33 | +} |
| 34 | +``` |
| 35 | + |
| 36 | +## Features |
| 37 | + |
| 38 | +- **Compile-time Validation**: Ensures URL patterns and associated values match correctly |
| 39 | +- **Automatic Enum Generation**: Creates initializers that map URL components to enum associated values |
| 40 | +- **Type Support**: |
| 41 | + - Built-in support for `String`, `Int`, `Float`, and `Double` |
| 42 | + - Non-String types use their respective String initializers |
| 43 | + - Extensible for custom types |
| 44 | + |
| 45 | +## Usage |
| 46 | + |
| 47 | +```swift |
| 48 | +@URLPattern |
| 49 | +enum DeepLink { |
| 50 | + @URLPath("/posts/{postId}") |
| 51 | + case post(postId: String) |
| 52 | + |
| 53 | + @URLPath("/posts/{postId}/comments/{commentId}") |
| 54 | + case postComment(postId: String, commentId: String) |
| 55 | + |
| 56 | + @URLPath("/f/{first}/s/{second}") |
| 57 | + case reverse(second: Int, first: Int) |
| 58 | +} |
| 59 | +``` |
| 60 | + |
| 61 | +1. Declare the `@URLPattern` macro on your enum. |
| 62 | + |
| 63 | +2. Add `@URLPath` macro to enum cases with the desired URL pattern. |
| 64 | + |
| 65 | +3. Use path parameters with `{associated_value_label}` syntax to map URL components to associated values. |
| 66 | + |
| 67 | + |
| 68 | +```swift |
| 69 | +// ✅ Valid URLs |
| 70 | +DeepLink(url: URL(string: "/posts/1")!) == .post(postId: "1") |
| 71 | +DeepLink(url: URL(string: "/posts/1/comments/2")!) == .postComment(postId: "1", commentId: "2") |
| 72 | +DeepLink(url: URL(string: "/f/1/s/2")!) == .postComment(second: 2, first: 1) |
| 73 | + |
| 74 | +// ❌ Invalid URLs |
| 75 | +DeepLink(url: URL(string: "/post/1")) == nil |
| 76 | +DeepLink(url: URL(string: "/posts/1/comments")) == nil |
| 77 | +DeepLink(url: URL(string: "/f/string/s/string")!) == nil |
| 78 | +``` |
| 79 | +4. Use the `Enum.init(url: URL)` generated initializer. |
| 80 | + |
| 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 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