GTRest
A lightweight Swift library for making web requests and consuming RESTful APIs!
On this page
- Making Requests
- Request Results
- Request HTTP Headers
- URL Query and HTTP Body Parameters
- Response HTTP Headers
- File Uploading
- Fetching Single Data
- Converting Raw Data To Custom Types
- Additional Notes
Making Requests
Make a web request by calling makeRequest(toURL:httpMethod:completion:)
method. Provide the URL (URL
object) and the HTTP method (a GTRest.HttpMethod
value).
Completion handler returns a GTRest.Results
object.
Example:
let url = URL(...) // A URL object.
let rest = GTRest()
rest.makeRequest(toURL: url, httpMethod: .get) { [unowned self] (results) in // or [weak self] (results) in
// Handle results
// Update your UI on main thread always:
DispatchQueue.main.async {
// Update UI.
}
}
Request Results
Request results are represented by a GTRest.Results
object. Completion handlers in makeRequest(toURL:withHttpMethod:completion:)
and upload(files:toURL:withHttpMethod:completion:)
methods return such an object.
let url = URL(...) // A URL object.
let rest = GTRest()
rest.makeRequest(toURL: url, httpMethod: .get) { [unowned self] (results) in // or [weak self] (results) in
// Access data returned by the server:
if let data = results.data {
// Perform app-specific actions
}
// Access the response:
if let response = results.response {
// Do something with the response object if necessary.
// Checking the HTTP status code :
if (200...299).contains(response.httpStatusCode) {
// Successful request.
} else { ... }
}
// Access the error:
if let error = results.error {
// Do something with the error.
}
// Update your UI on main thread always:
DispatchQueue.main.async {
// Update UI.
}
}
Request HTTP Headers
Use requestHttpHeaders
property to set any required HTTP headers to the request.
Example:
var rest = GTRest()
rest.requestHttpHeaders.add(value: "application/json", forKey: "Content-Type")
Common request headers and MIME types are provided through the GTRest.HttpHeader
and GTRest.MimeType
custom types respectively.
rest.requestHttpHeaders.add(value: GTRest.MimeType.applicationJson.rawValue,
forKey: GTRest.HttpHeader.contentType.rawValue)
Multiple headers can be added as well:
let requestHeaders = ["Content-type": "application/json", "Authorization": "Bearer abc123"]
rest.requestHttpHeaders.add(multipleValues: requestHeaders)
URL Query and HTTP Body Parameters
Use urlQueryParameters
property to set URL query parameters before making the request.
rest.urlQueryParameters.add(value: "gabriel", forKey: "username")
rest.urlQueryParameters.add(value: "37", forKey: "age")
// Result in the URL:
// https://yourURL?username=gabriel&age=37
Multiple values can be added at once here too:
let params = ["username": "gabriel", "age": "37"]
rest.urlQueryParameters.add(multipleValues: params)
In a similar fashion HTTP body parameters can be also set:
// Single parameter:
rest.httpBodyParameters.add(value: "gabriel", forKey: "username")
// Multiple parameters:
let params = ["username": "gabriel", "age": "37"]
rest.httpBodyParameters.add(multipleValues: params)
Important Note: Use httpBodyParameters
property when application/json
or application/x-www-form-urlencoded
content type has been specified as a request HTTP header. For any other content type, assign the HTTP body data directly to the httpBody
property.
Response HTTP Headers
Any response HTTP headers returned by the server can be accessed through the headers
property of the GTRest.Response
object in the GTRest.Results
results.
headers
is a GTRest.ResponseHeaders
object.
rest.makeRequest(toURL: url, httpMethod: .get) { [unowned self] (results) in // or [weak self] (results) in
// Access the response:
if let response = results.response {
// Access headers:
let headers = response.headers
}
}
File Uploading
Upload files using the upload(files:toURL:withHttpMethod:completion:)
method.
A file is described by a GTRest.FileInfo
object.
Important: multipart/form-data; boundary=xxx
is the content type used for web requests made through this method. You do not have to provide it, it is automatically set.
Example:
var rest = GTRest()
// Prepare the files that will be uploaded.
var resume = GTRest.FileInfo()
resume.fileContents = ... // File contents data
resume.mimetype = "application/pdf" // or GTRest.MimeType.applicationPDF.rawValue
resume.filename = "resume.pdf"
var avatar = GTRest.FileInfo()
avatar.fileContents = ... // File contents data
avatar.mimetype = GTRest.MimeType.imagePNG.rawValue
avatar.filename = "avatar.png"
// Optionally, set any request HTTP methods, but not the "content-type".
// Also, set any required URL query or HTTP body parameters.
// Prepare the URL.
let url = ... // A URL object.
rest.upload(files: [resume, avatar], toURL: url, withHttpMethod: .post) { [unowned self] (results, failedFiles) in // or [unowned self] (results, failedFiles) in
if let failedFiles = failedFiles {
// Do something with the files that failed to be uploaded.
}
// Do something with the results.
if let data = results.data {
// ...
}
// Update your UI on main thread always:
DispatchQueue.main.async {
// Update UI.
}
}
Fetching Single Data
Fetch single data with the getData(fromURL:completion:)
method.
This method is useful for fetching single data from a URL, usually the contents of a file. For example, the image data for a user profile picture, or the contents of a PDF file.
Example:
let rest = GTRest()
rest.getData(fromURL: url) { [unowned self] (data) in // or [weak self] (data) in
if let data = data {
// Do something with the fetched data.
}
}
Converting Raw Data To Custom Types
GTRest.Results
object returned when making requests provides a convenient method named convertData(toType:decoderConfiguration:)
. Its purpose is to convert raw fetched data from JSON (a Data
object) into a custom type by decoding it using JSONDecoder.
It is required that custom type must conform to Decodable or Codable protocol.
JSONDecoder object used to decode data in that method can be configured in the decoderConfiguration
handler. Keep it nil in case you don’t want to make any configuration to JSONDecoder instance.
In case decoding fails an exception is thrown by the method.
Example:
Consider the following struct:
struct User: Codable {
var id: Int?
var firstName: String?
var lastName: String?
}
Also, the following data fetched from server:
{
"id": 325,
"first_name": "Gabriel",
"last_name": "Theodoropoulos"
}
Here’s how to convert fetched user data, using the decoderConfiguration
to set the convertFromSnakeCase
as the keyDecodingStrategy
:
let rest = GTRest()
let url = URL(...)
// Additional configuration...
rest.makeRequest(toURL: url, withHttpMethod: .get) { (results) in
do {
if let user = try results.convertData(toType: User.self, decoderConfiguration: { (decoder) in
decoder.keyDecodingStrategy = .convertFromSnakeCase
}) {
// User data has been successfully converted into a `User` object.
print(user)
}
} catch {
print(error.localizedDescription)
}
}
Additional Notes
requestHttpHeaders
,urlQueryParameters
,httpBodyParameters
andheaders
property inGTRest.Response
type are objects of theGTRest.RestEntity
custom type. It adopts theGTKeyValueManageable
protocol which makes the following methods available:add(value:forKey:)
add(multipleValues:)
value(forKey:)
getStorageValues()
totalItems()
- All web requests are performed asynchronously in background threads.
- Optionally use
GTRest.HttpHeader
andGTRest.MimeType
custom types for common request header and MIME type values.
Created by Gabriel Theodoropoulos