[25] iOS Network Flashcards

(62 cards)

1
Q

How to create a simple Error object for network requests?

A
enum GHError: Error {
    case invalidURL
    case invalidResponse
    case invalidData
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

How to create a simple URL?

A
let endpoint = "https://api.github.com/users/sallen0400"
    guard let url = URL(string: endpoint) else {
        throw GHError.invalidURL
    }
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

How to create a GET request?

A
let (data, response) = try await URLSession.shared.data(from: url)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Verify the GET request has a valid response

A
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
        throw GHError.invalidResponse
    }
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Common HTTP responses codes?

A

200 -> OK
400 -> Bad Request / Invalid sysntax or parameters
401 -> Authentication required or failed
403 -> Authenticated but not allowed
404 -> Resource not found
500 -> Generic Server Failure

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

How is the Object that will contain the decoded response

A
struct GitHubUser: Codable {
    // define JSON values here
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How to decode a response?

A
do {
        let decoder = JSONDecoder ()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        return try decoder.decode(GitHubUser.self, from: data)
    } catch {
        throw GHError.invalidData
    }
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What does this strategy do?
~~~
decoder.keyDecodingStrategy = .convertFromSnakeCase
~~~

A

The JSON response may have properties defined using the snake_case form. This will map the response’s properties to the swift Struct

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

How to implement a generic network request?

A
func getuser<T: Decodable>(for: T.Type) async throws -> T {
    let endpoint = "https://api.github.com/users/sallen0400"
    guard let url = URL(string: endpoint) else {
        throw GHError.invalidURL
    }
    let (data, response) = try await URLSession.shared.data(from: url)
    guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
        throw GHError.invalidResponse
    }
    do {
        let decoder = JSONDecoder ()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        return try decoder.decode(T.self, from: data)
    } catch {
        throw GHError.invalidData
    }
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

How to add query parameters to a URL?

A
var components = URLComponents(string: "https://api.example.com/search")!
components.queryItems = [
    URLQueryItem(name: "query", value: "swift"),
    URLQueryItem(name: "page", value: "1")
]
guard let url = components.url else {
    throw GHError.invalidURL
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How to handle optional query parameters in a URL?

A
var components = URLComponents(string: "https://api.example.com/users")!
var queryItems: [URLQueryItem] = []
if let username = optionalUsername {
    queryItems.append(URLQueryItem(name: "username", value: username))
}
components.queryItems = queryItems
guard let url = components.url else {
    throw GHError.invalidURL
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How to create a POST request using URLSession?

A
var request = URLRequest(url: url estampado
request.httpMethod = "POST"
let (data, response) = try await URLSession.shared.data(for: request)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

How to encode a JSON body for a POST request?

A
struct User: Codable {
    let name: String
    let email: String
}
let user = User(name: "John", email: "john@example.com")
let jsonData = try JSONEncoder().encode(user)
request.httpBody = jsonData
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

How to set custom HTTP headers in a request?

A
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("Bearer yourToken", forHTTPHeaderField: "Authorization")
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

How to handle Bearer token authentication?

A
let token = "your_access_token"
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

How to handle Basic authentication?

A
let credentials = "username:password"
let base64Credentials = credentials.data(using: .utf8)!.base64EncodedString()
request.setValue("Basic \(base64Credentials)", forHTTPHeaderField: "Authorization")
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

How to verify different HTTP status codes?

A
guard let httpResponse = response as? HTTPURLResponse,
      (200...299).contains(httpResponse.statusCode) else {
    throw GHError.invalidResponse
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

How to handle specific error responses from the server?

A
if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode != 200 {
    struct APIError: Codable, Error {
        let message: String
    }
    let error = try JSONDecoder().decode(APIError.self, from: data)
    throw error
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

How to create a PUT request for updating data?

A
request.httpMethod = "PUT"
request.httpBody = jsonData // encoded data
let (data, response) = try await URLSession.shared.data(for: request)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

How to create a DELETE request?

A
request.httpMethod = "DELETE"
let (data, response) = try await URLSession.shared.data(for: request)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

How to upload multipart form data?

A
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var body = Data()
body.append("--\(boundary)\r\n".data(using: .utf8)!)
body.append("Content-Disposition: form-data; name=\"param\"\r\n\r\nvalue\r\n".data(using: .utf8)!)
body.append("--\(boundary)--\r\n".data(using: .utf8)!)
request.httpBody = body
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

How to upload a file using URLSession?

A
let fileURL = URL(fileURLWithPath: "/path/to/file")
let request = URLRequest(url: uploadURL)
let data = try await URLSession.shared.upload(for: request, fromFile: fileURL).0
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

How to download a file asynchronously?

A
let (localURL, response) = try await URLSession.shared.download(from: url)
try FileManager.default.moveItem(at: localURL, to: destinationURL)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

How to resume a download task?

A
let resumeData = // previously saved data
let (localURL, response) = try await URLSession.shared.download(resumingWith: resumeData)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
How to set a timeout for a URLRequest?
``` request.timeoutInterval = 30.0 // seconds ```
26
How to configure a custom URLSession?
``` let configuration = URLSessionConfiguration.default configuration.timeoutIntervalForRequest = 20.0 let session = URLSession(configuration: configuration) let (data, response) = try await session.data(from: url) ```
27
How to handle redirects in URLSession?
``` configuration.httpShouldSetCookies = true // example related config // For manual handling, implement delegate methods if needed. ```
28
How to manage cookies in network requests?
``` let cookie = HTTPCookie(properties: [.name: "session", .value: "123", .path: "/", .domain: "example.com"])! HTTPCookieStorage.shared.setCookie(cookie) ```
29
How to implement caching for responses?
``` let cache = URLCache(memoryCapacity: 10 * 1024 * 1024, diskCapacity: 50 * 1024 * 1024, directory: nil) configuration.urlCache = cache request.cachePolicy = .returnCacheDataElseLoad ```
30
How to invalidate a cache entry?
``` URLCache.shared.removeCachedResponse(for: request) ```
31
How to handle multiple concurrent requests?
``` let users = try await withThrowingTaskGroup(of: GitHubUser.self) { group in for username in usernames { group.addTask { try await getUser(username) } } return try await group.reduce(into: []) { $0.append($1) } } ```
32
How to create a network manager class?
``` class NetworkManager { private let session: URLSession init() { let config = URLSessionConfiguration.default session = URLSession(configuration: config) } func fetch(url: URL) async throws -> T { let (data, _) = try await session.data(from: url) return try JSONDecoder().decode(T.self, from: data) } } ```
33
How to add retry logic to a network request?
``` for attempt in 0..<3 { do { return try await session.data(from: url) } catch { if attempt == 2 { throw error } try await Task.sleep(for: .seconds(pow(2, Double(attempt)))) } } ```
34
How to handle rate limiting?
``` if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 429, let retryAfter = httpResponse.value(forHTTPHeaderField: "Retry-After"), let seconds = Double(retryAfter) { try await Task.sleep(for: .seconds(seconds)) // retry } ```
35
How to use background URLSession for downloads?
``` let config = URLSessionConfiguration.background(withIdentifier: "com.example.background") let session = URLSession(configuration: config, delegate: self, delegateQueue: nil) let downloadTask = session.downloadTask(with: url) downloadTask.resume() ```
36
How to monitor network reachability?
``` import Network let monitor = NWPathMonitor() monitor.pathUpdateHandler = { path in if path.status == .satisfied { // connected } } monitor.start(queue: DispatchQueue.global()) ```
37
How to test network requests with mocks?
``` class MockURLProtocol: URLProtocol { static var responseData: Data? override class func canInit(with request: URLRequest) -> Bool { true } override func startLoading() { client?.urlProtocol(self, didReceive: HTTPURLResponse(), cacheStoragePolicy: .notAllowed) client?.urlProtocol(self, didLoad: MockURLProtocol.responseData ?? Data()) client?.urlProtocolDidFinishLoading(self) } override func stopLoading() {} } URLProtocol.registerClass(MockURLProtocol.self) ```
38
How to unit test a network manager?
``` let config = URLSessionConfiguration.ephemeral config.protocolClasses = [MockURLProtocol.self] let mockSession = URLSession(configuration: config) let manager = NetworkManager(session: mockSession) // inject MockURLProtocol.responseData = // json data let user = try await manager.fetch(url: url) XCTAssertNotNil(user) ```
39
How to handle WebSocket connections?
``` let wsTask = session.webSocketTask(with: wsURL) wsTask.resume() try await wsTask.send(.string("Hello")) let message = try await wsTask.receive() switch message { case .string(let text): print(text) default: break } ```
40
What is URLSessionConfiguration?
An URLSessionConfiguration object defines the behavior and policies to use when uploading and downloading data using an URLSession object.
41
How many types of URLSessionConfiguration there are?
There are 3: - Default - ephemeral - background
42
How does the URLSessionConfiguration.default ?
- Uses a disc based cache except when the result is downloaded to a. file. - It stores credentials in the user's keychain. - Uses default values for its properties unless you customize it.
43
How does the URLSessionConfiguration.ephemeral work?
Is like .default, but it doesn't store cookies, credentials or cache data to disk.
44
How does the URLSessionConfirugation.background(withIdentifier: ) works?
It can transfer data while the app runs in the background. Hands control of transfers over to the system which is handle by its own process.
45
What is important to know about Sessions and its attributes?
They must be set before the section becomes active. You cannot update the session's attributes after creation.
46
What attribute to configure in URLSessionConfiguration to allow connections in low data mode?
```.allowsConstrainedNetworkAccess```
47
What attribute to configure in URLSessionConfiguration to allow cellular connection or cellular hostPot?
```.allowsExpensiveNetworkAccess```
48
After I create a URLSessionConfiguration, how do I create a URLSession?
```let myDefaultSession = URLSession(configuration: myDefaultConfiguration)```
49
Once URLSession is created, what can I do with it?
Create ```URLSessionTask``` instances to transfer data to/from servers.
50
How to use efficiently these two objects? URLSession & URLSessionTask?
Create only one URLSession and many URLSessionTasks with it.
51
What are the 3 subclasses of ```URLSessionTask```?
1. URLSessionDataTask -> In-memory response & is not supported in background sessions. 2. URLSessionUploadTask -> similar to dataTask but easier to to provide a request body. 3. URLSessionDownloadTask -> response is written on disk
52
What is required to start a task ```URLSessionTask```?
call the resume() method.
53
How to request data using modern Swift concurrency?
``` let configuration = URLSessionConfiguration.default let session = URLSession(configuration: configuration) // create a url guard let url = URL(..... Task { let (data, response) = try await session.data(from: url) guard let httpResponse = response as? HTTPURLResponse, (200..<300).contains(httpResponse.statusCode), let dataString = String(data: data, encoding: .utf8) else { return } print(dataString) } ```
54
What is the default priority in a Task?
Default priority: 0.5 Range: 0.0 (low) to 1.0 (high) This can be changed at any time
55
How works the cache policy?
56
Difference between ```URLSessionDownloadTask``` and ```URLSessionDataTask```?
```URLSessionDataTask``` stores data in memory for short lived tasks. ```URLSessionDownloadTask``` stores data in a file
57
What do I get as a response after executing a ```URLSessionDownloadTask```?
Instead of data, you get a URL, which is the location of a temporary file. Copying it to a permanent location is optional
58
What kind of delegates are available with URLSessionDelegate?
- URLSessionDelegate: General events - URLSessionTaskDelegate: Task-related methods ( if a task is waiting for connectivity or redirect) - URLSessionDataDelegate: Uploading - URLSessionDownloadDelegate: Downloading (related download stuff, showing progress, resuming and pausing downloads)
59
What object allows you to Manage the OS file system?
```FileManager```
60
How to get the documentsPath using FileManager?
``` let fileManager = FileManager.default guard let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { print("Song download failed") return } ```
61
How to store a recent dowloaded file?
``` guard let (downloadurl, response) = try? await session.download(from: url) else { print("Error downloading song.") return } guard let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { print("Song download failed") return } let lastPathComponent = url.lastPathComponent let destinationURL = documentsPath.appendingPathComponent(lastPathComponent) do { if fileManager.fileExists(atPath: destinationURL.path) { try fileManager.removeItem(at: destinationURL) } try fileManager.copyItem(at: downloadurl, to: destinationURL) await MainActor.run { downloadLocation = destinationURL } } catch { print("Failed to store the song.") } ```
62