A Swift Macro that helps mapping URLs to Enum cases.
URLPattern.mp4
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:
// Traditional approach with manual URL handling letpaths= url.pathComponents if paths.count ==2 && paths[1]=="home"{ // Handle home }elselet match =try? url.path.firstMatch(of:/\/posts\/([^\/]+)$/){ // Handle posts }This approach reduces code readability and scalability, and importantly, cannot validate incorrect patterns at compile-time.
URLPattern solves these issues by providing compile-time URL validation and value mapping:
@URLPatternenumDeepLink{@URLPath("/home")case home @URLPath("/posts/{postId}")case post(postId:String)@URLPath("/posts/{postId}/comments/{commentId}")case postComment(postId:String, commentId:String)}- Compile-time Validation: Ensures URL path values and associated value names match correctly
- Automatic Enum Generation: Creates initializers that map URL components to enum associated values
- Type Support:
- Built-in support for
String,Int,Float, andDouble - Non-String types (Int, Float, Double) use String-based initialization
- Built-in support for
@URLPatternenumDeepLink{@URLPath("/posts/{postId}")case post(postId:String)@URLPath("/posts/{postId}/comments/{commentId}")case postComment(postId:String, commentId:String)@URLPath("/f/{first}/s/{second}")case reverse(second:Int, first:Int)}Declare the
@URLPatternmacro on your enum.Add
@URLPathmacro to enum cases with the desired URL pattern.Use path values with
{associated_value_name}syntax to map URL components to associated value names. If mapping code is duplicated, the topmost enum case takes precedence.
// ✅ Valid URLs DeepLink(url:URL(string:"/posts/1")!)==.post(postId:"1")DeepLink(url:URL(string:"/posts/1/comments/2")!)==.postComment(postId:"1", commentId:"2")DeepLink(url:URL(string:"/f/1/s/2")!)==.reverse(second:2, first:1) // ❌ Invalid URLs DeepLink(url:URL(string:"/post/1")!)==nilDeepLink(url:URL(string:"/posts/1/comments")!)==nilDeepLink(url:URL(string:"/f/string/s/string")!)==nil- Use the
Enum.init(url: URL)generated initializer.
iflet deepLink =DeepLink(url: incomingURL){switch deepLink {case.post(let postId): // Handle post case .postComment(let postId, let commentId): // Handle postComment }}- Implement a deep link using an enum switch statement.
- For more detailed examples, please refer to the Example project.
- Unique Enum Case Names: Enum case names must be unique for better readability of expanded macro code.
- Unique Associated Value Names: Associated value names within each case must be unique.
- Valid URL Patterns: Arguments passed to @URLPath macro must be in valid URL path format.
- Supported Types: Only String, Int, Float, and Double are supported.
Project > Project Dependencies > Add https://github.com/heoblitz/URLPattern.git