Skip to content

Instantly share code, notes, and snippets.

@thomsmed
Created January 1, 2022 22:42
Show Gist options
  • Select an option

  • Save thomsmed/60b93a04a84dfad497ff474700299c04 to your computer and use it in GitHub Desktop.

Select an option

Save thomsmed/60b93a04a84dfad497ff474700299c04 to your computer and use it in GitHub Desktop.
ViewController.swift - From "Share authentication state across your apps, App Clips and Widgets" @ medium.com
//
// ViewController.swift
//
import UIKit
import TinyConstraints
enum TextType {
case info
case error
var uiColor: UIColor {
switch self {
case .info:
return .label
case .error:
return .systemRed
}
}
}
class ViewController: UIViewController {
private let titleLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 24)
label.text = "Hello from App"
return label
}()
private let loginButton: UIButton = {
let button = UIButton(type: .system)
return button
}()
private let statusLabel: UILabel = {
let label = UILabel()
label.font = .systemFont(ofSize: 17)
return label
}()
private let callApiButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Call Api!", for: .normal)
return button
}()
private var isAuthenticated = false {
didSet {
callApiButton.isHidden = !isAuthenticated
loginButton.setTitle(isAuthenticated ? "Sign out" : "Sign in", for: .normal)
showStatus(isAuthenticated ? "You are signed in!" : "You are not signed in")
}
}
override func viewDidLoad() {
super.viewDidLoad()
configureUI()
configureBehaviour()
}
private func configureUI() {
view.backgroundColor = .systemBackground
view.addSubview(titleLabel)
view.addSubview(loginButton)
view.addSubview(statusLabel)
view.addSubview(callApiButton)
titleLabel.topToSuperview(offset: 40, usingSafeArea: true)
titleLabel.leadingToSuperview(offset: 40, usingSafeArea: true)
loginButton.centerXToSuperview()
loginButton.centerYToSuperview(offset: -40)
statusLabel.centerInSuperview()
callApiButton.centerXToSuperview()
callApiButton.centerYToSuperview(offset: 40)
}
private func configureBehaviour() {
loginButton.addTarget(self, action: #selector(loginOrLogout), for: .primaryActionTriggered)
callApiButton.addTarget(self, action: #selector(callApi), for: .primaryActionTriggered)
isAuthenticated = Dependencies.authService.hasSignedInBefore
}
private func showStatus(_ text: String, type: TextType = .info) {
statusLabel.text = text
statusLabel.textColor = type.uiColor
}
@objc private func loginOrLogout(_ target: UIButton) {
if isAuthenticated {
logout()
} else {
login()
}
}
@objc private func callApi(_ target: UIButton) {
callFakeApi()
}
}
extension ViewController {
func login() {
Dependencies.authService.login { result in
switch result {
case let .failure(error):
self.showStatus(error.localizedDescription, type: .error)
case .success:
self.isAuthenticated = true
}
}
}
func logout() {
Dependencies.authService.logout()
isAuthenticated = false
}
func callFakeApi() {
Dependencies.authTokenProvider.performWithFreshToken { tokenResult in
switch tokenResult {
case let .failure(error):
self.showStatus(error.localizedDescription, type: .error)
case let .success(accessToken):
self.showStatus("Calling api... (token: \(accessToken.dropLast(accessToken.count - 5))...)")
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.showStatus("Success! (token: \(accessToken.dropLast(accessToken.count - 5))...)")
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment