A fork of SweetRouter
I like
You can use Carthage to install SweetRouter by adding it to your Cartfile:
github "thecb4/HyperSpace"
Imagine that you use the following URLs
within your App
https://myservercom.com:123/api/new/signIn
https://myservercom.com:123/api/new/signOut
https://myservercom.com:123/api/new/posts?date=today&userId=id
Every URL
in the list is called an Endpoint
Endpoint has the following structure:
Endpoint
┌─────────────────────────────────┴────────────────────────────────────┐
https://myservercom.com:123/api/new/posts?date=today&userId=id#paragraph
└────────────────┬────────────────┘└────────────────┬──────────────────┘
Environment Route
Endpoint is represented with EndpointType
protocol
.
Environment has the following structure:
Environment
┌────────────────┴─────────────────┐
https://myservercom.com:123/api/new/posts?date=today&userId=id#paragraph
└─┬─┘ └───────┬───────┘└┬┘└─────┬─┘
scheme host port default path
Examples of Environment
URL.Env(.https, "mytestserver.com").at("api", "new") // https://mytestserver.com/api/new/
URL.Env(IP(127, 0, 0, 1), 8080) // http://127.0.01:8080
URL.Env.localhost(4001) // http://localhost:4001
Route has the following structure:
Route
┌─────────────────┴─────────────────┐
https://myservercom.com:123/api/new/posts?date=today&userId=id#paragraph
└──┬──┘└────────┬─────────┘└───┬────┘
path query fragment
Example of Route
// /api/new/posts?date=today&userId=id#paragraph
URL.Route(at: "api", "new", "posts").query(("date", "today"), ("userId", "id")).fragment("paragraph")
Here is an example of the Router for some back-end API
:
enum Api: EndpointType {
enum Environment: EnvironmentType {
case localhost
case test
case production
var value: URL.Env {
switch self {
case .localhost: return .localhost(8080)
case .test: return .init(IP(126, 251, 20, 32))
case .production: return .init(.https, "myproductionserver.com", 3000)
}
}
}
enum Route: RouteType {
case auth, me
case posts(for: Date)
var route: URL.Route {
switch self {
case .me: return .init(at: "me")
case .auth: return .init(at: "auth")
case let .posts(for: date):
return URL.Route(at: "posts").query(("date", date), ("userId", "someId"))
}
}
}
static let current: Environment = .localhost
}
Endpoints resolve to an EndPointResult that provides the HTTPResponse, Data, and Error you would normally get from a URLSession DataTask. EndPointResult is a struct with helper methods that return Result and a String version of the HTTPResponse, StatusCode, or JSON decode of the data.
let ep = Router<Auth>(at: .signIn)
let result = ep.resolve()
let expectedJSON: Result<Example, URL.ResponseError> = result.json()
switch expectedJSON {
case let .success(value):
// do something with the json result
case .failure( .noDataPresent ):
print("no data present")
// gracefully handle no data being present
case let .failure( .decodeFailure(message) ):
print(message)
// gracefully handle decoding errors
}
It can often happen, that you will be using some third-party API
and you will have only access to Production environment. So in this case your Router will look something like this:
struct Auth: EndpointType {
enum Route: RouteType {
case signIn, signOut
var route: URL.Route {
switch self {
case .signIn: return .init(path: ["signIn"])
case .signOut: return .init(path: ["signOut"])
}
}
}
static let current = URL.Env(.https, "auth.server.com", 8080).at("api", "new")
}
And use it like this:
print(Router<Auth>(at: .signIn).url) // https://auth.server.com:8080/api/new/signIn
print(Router<Auth>(at: .signOut).url) // https://auth.server.com:8080/api/new/signOut
Add the following code somewhere in your app:
import Alamofire
import SweetRouter
extension Router: URLConvertible {
public func asURL() throws -> URL {
return url
}
}
And then you can use the same Routers like this:
Alamofire.request(Router<Auth>(at: .signIn))
As easy as that 😉