HttpUtility is a light weight open source MIT license project which is helpful in making HTTP requests to the server. It uses URLSession to make requests to the API and returns the Result enum containing the decoded object in case of success or a error incase of failure. Right now this utility only decodes JSON response returned by the server.
Most of the time iOS application just perform simple HTTP operations which include sending request to the server and getting a response and displaying it to the user. If your iOS app does that then you may use this utility which does not do too much of heavy lifting and just pushes your request to the server and returns you a decoded object.
CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate HttpUtility into your Xcode project using CocoaPods, specify it in your Podfile:
pod 'HttpUtility', '~> 1.2'
HttpUtility can be used for basic http operations like get, post, put and delete. It uses URLSession to perform operations and is just a wrapper around it.
The best thing about this utility is that it takes a simple URL and returns you a decoded object if the request is successful and returns an error if the request fails. Say good bye to writing loops and custom code to parse JSON response.
Given are the some of the examples on how you can make use of this utility
- Get request
- Post request
- Request with query string parameters
- Request with MultiPartFormData
- Request with authentication token
- Customize JSONDecoder in the Utility
- HUNetworkError
let utility = HTTPUtility.shared // using the shared instance of the utility to make the API call
let requestUrl = URL(string: "http://demo0333988.mockable.io/Employees")
let request = HURequest(withUrl: requestUrl!, forHttpMethod: .get)
utility.request(huRequest: request, resultType: Employees.self) { (response) in
switch response
{
case .success(let employee):
// code to handle the response
case .failure(let error):
// your code here to handle error
}
}
The httpUtility has an extra parameter "requestBody" where you should attach the data that you have to post to the server, in the given example the RegisterUserRequest is a struct inheriting from the Encodable protocol
let utiltiy = HttpUtility.shared // using the shared instance of the utility to make the API call
let requestUrl = URL(string: "https://api-dev-scus-demo.azurewebsites.net/api/User/RegisterUser")
let registerUserRequest = RegisterUserRequest(firstName: "code", lastName: "cat15", email: "[email protected]", password: "1234")
let registerUserBody = try! JSONEncoder().encode(registerUserRequest)
let request = HURequest(withUrl: requestUrl!, forHttpMethod: .post, requestBody: registerUserBody)
utility.request(huRequest: request, resultType: RegisterResponse.self) { (response) in
switch response
{
case .success(let registerResponse):
// code to handle the response
case .failure(let error):
// your code here to handle error
}
let utiltiy = HttpUtility.shared // using the shared instance of the utility to make the API call
let request = PhoneRequest(color: "Red", manufacturer: nil)
// using the extension to convert the encodable request structure to a query string url
let requestUrl = request.convertToQueryStringUrl(urlString:"https://api-dev-scus-demo.azurewebsites.net/api/Product/GetSmartPhone")
let request = HURequest(withUrl: requestUrl!, forHttpMethod: .get)
utility.request(huRequest: request, resultType: PhoneResponse.self) { (response) in
switch response
{
case .success(let phoneResponse):
// code to handle the response
case .failure(let error):
// your code here to handle error
}
}
let utiltiy = HttpUtility.shared // using the shared instance of the utility to make the API call
let requestUrl = URL(string: "https://api-dev-scus-demo.azurewebsites.net/TestMultiPart")
// your request model struct should implement the encodable protocol
let requestModel = RequestModel(name: "Bruce", lastName: "Wayne")
let multiPartRequest = HUMultiPartRequest(url: requestUrl!, method: .post, request: requestModel)
utility.requestWithMultiPartFormData(multiPartRequest: multiPartRequest, responseType: TestMultiPartResponse.self) { (response) in
switch response
{
case .success(let serviceResponse):
// code to handle the response
case .failure(let error):
// code to handle failure
}
}
let utility = HttpUtility.shared
let token = "your_token"
utility.authenticationToken = token
if you are using a basic or a bearer token then make sure you put basic or bearer before your token starts
let basicToken = "basic your_token"
let utility = HttpUtility.shared
utility.authenticationToken = basicToken
let bearerToken = "bearer your_token"
let utility = HttpUtility.shared
utility.authenticationToken = bearerToken
At times it may happen that you may need to control the behaviour of the default JSONDecoder being used to decode the JSON, for such scenarios the HTTPUtility provides a default init method where you can pass your own custom JSONDecoder and the HTTPUtility will make use of that Decoder and here's how you can do it
let customJsonDecoder = JSONDecoder()
customJsonDecoder.dateEncoding = .millisecondsSince1970
let utility = HttpUtility.shared
utility.customJsonDecoder = customJsonDecoder
At times when you pass the token and the default JSONDecoder is just not enough, then you may use the init method of the utility to pass the token and a custom JSONDecoder both to make the API request and parse the JSON response
let utility = HttpUtility.shared
let customJsonDecoder = JSONDecoder()
customJsonDecoder.dateEncoding = .millisecondsSince1970
let bearerToken = "bearer your_token"
utility.customJsonDecoder = customJsonDecoder
utility.authenticationToken = bearerToken
The HUNetworkError structure provides in detail description beneficial for debugging purpose, given are the following properties that will be populated in case an error occurs
-
Status: This will contain the HTTPStatus code for the request that we receive from the server.
-
ServerResponse: This will be the JSON string of the response you received from the server. (not to be confused with error parameter) on error if server returns the error JSON data that message will be decoded to human readable string.
-
RequestUrl: The request URL that you just called.
-
RequestBody: If you get failure on POST request this property would contain a string representation of the HTTPBody that was sent to the server.
-
Reason: This property would contain the debug description from the error closure parameter.
This utility is for performing basic tasks, and is currently evolving, but if you have any specific feature in mind then please feel free to drop a request and I will try my best to implement it