UI SDK Configuration and Authentication

UI SDK

UI SDK Configuration

In order to initialise the UI SDK on either iOS or Android, a working environment must be provided. The available environments are Sandbox and Production. The Sandbox is used for development and testing purposes. Bookings in the sandbox are not paid for and trip progress is simulated using Karhoo Bot fleets. A custom environment can also be provided.

To configure the UI SDK you will need to provide an implementation of our KarhooUISDKConfiguration interface (e.g. KarhooConfig: KarhooUISDKConfiguration). This lets our UI SDK grab certain dependencies and configuration settings.

// register configuration (AppDelegate) before any usage of the SDK
KarhooUI.set(configuration: KarhooConfig())
// The payment provider's view needs to be instantiated. It can be AdyenPaymentView or BraintreePaymentView depending on the PSP choice
// Adyen integration
val paymentManager = AdyenPaymentManager()
paymentManager.paymentProviderView = AdyenPaymentView()

// Braintree integration
val paymentManager = BraintreePaymentManager()
paymentManager.paymentProviderView = BraintreePaymentView()
  
// Later down the line
val config = KarhooConfig(applicationContext)
config.paymentManager = paymentManager

KarhooUISDK.setConfiguration(config)

The KarhooUISDKConfiguration interface also needs an implementation within your project.

struct KarhooConfig: KarhooUISDKConfiguration {
    
    var paymentProvider: PaymentProvider {
        AdyenPaymentProvider()
        // OR
        BraintreePaymentProvider()
    }
  
    // logo used on side menu and trip completion pop up
    func logo() -> UIImage {
        return UIImage("")!
    }

    func environment() -> KarhooEnvironment {
        return .sandbox
    }
  
    func authenticationMethod() -> AuthenticationMethod {
        return .karhooUser
    }
}

// With this configuration the UISDK can be initialised in your App/SceneDelegate. 
// This will also ensure the network layer (KarhooSDK) is initialised.
import KarhooUISDK

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        KarhooUI.set(configuration: YourCompanyKarhooConfiguration())
       ..
        return true
    }
}
class KarhooConfig(val context: Context, private val authMethod: AuthenticationMethod = AuthenticationMethod.KarhooUser()) :
        KarhooUISDKConfiguration {
    override lateinit var paymentManager: PaymentManager
      
    override fun logo(): Drawable? {
        return context.getDrawable(R.drawable.karhoo_wordmark)
    }

    override fun environment(): KarhooEnvironment {
        KarhooEnvironment.Sandbox()
    }

    override fun simulatePaymentProvider(): Boolean = false

    override fun context(): Context {
        return context
    }

    override fun authenticationMethod(): AuthenticationMethod {
        return authMethod
    }

    override fun analyticsProvider(): AnalyticProvider? {
        return GoogleAnalyticsProvider()
    }
}

Authentication

The UI SDK currently supports 3 different types of authentication methods, each can be used for different use cases depending on the integration model:

  • Username/password: The users created and managed in the Karhoo platform
  • Token Exchange or Third-party authentication: The users are created and managed in your own identity system
  • Guest authentication: No sign-in required

The AuthenticationMethod is set as part of the SDK configuration, therefore it is important to configure the SDK for the right configuration mechanism first

Username/password

SDK Configuration

final class KarhooConfig: KarhooUISDKConfiguration {

    static var auth: AuthenticationMethod = .karhooUser

    func environment() -> KarhooEnvironment {
        return .sandbox
    }

    func authenticationMethod() -> AuthenticationMethod {
        return .karhooUser
    }
}
class KarhooConfig(val context: Context) :
        KarhooUISDKConfiguration {

    override fun authenticationMethod(): AuthenticationMethod {
        return AuthenticationMethod.KarhooUser()
    }
}

User Authentication

The KarhooApi.userService provides all the required functionality for common user management tasks such as registering a new user, logging in an existing user, updating the user details and resetting their password.

Since we have specified AuthenticationMethod.KarhooUser as the authentication method, you need to use the KarhooApi.userService.loginUser API to authenticate the user:

val userService = KarhooApi.userService
val userLogin = UserLogin(email = "[email protected]", password = "password")

userService.loginUser(userLogin: userLogin).execute { result in
     switch result {
        case .success(let user):
            print("User: \(user)")
        case .failure(let error):
            print("error: \(error.code) \(error.message)")
    }
}
val loginRequest = UserLogin(email = "[email protected]", password = "password"
KarhooApi.userService.loginUser(loginRequest).execute { result ->
   when (result) {
      is Resource.Success -> {
         val userInfo: UserInfo = result.data
         Log.d("Welcome ${userInfo?.firstName}")
         // Proceed to next step
      }
      is Resource.Failure -> {
         if (result.error == KarhooError.UserAlreadyLoggedIn) {
            Log.d("Welcome back")
            // Proceed to next step
         } else {
            Log.d((result.error)
         }
      }
   }
}

Token Exchange

You will first need to integrate your external authentication system with the Karhoo platform before initialising the SDK with your client id. When using this authentication method, the authentication service must be used to login and revoke access before interacting with other Karhoo services.

SDK Configuration

struct KarhooConfig: KarhooSDKConfigurationProvider {
 
    func authenticationMethod() -> AuthenticationMethod {
    let settings = TokenExchangeSettings(clientId: "", scope: "")
        return .tokenExchange(settings: settings)
   }
}
class KarhooConfig : KarhooSDKConfiguration {
  
    override fun authenticationMethod(): AuthenticationMethod {
            return AuthenticationMethod.TokenExhange(clientId = "",
                                                       scope = "") 
        }
}

User Authentication

The KarhooApi.authService provides all the required functionality for common user management tasks such as registering a new user, logging in an existing user, updating the user details and resetting their password.

Since we have specified AuthenticationMethod.TokenExhange as the authentication method, the KarhooApi.userService.loginUser API needs to be used to authenticate the user:

let authService = Karhoo.getAuthService()

authService.login(token: String).execute(callback: { result in
     switch result {
        case .success(let user):
            print("User: \(user)")
        case .failure(let error):
            print("error: \(error.code) \(error.message)")
        }
   })
}
val authService = KarhooApi.authService

authService.login(token = "123csXXs").execute { result ->
    when (result) {
        is Resource.Success -> Log.d(result.data) // Handle data
        is Resource.Failure -> Log.d(result.error.internalMessage) //Handle errors
    }
}

Guest authentication

The user does not require any credentials in order to access the Karhoo platform in the guest authentication method. You need to configure the SDK with valid parameters.

struct KarhooConfig: KarhooSDKConfigurationProvider {
  func authenticationMethod() -> AuthenticationMethod {
    let guestSettings = GuestSettings(identifier: "",
                                    referer: "",
                                    organisationId: "")
        return .guest(settings: guestSettings)
   }
}
class KarhooConfig : KarhooSDKConfiguration {

    override fun authenticationMethod(): AuthenticationMethod {
        return AuthenticationMethod.Guest(identifier = "client_identifier", referer = "referer", organisationId = "organisation_id")
  }
}

Analytics

Our UI SDK includes an event-model that allows a subset of user interactions to be provided for you to be used in your Analytics framework. The specific Analytics strategy is for you to choose but the scope of events that can be captured is constrained by the events generated by the Karhoo UI SDK.

public protocol Analytics {
    func tripStateChanged(tripState: TripInfo?)
    func fleetsShown(quoteListId: String?, amountShown: Int)
    func prebookOpened()
    func prebookSet(date: Date, timezone: String)
    func userCalledDriver(trip: TripInfo?)
    func pickupAddressSelected(locationDetails: LocationInfo)
    func destinationAddressSelected(locationDetails: LocationInfo)
    func bookingRequested(tripDetails: TripInfo)
    func paymentSucceed()
    func paymentFailed(message: String, last4Digits: String, date: Date, amount: String, currency: String)
    func trackTripOpened(tripDetails: TripInfo, isGuest: Bool)
    func pastTripsOpened()
    func upcomingTripsOpened()
    func trackTripClicked(tripDetails: TripInfo)
    func contactFleetClicked(page: AnalyticsScreen, tripDetails: TripInfo)
    func contactDriverClicked(page: AnalyticsScreen, tripDetails: TripInfo)
    func bookingScreenOpened()
    func checkoutOpened(_ quote: Quote)
    func quoteListOpened(_ bookingDetails: BookingDetails)
}
interface Analytics {
    fun userLocated(location: Location)
    fun bookingRequested(tripDetails: TripInfo, outboundTripId: String?)
    fun tripStateChanged(tripState: TripInfo?)
    fun userCancelTrip(trip: TripInfo?)
    fun pickupAddressSelected(locationDetails: LocationInfo, positionInAutocompleteList: Int)
    fun destinationAddressSelected(locationDetails: LocationInfo, positionInAutocompleteList: Int)
    fun destinationPressed()
    fun prebookSet(date: Date, timezone: String)
    fun fleetsShown(quoteListId: String?, amountShown: Int)
    fun prebookOpened()
    fun userCalledDriver(trip: TripInfo?)
    fun userCalledFleet(trip: TripInfo?)
    fun trackRide()
    fun bookingScreenOpened()
    fun quoteListOpened(bookingInfo: BookingInfo?)
    fun checkoutOpened(quote: Quote)
    fun paymentSucceed()
    fun paymentFailed(errorMessage: String, lastFourDigits: String, date: Date, amount: Int, currency: String)
    fun trackTripOpened(tripInfo: TripInfo, isGuest: Boolean)
    fun pastTripsOpened()
    fun upcomingTripsOpened()
    fun trackTripClicked(tripInfo: TripInfo)
    fun contactFleetClicked(page: String, tripInfo: TripInfo)
    fun contactDriverClicked(page: String, tripInfo: TripInfo)
}

You need to implement the above protocol and then configure the UI SDK to use it.

struct KarhooConfig: KarhooUISDKConfiguration {
    func analytics() -> Analytics {
        KarhooAnalytics()
    }
}
KarhooUISDK.analytics = KarhooAnalytics()

Legal notices

The UI SDK allows for explicit consumer acceptance of the terms and conditions prior to booking. You can enable explicit user consent by adding a checkbox to terms and conditions as part of the UI SDK configuration.

struct KarhooConfig: KarhooUISDKConfiguration {
    var isExplicitTermsAndConditionsConsentRequired: Bool { true }
}
class KarhooConfig : KarhooSDKConfiguration {
  
    override fun isExplicitTermsAndConditionsConsentRequired(): Boolean {
        return true
    }
}

You can also enable the display of ‘legal notices’ which can be used to summarise key elements of the longer terms and conditions of use documents that are linked into the user experience. The legal notice is not presented by default and the relevant strings are empty. If you want to display a custom legal notice to the users, you need to override and provide the following strings.
In the case of iOS, the strings need to be provided in Localizable.strings

📘

The supported links are valid URLs or email addresses with mailto: prefix as provided in the example below

"Text.Booking.LegalNoticeLink" = "mailto:[email protected]";
"Text.Booking.LegalNoticeText" = "The data collected is electronically processed by Karhoo sending email to %[email protected] Your data may need to be translated";
"Text.Booking.LegalNoticeTitle" = "Flit Technologies";
<string name="kh_uisdk_legal_notice_title">Karhoo</string>
<string name="kh_uisdk_legal_notice_link">mailto:[email protected]</string>
<string name="kh_uisdk_legal_notice_text">The data collected is electronically processed by Karhoo sending email to %s. Your data may need to be translated</string>