Authenticated User Implementation - Hipo/mobile-team-guidelines GitHub Wiki

Generally we are using singleton pattern for authenticated user model implementation in applications.

We could implement AuthenticatedUser as a subclass of User model like the following;

class User {
    let identifier: Int
    let firstName: String
    let lastName: String
}
class AuthenticatedUser: User {
    private static let shared = AuthenticatedUser()
    
    var token: String
    let email: String	
    var phoneNumber: String

	// variables
	let token: String
	...
	
	// methods	
	func saveToLocal() {
		...
	}
		
	func logout() {
		...
	}
	
	func fetch() {
		...
	}
}

Method explanations:

func saveToLocal(): Saves the authenticated user to UserDefaults or Keychain depending on situation.

func logout(): Required functionalities after a logout could be implemented within this method. For instance, calling relevant endpoint, clearing local data (from userdefaults, or Keychain), unregistering from push notifications.

func fetch(): In an application we often need to update authenticated user's data - for example, when the user created a new post and number of posts label needed to update. Using this method we can update the user whenever needed. A specific notification could also be posted to inform views all accross the application that is connected the user's information.

Usage:

AuthenticatedUser.shared.saveToLocal()
AuthenticatedUser.shared.logout()
AuthenticatedUser.shared.fetch()

Decoding JSON response to custom objects

We can simply map json responses into custom objects using Codable protocol like below;

class User: Codable {
    let identifier: Int
    let firstName: String
    let lastName: String
    
    private enum CodingKeys: String, CodingKey {
        case identifier = "id"
        case firstName  = "first_name"
        case lastName   = "last_name"
    }
}
class AuthenticatedUser: User {
    private static let shared = AuthenticatedUser()
    
    var token: String
    let email: String	
    var phoneNumber: String
    
    private enum CodingKeys: String, CodingKey {
        case token
        case email
        case phoneNumber = "phone_number"
    }
}

Usage:

do {        
    let user = try JSONDecoder().decode(AuthenticatedUser.self, from: data)
            
    // Using user object
} catch {
	// Handling Parsing Error
}