Appracatappra/UrlUtilities
Adds functions to construct a URL, HTTP Entity or URL Request in a combine like fashion.
Support
If you find UrlUtilities useful and would like to help support its continued development and maintenance, please consider making a small donation, especially if you are using it in a commercial product:
<a href="https://www.buymeacoffee.com/KevinAtAppra" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>
It's through the support of contributors like yourself, I can continue to build, release and maintain high-quality, well documented Swift Packages like UrlUtilities for free.
Installation
Swift Package Manager (Xcode 11 and above)
- In Xcode, select the File > Add Package Dependency… menu item.
- Paste
https://github.com/Appracatappra/UrlUtilities.gitin the dialog box. - Follow the Xcode's instruction to complete the installation.
Why not CocoaPods, or Carthage, or etc?
Supporting multiple dependency managers makes maintaining a library exponentially more complicated and time consuming.
Since, the Swift Package Manager is integrated with Xcode 11 (and greater), it's the easiest choice to support going further.
Overview
`UrlUtilities` includes several functions that are useful when working with **RESTful API Endpoints**. It includes the following utilities:
* `URLBuilder` - Assembles a **URL String** from a base path and any number of path or query parameters.
* `HTTPBodyBuilder` - Assembles the body of a `URLRequest` by setting a **JSON** pattern and filling it with any number of parameters.
Additionally, `UrlUtilities` has the following extensions:
* `String` - Adds the `urlEncoded` property which returns the string value properly encoded to send to a **URL** with any special characters encoded.
* `URLRequest` - Includes the following extensions:
* `defaultAuthorization` - Holds a default authorization string that will automatically be added to any `URLRequest.build` function calls.
* `build(url:URL, data:Data?, method:HttpMethodType = .post, timeout:Double = 10)` - Creates a `URLRequest` with the common default values.
* `build(url:URL, method:HttpMethodType = .post, timeout:Double = 10)` - Creates a `URLRequest` with the common default values.
### URLBuilder
`UrlUtilities` allows you to construct a **URL** string from a base path, then add path or query parameters in method similar to adding properties to a **SwiftUI View**. Take a look at the following example:
```swift
let endpoint = URLBuilder("https://api.restendpoint.com")
.addPathParameter(3)
.addPathParameter("login")
.addParameter(name: "username", value: "jdoe")
.addParameter(name: "password", value: "pass123")
// Get the string value
// "https://api.restendpoint.com/3/login?username=jdoe&password=pass123"
let validation = endpoint.urlString
// Ensure we have a good url
guard let url = endpoint.url else {return nil}
```
In the example above:
* `addPathParameter` - Appends the given value to the base path directly.
* `addParameter` - Adds a query parameter to the URL in the form `name=value`. It will automatically append "?" for the first parameter or "&" for subsequent parameters.
The value can be: `String`, `Bool`, `Int`, `Double`, `Float`, `Color` or `Enum`. For `Enum`, it must conform to either `String, Hashable` or `Int Hashable` (see below for details).
`Color` will be converted into a hex value in the form `#rrggbbaa` using the standard HTTP and CSS syntax.
> **NOTE:** Any string value will be automatically **URL Encoded** to ensure any special characters don't interfere with the generated **URL**.
### Optional Parameters
`UrlUtilities` makes it east to work with optional parameters. For example:
```swift
let sessionID:Int = 0
let username = "YOUR_USSERNAME"
let password = "YOUR_PASSWORD"
let endpoint = URLBuilder("https://login")
.addParameter(name: "username", value: "jdoe")
.addParameter(name: "password", value: "pass123")
.addParameter(name: "sessionID", value: sessionID, onCondition: (sessionID != 0))
```
In the above example, `onCondition` must evaluate to `true` before the parameter `sessionID` is included. Path parameters work in the same fashion:
```swift
let sessionID:Int = 0
let username = "YOUR_USSERNAME"
let password = "YOUR_PASSWORD"
let endpoint = URLBuilder("https://login")
.addPathParameter(sessionID, onCondition: (sessionID != 0))
.addParameter(name: "username", value: "jdoe")
.addParameter(name: "password", value: "pass123")
```
> **NOTE:** Any `String` parameter that evaluates to the **Empty String** (`""`) will automatically be excluded. The same goes for parameters that evaluate to `nil`. You do not need to specify `onCondition` for these types of values.
### Enum Values
An `Enum` that has a `rawValue` of either `String` or `Int` and also conforms to `Hashable` can be used without explicitly specifying `rawValue` when adding a parameter. See:
```swift
enum UserAccoutType: String, Hashable {
case guest = "guest"
case registered = "registered"
}
let sessionID:Int = 0
let username = "YOUR_USERNAME"
let password = "YOUR_PASSWORD"
let endpoint = URLBuilder("https://login")
.addParameter(name: "username", value: username)
.addParameter(name: "password", value: password)
.addParameter(name: "type", value: UserAccountType.guest)
```
### HTTPBodyBuilder
`UrlUtilities` include methods for constructing a `URLRequest` body using similar parameter builders. Take the following example:
```swift
let apiKey: String = "YOUR_API_KEY"
let sessionID:Int = 0
let username = "YOUR_USERNAME"
let password = "YOUR_PASSWORD"
// Assemble post body.
let body = HTTPBodyBuilder("""
{
"user": "<user>",
"password": "<password>",
"type": "<type>"
}
""")
.addParameter(name: "user", value: username)
.addParameter(name: "password", value: password)
.addParameter(name: "type", value: UserAccoutType.guest)
// Get the string contents
let endpoint = body.dataString
// Get the body data
let data = body.data
```
### Default Parameters
Both `URLBuilder` and `HTTPBodyBuilder` allow you to define a set of **Default Parameters** that will be included in every `URLBuilder` and `HTTPBodyBuilder` created. This is useful for items like **API Keys** that must be sent to every **RESTful API Endpoint** call.
For example:
```swift
let apiKey: String = "YOUR_API_KEY"
let sessionID:Int = 0
// Set API Key
URLBuilder.addDefaultParameter(name: "api_key", value: apiKey)
let endpoint = URLBuilder("https://login")
.addParameter(name: "username", value: "jdoe")
.addParameter(name: "password", value: "pass123")
.addParameter(name: "sessionID", value: sessionID, onCondition: (sessionID != 0))
.urlString
// Get the string value
// "https://login?api_key=YOUR_API_KEY&username=jdoe&password=pass123"
let validation = endpoint.urlString
```
`addDefaultParameter` works exactly like `addParameter` and excepts the same data types.
> **NOTE:** If you define a **Default Parameter**, you can override it later with a `addParameter` call with the same **Parameter Name**. This will only affect the current `URLBuilder` or `HTTPBodyBuilder` instance.
>
> To affect all subsequent instances, call `addDefaultParameter` call with the same **Parameter Name**.
### Finding and Deleting Parameters
Both `URLBuilder` and `HTTPBodyBuilder` allow you to find and delete both **Parameters** and **Default Parameters**. For example:
```swift
let apiKey: String = "YOUR_API_KEY"
let sessionID:Int = 0
// Set API Key
URLBuilder.addDefaultParameter(name: "api_key", value: apiKey)
let endpoint = URLBuilder("https://login")
.addParameter(name: "username", value: "jdoe")
.addParameter(name: "password", value: "pass123")
.addParameter(name: "sessionID", value: sessionID, onCondition: (sessionID != 0))
// Find user name
let name = endpoint.findParameter("username")
// Remove the default API Key
endpoint.deleteParameter("api_key")
```
### Building URLRequests
`UrlUtilities` extends the `URLRequest` class with convenience constructors that handle typical requests. Take the following example:
```swift
let apiKey: String = "YOUR_API_KEY"
let sessionID:Int = 0
// Set api key
URLBuilder.addDefaultParameter(name: "api_key", value: apiKey)
let endpoint = URLBuilder("https://create-user")
.addParameter(name: "user", value: username)
.addParameter(name: "password", value: password)
.addParameter(name: "sessionID", value: sessionID, onCondition: (sessionID != 0))
guard let url = endpoint.url else {
// Failed to create URLRequest"
return
}
// Assemble post body.
let body = HTTPBodyBuilder("""
{
"user": <user>,
"password": "<password>",
"type": "<type>"
}
""")
.addParameter(name: "username", value: "jdoe")
.addParameter(name: "password", value: "pass123")
.addParameter(name: "type", value: UserAccoutType.registered)
let request = URLRequest.build(url: url, data: body.data)
```
There is an additional version of `URLRequest.build` that doesn't require a body:
```swift
let apiKey: String = "YOUR_API_KEY"
let sessionID:Int = 0
// Set api key
URLBuilder.addDefaultParameter(name: "api_key", value: apiKey)
let endpoint = URLBuilder("https://delete-user")
.addParameter(name: "user", value: username)
.addParameter(name: "sessionID", value: sessionID, onCondition: (sessionID != 0))
guard let url = endpoint.url else {
// Failed to create URLRequest"
return
}
let request = URLRequest.build(url: url, method: .delete)
```
#### Default Authorization
When assembling a `URLRequest` with `build` if you set the `URLRequest.defaultAuthorization` to a string value first, it will automatically be added to the `allHTTPHeaderFields` under the `Authorization` key.
For example, if you are using a **Bearer Token** to authorize your requests, you could do the following:
```swift
let bearerToken: String = "YOUR_BEARER_TOKEN"
let sessionID:Int = 0
// Set the Bearer Token
URLRequest.defaultAuthorization = "Bearer \(bearerToken)"
let endpoint = URLBuilder("https://delete-user")
.addParameter(name: "user", value: username)
.addParameter(name: "sessionID", value: sessionID, onCondition: (sessionID != 0))
guard let url = endpoint.url else {
// Failed to create URLRequest"
return
}
let request = URLRequest.build(url: url, method: .delete)
```
# Documentation
The **Package** includes full **DocC Documentation** for all of its features.Package Metadata
Repository: Appracatappra/UrlUtilities
Stars: 1
Forks: 0
Open issues: 0
Default branch: main
Primary language: swift
License: MIT
README: README.md