Swift Networking
Making HTTP requests and handling network data
🌐 What is Swift Networking?
Swift networking involves making HTTP requests to web APIs, downloading data, and handling responses. URLSession is the primary framework for network operations in iOS apps.
// Simple GET request
let url = URL(string: "https://api.example.com/data")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
// Handle response
}
task.resume()
Networking Components
URLSession
Main networking class
let session = URLSession.shared
// or custom configuration
URLRequest
Configure HTTP requests
var request = URLRequest(url: url)
request.httpMethod = "POST"
Data Tasks
Handle data responses
session.dataTask(with: request) {
data, response, error in
}
JSON Parsing
Decode JSON responses
let decoder = JSONDecoder()
let result = try decoder.decode(Model.self, from: data)
🔹 Basic GET Request
Fetch data from a web API:
func fetchData() {
guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1") else {
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}
guard let data = data else {
print("No data received")
return
}
// Parse JSON
do {
let post = try JSONDecoder().decode(Post.self, from: data)
print("Title: \(post.title)")
} catch {
print("JSON parsing error: \(error)")
}
}.resume()
}
🔹 POST Request with JSON
Send data to a server:
func postData() {
guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let newPost = Post(title: "New Post", body: "Post content", userId: 1)
do {
let jsonData = try JSONEncoder().encode(newPost)
request.httpBody = jsonData
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}
print("Post created successfully!")
}.resume()
} catch {
print("Encoding error: \(error)")
}
}
🔹 Data Models with Codable
Define models for JSON parsing:
struct Post: Codable {
let id: Int?
let title: String
let body: String
let userId: Int
}
struct User: Codable {
let id: Int
let name: String
let email: String
let phone: String?
// Custom key mapping
enum CodingKeys: String, CodingKey {
case id
case name
case email
case phone
}
}
🔹 Error Handling
Handle network errors properly:
enum NetworkError: Error {
case invalidURL
case noData
case decodingError
case serverError(Int)
}
func fetchWithErrorHandling() {
// ... URL setup ...
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Network error: \(error.localizedDescription)")
return
}
guard let httpResponse = response as? HTTPURLResponse else {
print("Invalid response")
return
}
guard 200...299 ~= httpResponse.statusCode else {
print("Server error: \(httpResponse.statusCode)")
return
}
guard let data = data else {
print("No data received")
return
}
// Process data...
}.resume()
}
🔹 Async/Await Networking
Modern Swift networking with async/await:
func fetchDataAsync() async throws -> Post {
guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1") else {
throw NetworkError.invalidURL
}
let (data, response) = try await URLSession.shared.data(from: url)
guard let httpResponse = response as? HTTPURLResponse,
200...299 ~= httpResponse.statusCode else {
throw NetworkError.serverError(0)
}
return try JSONDecoder().decode(Post.self, from: data)
}
// Usage
Task {
do {
let post = try await fetchDataAsync()
print("Post title: \(post.title)")
} catch {
print("Error: \(error)")
}
}