SchemeRoute
Swift 매크로를 이용해 URL 스킴 기반 라우팅 코드를 자동으로 생성하는 패키지입니다.
This package uses Swift macros to generate URL scheme based routing code automatically.
enum
선언과 패턴만으로 문자열/URL ↔ 라우트 변환을 위한 SchemeMapper
를 생성할 수 있습니다.
With just an enum
declaration and patterns, you can build a SchemeMapper
for string/URL ↔ route conversions.
Requirements
- Swift 5.10 이상 (매크로 기능 활용)
Swift 5.10 or later (requires macro support) - iOS 13 / macOS 10.15 / tvOS 13 / watchOS 6 / macCatalyst 13 이상 타깃
Targets iOS 13 / macOS 10.15 / tvOS 13 / watchOS 6 / macCatalyst 13 or newer
Installation (Swift Package Manager)
Package.swift
의 dependencies
배열에 SchemeRoute
를 최신 버전으로 추가합니다 (현재 0.2.0).
Add SchemeRoute
to the dependencies
array in Package.swift
with the latest version (currently 0.2.0).
.package(url: "https://github.com/ShapeKim98/SchemeRoute.git", from: "0.2.0")
사용할 타깃의 dependencies
에 SchemeRoute
를 명시합니다.
Declare SchemeRoute
in the target's dependencies
where it will be used.
.target(
name: "YourApp",
dependencies: [
.product(name: "SchemeRoute", package: "SchemeRoute")
]
)
Xcode에서는 File > Add Packages... 메뉴에서 같은 URL을 입력하면 됩니다.
In Xcode, use File > Add Packages... and enter the same URL.
Quick Start
import SchemeRoute
@SchemeRoutable
enum AppRoute: Equatable {
static var scheme: String { "myapp" }
static var host: String { "app" }
@SchemePattern("")
case home
@SchemePattern("user/${id}/profile")
case userProfile(id: String)
@SchemePattern("article/${slug}?ref=${ref}")
case article(slug: String, ref: String)
}
// 문자열 → 라우트 (호스트는 기본값으로 분리)
let route = AppRoute(rawValue: "user/42/profile")
// URL → 라우트
let fromURL = AppRoute(url: URL(string: "myapp://app/article/swift?ref=newsletter"))
// 라우트 → URL
let url = AppRoute.article(slug: "swift", ref: "newsletter").url()
기본 스킴/호스트를 지정하지 않으면 패턴 문자열 안에 호스트(필요하다면 스킴까지)를 직접 포함할 수 있습니다. 기존 iOS/웹 URL을 그대로 다뤄야 할 때 유용합니다.
@SchemeRoutable
enum InlineRoute: Equatable {
@SchemePattern("kakaolink?categoryId=${categoryId}")
case kakaolink(categoryId: String)
@SchemePattern("inline.app/user/${id}/profile")
case inlineProfile(id: String)
}
let inline = InlineRoute(rawValue: "inline.app/user/42/profile")
let kakao = InlineRoute(url: URL(string: "kakaoapp://kakaolink?categoryId=424"))
let deepURL = InlineRoute.inlineProfile(id: "42").url(scheme: "myapp")
패턴에 포함된 호스트는 그대로 유지되며, url(scheme:)
을 통해 런타임에서 필요한 스킴을 주입할 수 있습니다.
@SchemeRoutable
매크로는 enum
내 모든 케이스를 스캔하여 SchemeMapper<AppRoute>
를 생성합니다.
The @SchemeRoutable
macro scans every case in the enum
and generates a SchemeMapper<AppRoute>
.
init?(url:)
은 옵셔널 URL을 그대로 받아 nil 이면 초기화에 실패합니다.
init?(url:)
accepts an optional URL and returns nil
when the argument is nil
.
SchemeRoute
프로토콜의 기본 구현(rawValue
, init?(rawValue:)
, init?(url:)
)도 자동으로 동작합니다.
The default SchemeRoute
implementations (rawValue
, init?(rawValue:)
, init?(url:)
) then work automatically.
Pattern Rules
- 패턴 문자열은 기본적으로
path?query
형태입니다.SchemeRoute.host
나SchemeRoute.scheme
가 비어 있으면 직접 호스트(및 스킴)을 포함시킬 수 있습니다.
Pattern strings arepath?query
by default. WhenSchemeRoute.host
orSchemeRoute.scheme
are empty, you may inline the host (and scheme) manually. - 경로와 쿼리에서 값이 되는 부분은
${name}
플레이스홀더로 표기합니다.
Use${name}
placeholders wherever the path or query should inject values.- 경로 예:
user/${id}/profile
Path example:user/${id}/profile
- 쿼리 예:
pay/complete?order_id=${orderId}
Query example:pay/complete?order_id=${orderId}
- 경로 예:
- 플레이스홀더 이름은
case
의 연관값 라벨과 1:1 로 매칭되어야 하며, 모든 연관값은String
타입이어야 합니다.
Placeholder names must match associated value labels 1:1, and every associated value must beString
. - 같은 연관값을 두 번 이상 사용할 수 없고 사용하지 않은 연관값이 있으면 오류가 발생합니다.
The same associated value cannot be used more than once, and unused associated values trigger an error. - 외부 라벨이 붙은 연관값(
case article(slug slug: String)
)은 지원하지 않습니다.
Associated values with external labels (e.g.case article(slug slug: String)
) are not supported. SchemeRoute.scheme
/host
가 지정되어 있다면url()
호출 시 기본값으로 사용됩니다. 필요하면url(scheme:host:)
에서 값을 덮어쓸 수 있습니다.
WhenSchemeRoute.scheme
/host
are set,url()
uses them automatically; override them by passing arguments tourl(scheme:host:)
when needed.
Manual Router Configuration
매크로 대신 직접 매퍼를 구성하려면 SchemeMapper
의 Builder
를 사용할 수 있습니다.
If you prefer manual control, build the mapper by hand with SchemeMapper
's Builder
.
let router = SchemeMapper<AppRoute> { builder in
builder.register("user/${id}/profile", queryKeys: []) { params in
guard let id = params["id"] else { return nil }
return .userProfile(id: id)
} render: { route in
guard case let .userProfile(id) = route else { return nil }
return ["id": id]
}
}
대부분의 경우 매크로를 사용하는 편이 선언적이며 오류를 줄일 수 있습니다.
In most cases, macros remain more declarative and help prevent mistakes.
Example Run
리포지토리에는 간단한 실행 예제가 포함되어 있습니다.
A simple runnable example ships with the repository.
swift run SchemeRouteClient
출력 로그를 통해 문자열/URL 매칭과 URL 생성을 확인할 수 있습니다.
Check the output log to see string/URL matching and URL generation in action.
License
이 프로젝트는 MIT License 하에 배포됩니다.
This project is distributed under the MIT License.