Get immediate access to this and over 1,500+ other videos and books.

Boost your skills with a raywenderlich.com Beginner subscription. With over 60+ video courses and our core foundational programming books bundled in one subscription, it’s simply the best investment you can make in your development career.

Understand Authentication

This video was last updated on Sep 15 2022

Learn about the different ways to authenticate, and provide authentication, when working with URLSession.

Contributors

Heads up... You've reached locked video content where the transcript will be shown as obfuscated text.

You can unlock the rest of this video course, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

If a session task requires authentication either as part of the requested URL or in the shared URL credential storage (and there are no valid credentials available) then the session creates an authentication challenge.

class AcronymSender {
  private let session: URLSession
  private let sessionConfiguration: URLSessionConfiguration
  
  init() {
    self.sessionConfiguration = URLSessionConfiguration.default
    self.sessionConfiguration.waitsForConnectivity = true
    self.session = URLSession(configuration: sessionConfiguration)
  }
}
private let baseURL: URL
private let loginEndpoint: URL
private let newEndpoint: URL
self.baseURL = URL(string: "https://tilftw.herokuapp.com/“)!
self.loginEndpoint = URL(string: "login", relativeTo: baseURL)!
self.newEndpoint = URL(string: "new", relativeTo: baseURL)!
func send(acronym: Acronym, for user: User) async throws {
    
}
enum AcronymError: Error {
  case failedToEncodeUserCredentials
}
let credentials = "\(user.email):\(user.password)"

guard let data = credentials.data(using: .utf8) else {
  throw AcronymError.failedToEncodeUserCredentials
}

let encodedString = data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
var loginRequest = URLRequest(url: loginEndpoint)
loginRequest.httpMethod = "POST"
loginRequest.allHTTPHeaderFields = [
  "accept": "application/json",
  "content-type": "application/json",
  "authorization": "Basic \(encodedString)"
]
let (loginData, loginResponse) = try await session.data(for: loginRequest)
guard let httpLoginResponse = loginResponse as? HTTPURLResponse,
      httpLoginResponse.statusCode == 200
else {
  throw AcronymError.invalidLoginResponse
}
case invalidLoginResponse
var auth = Auth(token: "")
    
do {
  auth = try JSONDecoder().decode(Auth.self, from: loginData)
} catch {
  throw AcronymError.failedToDecodeAuthToken
}
case failedToDecodeAuthToken
var acronymRequest = URLRequest(url: newEndpoint)
acronymRequest.httpMethod = "POST"
acronymRequest.allHTTPHeaderFields = [
  "accept": "application/json",
  "content-type": "application/json",
  "authorization": "Bearer \(auth.token)"
]
do {
  acronymRequest.httpBody = try JSONEncoder().encode(acronym)
} catch {
  throw AcronymError.failedToEncodeAcronym
}
case failedToEncodeAcronym
let (_, acronymResponse) = try await session.data(for: acronymRequest)
    
guard let httpAcronymResponse = acronymResponse as? HTTPURLResponse,
      httpAcronymResponse.statusCode == 200
else {
  throw AcronymError.invalidAcronymResponse
}
case invalidAcronymResponse
private let sender: AcronymSender = AcronymSender()
private let user: User = User(email: "jo@razeware.com", name: "jo", password: "password")
private func sendAcronymTapped() async {
  do {
    try await sender.send(acronym: acronym, for: user)
      
    Task { @MainActor in
      showAcronymSubmitSucceededAlert = true
    }
      
  } catch {
    Task { @MainActor in
      showAcronymSubmitFailedAlert = true
    }
  }
}
Task {
  await sendAcronymTapped()
}
https://tilftw.herokuapp.com/acronyms

Reviews

Comments