4οΈβ£URLSession
Fall 2023 | Vin Bui
In the previous sections, we used Alamofire to send network requests. Although Alamofire is very elegant and simple to use, there are times when we want to use native Swift to send network requests. We can do this with URLSession.
GET Requests
Letβs take a look at the Alamofire version from the previous section:
// 1. Create the function
func fetchRoster(completion: @escaping ([Member]) -> Void) {
// 2. Specify the endpoint
let endpoint = "<Enter URL String Here>"
// 3. Create a decoder
let decoder = JSONDecoder()
// decoder.dateDecodingStrategy = .iso8601 // Only if needed
// decoder.keyDecodingStrategy = .convertFromSnakeCase // Only if needed
// 4. Create the request
AF.request(endpoint, method: .get)
.validate()
.responseDecodable(of: [Member].self, decoder: decoder) { response in
// 5. Handle the response
switch response.result {
case .success(let members):
print("Successfully fetched \(members.count) members")
completion(members)
case .failure(let error):
print("Error in NetworkManager.fetchRoster: \(error)")
}
}
}
We can do the same exact thing using URLSession (only steps after Step 3 are different):
// 1. Create the function
func fetchRoster(completion: @escaping ([Member]) -> Void) {
// 2. Specify the endpoint
let endpoint = "<Enter URL String Here>"
// 3. Create a decoder
let decoder = JSONDecoder()
// decoder.dateDecodingStrategy = .iso8601 // Only if needed
// decoder.keyDecodingStrategy = .convertFromSnakeCase // Only if needed
// 4. Create a URLRequest
var urlRequest = URLRequest(url: URL(string: endpoint)!)
urlRequest.httpMethod = "GET"
// 5. Create and resume the task
URLSession.shared.dataTask(with: urlRequest) { data, response, error in
// 6. Handle the response (you can also do something with `response`)
guard error == nil, let data else {
print("Error in NetworkManager.fetchRoster: \(error)")
return
}
if let members = try? decoder.decode([Member].self, from: data) {
completion(members)
}
}
.resume()
}
POST Requests
Letβs take a look at a POST request using Alamofire:
// 1. Create the function
func addToRoster(member: Member, completion: @escaping (Member) -> Void) {
// 2. Specify the endpoint
let endpoint = "<Enter URL String Here>"
// 3. Define the request body
let parameters: Parameters = [
"name": member.name,
"subteam": member.subteam,
"position": member.position
]
// 4. Create a decoder
let decoder = JSONDecoder()
// decoder.dateDecodingStrategy = .iso8601 // Only if needed
// decoder.keyDecodingStrategy = .convertFromSnakeCase // Only if needed
// 5. Create the request
AF.request(endpoint, method: .post, parameters: parameters, encoding: JSONEncoding.default)
.validate()
.responseDecodable(of: Member.self, decoder: decoder) { response in
// 5. Handle the response
switch response.result {
case .success(let member):
print("Successfully added member \(member.name)")
completion(member)
case .failure(let error):
print("Error in NetworkManager.addToRoster: \(error.localizedDescription)")
}
}
}
If we were to use URLSession, we need to:
Change the
httpMethod
property of theURLRequest
to"POST"
.Call the
setValue
function with("application/json", forHTTPHeaderField: "Content-Type")
.Set the
httpBody
property of theURLRequest
.The code below uses
JSONSerialization
to serialize the dictionaryparameters
to JSON and use it as the request body.Alternatively, we can also use a
JSONEncoder
to encode our object into JSON, but it wonβt be shown here.
// 1. Create the function
func addToRoster(member: Member, completion: @escaping (Member) -> Void) {
// 2. Specify the endpoint
let endpoint = "<Enter URL String Here>"
// 3. Define the request body
let parameters = [
"name": member.name,
"subteam": member.subteam,
"position": member.position
]
guard let httpBody = try? JSONSerialization.data(
withJSONObject: parameters,
options: []
) else { return }
// 4. Create a decoder
let decoder = JSONDecoder()
// decoder.dateDecodingStrategy = .iso8601 // Only if needed
// decoder.keyDecodingStrategy = .convertFromSnakeCase // Only if needed
// 5. Create a URLRequest
var urlRequest = URLRequest(url: URL(string: endpoint)!)
urlRequest.httpMethod = "POST"
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.httpBody = httpBody
// 6. Create and resume the task
URLSession.shared.dataTask(with: urlRequest) { data, response, error in
// 7. Handle the response (you can also do something with `response`)
guard error == nil, let data else {
print("Error in NetworkManager.addToRoster: \\(error)")
return
}
if let member = try? decoder.decode(Member.self, from: data) {
completion(member)
}
}
.resume()
}
Last updated
Was this helpful?