If you have been diving deep into iOS development you may have already come across accessing data/databases using URLSession, this is fine and all but sometimes it gets annoying to use, this is where Alamofire comes in. So what is Alamofire?
What is Alamofire?
Alamofire is an elegant and composable way to interface to HTTP network requests. It builds on top of Apple’s URL Loading System provided by the Foundation framework. At the core of the system is URLSession and the URLSessionTask subclasses. Alamo fire wraps these APIs, and many others, in an easier to use interface and provides a variety of functionality necessary for modern application development using HTTP networking.
Part 1: Installation
You need to have cocoapods installed for this, once that is ready, let’s create our xcode project. For this example we have created an xcode project called AlamofireTest.
We’ll be using Cocoapods to install the Alamofire library. If need to set up Cocoapods on your system first, check out my Cocoapods tutorial.
Now navigate to your project folder and open a terminal window, also navigate the terminal window to the project location.
Once there you should do a “pod init” in your terminal
It will then output a file named Podfile.
Open the Podfile in Textedit and add the line pod “Alamofire”, “[version number]” or just simply pod “Alamofire”
Save the file and in your terminal do a pod install, once it has finished installation it should have created a Pods folder, [projectname].xcworkspace, and a Podfile.lock.
Open the file named [projectname.xcworkspace] and your project should have Alamofire installed and ready to go
Part 2: Using Alamofire
Simple Request
For this example we will be using httpbin.org to simulate our http calls.
For starters let’s do a simple GET request, in your ViewController.swift type the following:
Save and run the program, once it runs it should print out in the debug log like this
Its as simple as that!. There are also other HTTP Method calls like POST, PUT, DELETE, ETC.
To do so its as simple as adding a method in the Alamofire request by using their already pre-built enums for it. Just simply type:
// POST AF.request("https://httpbin.org/post", method: .post) // PUT AF.request("https://httpbin.org/put", method: .put) // DELETE AF.request("https://httpbin.org/delete", method: .delete)
Request with Parameters
Not all HTTP Requests are plain and simple, most pages need information like account information, page information, category, etc. these can be easily done in Alamofire by doing so:
let parameters = ["category": "Movies", "genre": "Action"] AF.request("https://httpbin.org/get", parameters: parameters).response { response in debugPrint(response) } //this is equivalent to https://httpbin.org/get?category=Movies&genre=Action
Nice and easy right?
HTTP Headers
Alamofire has its own support for HTTP Headers which are a great way to let the client and the server pass additional information with an HTTP request or response. It can be easily added to our Alamofire Request easily by just adding an HTTPHeaders value:
let headers: HTTPHeaders = [ .authorization(username: "test@email.com", password: "testpassword"), .accept("application/json") ] AF.request("https://httpbin.org/headers", headers: headers).responseJSON { response in debugPrint(response) }
It can also be easily combined with other options like sending parameters:
let headers: HTTPHeaders = [ .authorization(username: "test@email.com", password: "testpassword"), .accept("application/json") ] let parameters = ["category": "Movies", "genre": "Action"] AF.request("https://httpbin.org/headers", headers: headers, parameters: parameters).responseJSON { response in debugPrint(response) }
Handling Authorization
There are a few ways to handle authentication using Alamofire, one of them is via Header as shown in the example above, the others are more direct or make use of the URLCredential data type, here are some examples:
// Normal way to authenticate using the .authenticate with username and password let user = "test@email.com" let password = "testpassword" AF.request("https://httpbin.org/basic-auth/\(user)/\(password)") .authenticate(username: user, password: password) .responseJSON { response in debugPrint(response) } // Authentication using URLCredential let credential = URLCredential(user: user, password: password, persistence: .forSession) AF.request("https://httpbin.org/basic-auth/\(user)/\(password)") .authenticate(with: credential) .responseJSON { response in debugPrint(response) }
Response Handling
Alamofire support different ways on how to handle a response. A response is expected to provide the client with the resource it requested, or inform the client that the action it requested has been carried out; or else to inform the client that an error occurred in processing its request.
Basic Response
This basic response does not evaluate any of the response data it just forwards information directly from URLSessionDelegate. Think of it as the Alamofire equivalent of cURL to execute a request.
AF.request("https://httpbin.org/get").response { response in debugPrint("Response: \(response)") }
JSON Response
The responseJSON handler uses a JSONResponseSerializer to convert the Data returned by the server into an Any type using the specified JSONSerialization.ReadingOptions.
AF.request("https://httpbin.org/get").responseJSON { response in debugPrint("Response: \(response)") }
Data Response
The responseData handler uses a DataResponseSerializer to extract and validate the Data returned by the server.
AF.request("https://httpbin.org/get").responseData { response in debugPrint("Response: \(response)") }
String Response
The responseString handler uses a StringResponseSerializer to convert the Data returned by the server into a String with the specified encoding.
AF.request("https://httpbin.org/get").responseString { response in debugPrint("Response: \(response)") }
Decodable Response
The responseDecodable handler uses a DecodableResponseSerializer to convert the Data returned by the server into the passed Decodable type using the specified DataDecoder
struct HTTPBinResponse: Decodable { let url: String } AF.request("https://httpbin.org/get").responseDecodable(of: HTTPBinResponse.self) { response in debugPrint("Response: \(response)") }
File Download/Handling
Alamofire supports multiple ways of handling data, some data is fine by just fetching by memory, but for larger sets of data Session.download, DownloadRequest, and DownloadResponse is also supported.
Fetch in Memory
Basic fetching of an image by memory, it is not saved and will require loading again if being fetched again.
AF.download("https://httpbin.org/image/png").responseData { response in if let data = response.value { self.imageView.image = UIImage(data: data) } }
Download locally
Alamofire supports downloading of file to make it easier to access, think of it as a copy for faster loading like a cache:
=
let destination: DownloadRequest.Destination = { _, _ in let documentsURL = FileManager.default.urls(for: .picturesDirectory, in: .userDomainMask)[0] let fileURL = documentsURL.appendingPathComponent("image.png") return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) } AF.download("https://httpbin.org/image/png", to: destination).response { response in debugPrint(response) if response.error == nil, let imagePath = response.fileURL?.path { let image = UIImage(contentsOfFile: imagePath) } }
Uploading Data/Files
Uploading data is somewhat easy, you just need to specify what kind of Data you are sending and let alamofire do the rest, it works the same as a POST.
let data = Data("data".utf8) AF.upload(data, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response) }
It is also possible to send a multipart form data like so:
AF.upload(multipartFormData: { multipartFormData in multipartFormData.append(Data("one".utf8), withName: "one") multipartFormData.append(Data("two".utf8), withName: "two") }, to: "https://httpbin.org/post") .responseJSON { response in debugPrint(response) }
You can also upload files via Alamofire by simply specifying the file name and it’s extension:
let fileURL = Bundle.main.url(forResource: "video", withExtension: "mp4")! AF.upload(fileURL, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response) }
Upload/Download Progress
We now know that Alamofire supports both downloading and uploading of files, but how do we track the progress of our upload/download as it happens? There is an option for that, just simply add a .downloadProgress or .uploadProgress just before your response like so:
// For downloadProgress let destination: DownloadRequest.Destination = { _, _ in let documentsURL = FileManager.default.urls(for: .picturesDirectory, in: .userDomainMask)[0] let fileURL = documentsURL.appendingPathComponent("image.png") return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) } AF.download("https://httpbin.org/image/png", to: destination) .downloadProgress { progress in print("Download Progress: \(progress.fractionCompleted)") } .response { response in debugPrint(response) if response.error == nil, let imagePath = response.fileURL?.path { let image = UIImage(contentsOfFile: imagePath) } } // For uploadProgress let fileURL = Bundle.main.url(forResource: "video", withExtension: "mp4")! AF.upload(fileURL, to: "https://httpbin.org/post") .uploadProgress { progress in print("Upload Progress: \(progress.fractionCompleted)") } .responseJSON { response in debugPrint(response.response) }
Conclusion
That’s about it for this essential guide to Swift Alamofire, with these information you should be equipped enough to utilize Alamofire in your swift project, if you ever need extra info you can check out the official guide and documentation here. Good luck and have fun coding! 🙂
Further Reading
- CocoaPods Tutorial using Swift and Xcode: Learn how to install and use Cocoapods in your Xcode project! Take advantage of third party Swift libraries and GitHub repositories easily.
- How To Use SwiftyJSON: SwiftyJSON is a Swift library for reading and processing JSON data. Learn how easy it is to use it and how it’s different from Codable and JSONSerialization
- How To Submit Your App To the App Store: Learn how to submit your app to the App Store with App Store Connect the right way!