Capture User Information

This section details how to build the capture user information experience, which involves obtaining the following information:

  • Verification of the user's State, Country, and zip code where the user’s car is registered.

  • Obtaining location and other required permissions for IQL to track users’ trips.

This section includes the following topics:

Capture User Information

Capture User Information

Capture User Information

Capture User Information

Capture User Information

1.0. Capture User Zip Code and Insurer Information

Use this section to know how to prompt users to provide their local zip code and use this information to obtain the user's State and Country information. You will need the user's zip code in order to verify whether any offers are available or not.

2.0. Validate IQL Test Drive Availability

After the user provides their zip code and their current insurer's details, you need to check with IQL backend for the insurer's test drive availability in that zip code area. Refer to the supportedState Details API endpoint to know how to obtain this information.

To validate the availability of a test drive for a given zip code, send the zip code to the Supported State Details API provided by the IQL Backend. This API will indicate whether the entered zip code is supported or not. This step is necessary to ensure that the user is eligible for the program and can participate in a test drive in their area. The following code snippet provides an example of how to make this API call.

extension EnterZipCodeController {
    @objc func onContinueClicked() {
        DDLogDebug("On zipcode screen continue button clicked")
        DispatchQueue.main.async {
            (self.continueButton as? ZWLUIButton)?.showLoading()
            self.enableInteractable(enabled: false)
        }
        insurerRepository.userData.insurerName = insurerTextField.text ?? ""
        insurerRepository.userData.stateCode = self.zipCodeInfo.shortHand
        verifyUserDetails()
    }
    func verifyUserDetails() {
        insurerRepository.apiSuccessCallback = { (success, statusCode) in
            switch statusCode {
            case "200":
                if success {
                    self.updateDriveInfoAPI()
                } else {
                    self.showErrorSheet(bottomSheetName: self.programNotAvailableError, title: "test_drive_not_available", description: "test_drive_not_available_description", primaryButton: "Ok", imageName: "no_saving")
                }
            default:
                self.showErrorSheet(bottomSheetName: self.showAPIError, title: "", description: "technical_issue",  primaryButton: "Ok", imageName: "map_loading_error")
            }
            DispatchQueue.main.async {
                (self.continueButton as? ZWLUIButton)?.stopLoading()
                self.enableInteractable(enabled: true)
            }
        }
        insurerRepository.verifyUserStateInfo()
    }
}
struct InsurerListModel: Codable {
    var isSupportedState : Bool?
    var canReceiveOffer  : Bool?
    enum CodingKeys: String, CodingKey {
        case isSupportedState = "is_supported_state"
        case canReceiveOffer  = "can_receive_offer"
    }
}


class InsurerRepository {
    var userData = UserInputData()
    var apiSuccessCallback : ((Bool,String) -> Void)?
    func verifyUserStateInfo() {
        DDLogDebug("Start: Fetch driver status")
        let core = IQLRef.sharedInstance
        core.api.verifyEligiblityforProgram(inputData: userData) { successResponse in
            if successResponse.isSupportedState == true && successResponse.canReceiveOffer == true {
                if self.apiSuccessCallback != nil {
                    self.apiSuccessCallback!(true, "200")
                }
            } else {
                if self.apiSuccessCallback != nil {
                    self.apiSuccessCallback!(false, "200")
                }
            }
        } onFailure: { failureResponse in
            DDLogDebug("Failure - \(failureResponse)")
            DDLogDebug("End: supported state API failed")
            self.apiSuccessCallback!(true, failureResponse.status!)
        } onError: { error in
            DDLogDebug("Error - \(error)")
            DDLogDebug("End: supported state API Error")
            self.apiSuccessCallback!(true, error.rawResponse!)
        }
    }
}

3.0. Integrate IQL DriverInfo Endpoint

After the user's zip code is deemed eligible for the test drive program, use the PUTdriverInfo Endpoint to update the user's information, including their zip code, state, country, and current insurer, segment fields to the IQL backend. This information will be used later to redeem the offer provided by the insurer.

The following code snippets provide a sample implementation, for your reference:

Use the following code snippet to create a driverInfoDTO struct to parse data to and from the driverInfo API, which will be used for both PUT and GET API requests.

struct DriverInfoDTO: Codable {
    var country: String?
    var state: String?
    var zipcode: String?
    var insurer: String?
    var segment: Segment?
    enum CodingKeys: String, CodingKey {
        case country = "country"
        case state = "state"
        case zipcode = "zipcode"
        case insurer = "insurer"
        case segment = "segment"
    }
}

After verifying the test drive availability, if a test drive is available for the given zip code, upload the driverInfoDTO details to the IQL backend by calling the PUT driverInfo API.

class EnterZipCodeController {
    .
    .
    .
    func verifyUserDetails() {
        insurerRepository.apiSuccessCallback = { (success, statusCode) in
            switch statusCode {
            case "200":
                if success {
                    self.updateDriveInfoAPI()
                }
                    .
                    .
                    .
            }
        }
    }
    func updateDriveInfoAPI() {
        let core = IQLRef.sharedInstance
        guard let driverId = core.loginRepository.currentUser?.driverId else {
            fatalError("User id doesn't exist")
        }
        let driverInfoDTO = DriverInfoDTO(country: insurerRepository.userData.countryCode,
                                          state: self.zipCodeInfo.shortHand,
                                          zipcode: zipCodeField.text!,
                                          insurer: insurerTextField.text!,
                                          segment: Segment(acquisitionSource: "zendrive_iql_reference_app"))
        core.api.updateDriverInfo(driverId: driverId, driverInfo: driverInfoDTO, onSuccess: { success in
            if success {
                self.updateUserInfo()
                self.core.loginRepository.setLeaveProgram(leaveProgram: false)
                self.getAppNavController()?.navigateTo(nav: .permissions)
            } else {
                self.refreshUI()
            }
        }, onFailure: { (failure: FailureResponse) in
            DDLogError("Received driver info failure response - \(failure)")
            self.refreshUI()
        }) { (error: APIError) in
            DDLogError("Received driver info error response - \(error)")
            self.refreshUI()
        }
    }
}
class API {
    .
    .
    .
    func updateDriverInfo(
        driverId: String,
        driverInfo: DriverInfoDTO,
        onSuccess: ((_ postData: Bool) -> Void)?,
        onFailure: ((_ failureResponse: FailureResponse) -> Void)?,
        onError: ((_ error: APIError) -> Void)?
    ) {
        executePutRequest(
            endpoint: .driverInfo,
            pathParams:["driver_id": driverId],
            postData:driverInfo,
            onSuccess: onSuccess, onFailure: onFailure, onError: onError)
    }
        .
        .
        .
}

4.0. IQL Reference Application UX Design

Here is the overall design implementation for the IQL Reference Application:

5.0. Publisher Integration Testing Checklist

Follow the testing checklist given below to test the capture user information experience in your application:

  • Zipcode: Ensure that only valid zip codes are accepted and the corresponding state information is returned. In case of an invalid code, display an error message to inform the user.

  • Current Insurer: Ensure there is a list of insurer names displayed so the user can pick their current insurer. If their current insurer is not listed, provide the option to help them select their insurer.

  • Program Availability: If the program availability is based on zipcode and current insurer information, display a 'Program Unavailable' message for unsupported zipcodes and insurer combinations. If the program is available for the zipcode provided, make sure the user is able to continue onboarding.