Networking in iOS (Swift)
Networking in iOS is the process of communicating with APIs, servers, and internet resources to send or receive data.
Networking in iOS (Swift)
URL in Swift
URL represents an internet address or API endpoint.
1
let url = URL(string: "https://jsonplaceholder.typicode.com/users")
URLSession
URLSession is the main networking API in iOS used to perform HTTP requests. It supports:
- GET request
- POST request
- PUT request
- DELETE request
- Uploading
- Downloading
Simple GET Request
Fetch Data from API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
struct ContentView: View {
var body: some View {
Button("Fetch Users") {
// Call API
fetchUsers()
}
}
// API request function
func fetchUsers() {
// API URL
guard let url = URL(
string: "https://jsonplaceholder.typicode.com/users"
) else {
return
}
// Create network request
URLSession.shared.dataTask(
with: url
) { data, response, error in
// Handle error
if let error = error {
print(error.localizedDescription)
return
}
// Check response data
if let data = data {
// Convert data to string
let result = String(
data: data,
encoding: .utf8
)
print(result ?? "")
}
}.resume()
}
}
Codable
Codable converts JSON into Swift objects automatically. It combines:
- Encodable
- Decodable
Example: API JSON Response
1
2
3
4
{
"id": 1,
"name": "John"
}
Convert JSON into Swift Model
1
2
3
4
struct User: Codable {
let id: Int
let name: String
}
Parse API Response
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
func fetchUser() {
// API URL
guard let url = URL(
string: "https://jsonplaceholder.typicode.com/users/1"
) else {
return
}
// Fetch data
URLSession.shared.dataTask(
with: url
) { data, response, error in
// Ensure data exists
guard let data = data else {
return
}
do {
// Decode JSON data
let user = try JSONDecoder()
.decode(User.self, from: data)
print(user.name)
} catch {
print(error.localizedDescription)
}
}.resume()
}
HTTP Methods
GET Request
Used to fetch data.
1
request.httpMethod = "GET"
POST Request
Used to create new data.
1
request.httpMethod = "POST"
PUT Request
Used to update existing data.
1
request.httpMethod = "PUT"
DELETE Request
Used to remove data.
1
request.httpMethod = "DELETE"
POST Request Example
Send Data to API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
struct PostData: Codable {
let title: String
let body: String
}
func createPost() {
// API URL
guard let url = URL(
string: "https://jsonplaceholder.typicode.com/posts"
) else {
return
}
// Create request object
var request = URLRequest(url: url)
// Set request method
request.httpMethod = "POST"
// Set header
request.setValue(
"application/json",
forHTTPHeaderField: "Content-Type"
)
// Request body model
let post = PostData(
title: "Hello",
body: "Networking in Swift"
)
do {
// Convert object into JSON data
request.httpBody = try JSONEncoder()
.encode(post)
} catch {
print(error.localizedDescription)
}
// Send request
URLSession.shared.dataTask(
with: request
) { data, response, error in
print("Post Created")
}.resume()
}
Async Await
Swift supports async networking using async/await.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func fetchUsers() async {
// API URL
guard let url = URL(
string: "https://jsonplaceholder.typicode.com/users"
) else {
return
}
do {
// Fetch data
let (data, response) = try await URLSession.shared
.data(from: url)
// Decode JSON
let users = try JSONDecoder()
.decode([User].self, from: data)
print(users)
} catch {
print(error.localizedDescription)
}
}
API Headers
Headers provide extra information to the server.
Example:
- Authorization
- Content-Type
- Language
- Token
1
2
3
4
5
// Authorization header
request.setValue(
"Bearer TOKEN_HERE",
forHTTPHeaderField: "Authorization"
)
Error Handling
1
2
3
4
5
6
7
if let error = error {
// Print error message
print(error.localizedDescription)
return
}
Update UI on Main Thread
1
2
3
4
5
DispatchQueue.main.async {
// Update UI safely
self.users = decodedUsers
}
ObservableObject Networking
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class UserViewModel: ObservableObject {
// Published users array
@Published var users: [User] = []
// Fetch users
func fetchUsers() {
// API URL
guard let url = URL(
string: "https://jsonplaceholder.typicode.com/users"
) else {
return
}
// Network request
URLSession.shared.dataTask(
with: url
) { data, response, error in
// Ensure data exists
guard let data = data else {
return
}
do {
// Decode JSON response
let decodedUsers = try JSONDecoder()
.decode([User].self, from: data)
// Update UI safely
DispatchQueue.main.async {
self.users = decodedUsers
}
} catch {
print(error.localizedDescription)
}
}.resume()
}
}
MVVM Networking Structure
Model
Represents API data.
1
2
3
4
5
struct User: Codable {
let id: Int
let name: String
}
ViewModel
Handles business logic and networking.
1
2
3
class UserViewModel: ObservableObject {
}
View
Displays UI.
1
2
3
struct ContentView: View {
}
This post is licensed under CC BY 4.0 by the author.