SDK Initialization

This page describes how to get up and running with the SDK has been installed.

The DexCareSDK object is the primary access point for interacting with the SDK. All services can be accessed through this object.

  • To initialize the SDK, you will need to call DexcareSDK.init(configuration: DexcareConfiguration). It is recommended to keep the SDK alive for the entirety of your application’s lifecycle. It is best to initialize the SDK as early as possible in your application’s lifecycle, however it is not necessarily needed to be initialized on didFinishLaunchingWithOptions. After initialization, the SDK does not pre-load any data.

    The DexcareConfiguration object requires a few objects to be setup before the SDK can be initialized.

    VirtualVisitConfiguration

    A VirtualVisitConfiguration object will contain all the appropriate information that is required for virtual visits.

    • pushNotificationAppId - The AppId for push notifications set up by Apple.
    • pushNotificationPlatform - The platform for push notifications set up by Apple (usually ios or ios-sandbox).
    • virtualVisitUrl - The url that is provided by your DexCare contact.
    let virtualVisitConfig = VirtualVisitConfiguration (
        pushNotificationAppId: "App id",
        pushNotificationPlatform: "ios",
        virtualVisitUrl: URL(string: "https://www.virtualvisiturl.com/api/")!
    )
    

    Environment

    An Environment object will contain all the urls and keys needed to run the SDK. The required URLs and keys will be provided by your DexCare contact.

    let environment = Environment(
        fhirOrchUrl: URL(string:  "https://www.aurl.com/api/")!,
        virtualVisitConfiguration: virtualVisitConfig,
        dexcareAPIKey: "apikey"
    

    DexcareSDKLogger

    The DexcareSDKLogger is a protocol that you can use to see more information about what the SDK does. If an instance of DexcareSDKLogger is attached on initialization, the SDK will post results, errors, information to the logger, which can help you debug issues.

    The DexcareSDKLogger has one function you must implement: func log(_ message: String, level: DexcareSDKLogLevel, sender: String)

    // Example `DexcareSDKLogger` to pass into the SDK.
    // Pass ConsoleLogger() into the SDK init method to post NSLog's to the console.
    class ConsoleLogger: DexcareSDKLogger {
        static var shared: ConsoleLogger = ConsoleLogger()
        func log(_ message: String, level: DexcareSDKLogLevel, sender: String) {
            let emoji: String
            switch level {
                case .verbose: emoji = "➡️"
                case .debug: emoji = "✳️"
                case .info: emoji = "✏️"
                case .warning: emoji = "⚠️"
                case .error: emoji = "❌"
            }
            NSLog("\(emoji) \(sender): \(message)")
        }
    }
    
    

    As an example, if the above is implmented, and a function call fails to the server, it will print to the console:

    ❌ DexcareSDK: Response error in 1.58s for: https://dexcareurl.com/api/7/visits/providerbooking?product=healthconnect-iOS - Status: 500 - Correlation: AD5C5189-DC90-46CB-A5F8-2641A0886E2C
    

    Correlation

    :heavy_check_mark: By providing the Correlation GUID to your dexcare contact, we can easily tell what went wrong in the call. :tada:

    Without it, it is more difficult to search on a server log to try and find out what happened.

    DexcareConfiguration

    Finally the DexcareConfiguration object combines all the 2 config objects.

    • environment - an Environment object created above.
    • userAgent - any specific information you want to pass in the UserAgent header to the API call. xxxUserAgentxxx|6.0.0|iPhone|12.1|darwin as an example of what will be used.
    • domain - a string provided by your DexCare contact.
    • customStrings - an optional set of strings that can override the default display strings inside a Virtual Visit. Deprecated on 8.1+
    • logger - an optional implementation of DexcareSDKLogger.
    return DexcareConfiguration(
        environment: environment,
        userAgent: "MyDexcareApp",
        domain: "com.myapp",
        customStrings: nil,
        logger: ConsoleLogger() // as an example
    )
    

    Localization

    Starting with iOS SDK 8.1+, support for localization is available. The SDK uses a Localizable.strings file, with a set of keys that are displayed inside the SDK UI.

    The SDK will use your device language to localize.

    Currently the SDK supports the following languages:

    • English (en)
    • Spanish (es)

    Overriding and new languages

    In order to override the default localization the SDK uses, you must have a Localizable.strings file created, making sure on Build Phases it is included in Copy Bundle Resources

    So in order for the SDK to show Spanish, you must add a Spanish inside your own apps localization. Even if that is an empty strings file, that will tell Xcode, your app allows Spanish.

    Once setup, simply create a strings key with the same value as the SDK uses. The SDK, when localizaing, will check the Bundle.main first (your app) and then use it’s own localization if the key is not found.

    New languages may be added and supported in the future, howevever, you can add your own localization to any languages by simply adding on to your Localizable.strings file.

    Localizable Keys

    Below are the localized keys SDK uses in it’s UI. If you wish to override any values, in any language, you must use the same keys.

    "dialog_reconnectError_button_confirm"="Ok";
    "dialog_declinedVisit_button_confirm"="Ok";
    "waitingRoom_subtitle_providerWaitTime"="One of our healthcare providers will meet you here as soon as they become available";
    "waitingRoom_caption_estimatedTime"="Estimate as of";
    "waitingRoom_message_readyPhotoId"="Keep the app open, and when your provider is ready you'll be notified. Please have your photo ID ready.";
    "waitingRoom_link_cancelVisit"="Cancel this virtual visit";
    "waitingRoom_title_navigation"="Virtual Visit Waiting Room";
    "chatView_hint_emptyChat"="Type here…";
    "visit_chatView_title_navigation"="Chat With Provider";
    "waitingRoom_chatView_title_navigation"="Chat";
    "chatView_button_send"="Send";
    "dialog_waitingRoomCancelConfirm_title_cancelCall"="Cancel Call";
    "dialog_waitingRoomCancelConfirm_message_cancelCallConfirmation"="Are you sure you want to cancel this virtual visit?";
    "dialog_waitingRoomCancelConfirm_button_confirm"="Confirm";
    "dialog_waitingRoomCancelConfirm_button_cancel"="Return";
    "dialog_visitEndConfirm_title"="Confirm";
    "dialog_visitEndConfirm_message"="Are you sure you want to end the call?";
    "dialog_visitEndConfirm_button_confirm"="End Call";
    "dialog_visitEndConfirm_button_cancel"="Cancel";
    "waitingRoom_body_userTyping"="%s is typing...";
    "dialog_lostConnection_title"="Sorry, we lost the connection.";
    "dialog_lostConnection_message"="We are attempting to reconnect.";
    "dialog_reconnectError_title"="Sorry, we couldn't reconnect.";
    "dialog_reconnectError_provider_message"="A provider will call you shortly.\nIn the meantime:\n\n1. Please try reconnecting to the internet.\n\n2. Use the confirmation email we sent you to reconnect.\n\nIf you still need help, please call\n%1$s.";
    "dialog_cancelError_title"="Error";
    "dialog_cancelError_message"="Unable to cancel visit. Please try again later.";
    "dialog_visitPermission_title_joinedElsewhere"="Connection lost";
    "dialog_visitError_body_joinedElsewhereMessage"="It seems you have joined the virtual visit from another device. You can continue using the other device. We have ended this session now.";
    "visit_toast_providerVideoDisabled"="The provider has temporarily disabled their video.";
    "visit_toast_providerVideoEnabled"="The provider has enabled their video.";
    "dialog_visitDeclined_title"="Visit declined";
    "dialog_visitDeclinedMessage_message"="You will not be billed for an incomplete Virtual Visit.";
    "dialog_visitDeclined_button_confirm"="ok";
    "dialog_cancelReconnect_title"="Confirm";
    "dialog_cancelReconnect_message"="Are you sure you want to stop the reconnection attempt? This will remove you from the virtual visit, but your visit will not be cancelled.";
    "dialog_cancelReconnect_confirm"="Keep Trying";
    "dialog_cancelReconnect_cancel"="Cancel";
    "dialog_permission_title"="Permissions Required";
    "dialog_permission_body_message"="In order to start your visit: Please allow camera and microphone access to start your virtual visit with a provider.";
    "dialog_permission_button_appSettings"="Open Settings";
    "dialog_permission_button_confirm"="Ok";
    "dialog_reconnect_title" = "Reconnecting...";
    "dialog_reconnect_cancel" = "Cancel";
    
    
  • Setting up configs

    Your app will need to define several configuration values in string resources. Most of these can be provided by your DexCare contact, and note that some may differ for debug vs. release builds.

    See the DexCareSDK Sample App repo for a list of config values required by the SDK.

    Initializing the SDK

    To initialize the SDK, you will need to call DexCareSDK.init as early as possible in your application’s lifecycle, optimally inside your Application’s onCreate() method. The SDK can only be initialized once.

    The init method takes the parameters: context: Context, environment: Environment, refreshTokenContract: RefreshTokenContract? = null.

    context should be your Application’s context.

    environment should be an implementation of the SDK’s Environment interface. The required base URLs will be provided by your DexCare contact.

    refreshTokenContract is an optional argument, which can be an implementation of the SDK’s RefreshTokenContract interface.

    As of SDK 4.0.0, the SDK’s Koin instance is internal to the SDK.

    Your app is not required to use Koin.

    Initialization of the SDK should look something like this:

    class MainApplication : Application() {
        override fun onCreate() {
            super.onCreate()
            DexCareSDK.init(this,
                object : Environment {
                    override val isProd: Boolean = BuildConfig.BUILD_TYPE.toLowerCase(Locale.ROOT) == "release"
                    override val fhirOrchUrl: String = getString(R.string.dexcare_fhirorch_url)
                    override val virtualVisitUrl: String = getString(R.string.dexcare_virtualvisit_url)
                }
            )
        }
    }
    

    Localization

    Starting with Android SDK 8.1.*, support for localization is available. The SDK uses the localized Strings.xml file keys to display localized content in the SDK.

    The SDK will use the device local language by default.

    Currently the SDK supports the following languages:

    • English (en)
    • Spanish (es)

    Overriding and new languages

    In order to override the localized strings you need to define your content using the keys deinfed in the Strings.xml file. You can also introduce new languages by adding a Strings.xml file inside a values-[languageCode] folder.

    [languageCode] has to be a two character string.

    Below are the list of localized key pair values.

        <string name="waitingRoom_subtitle_providerWaitTime">One of our healthcare providers will meet you here as soon as they become available</string>
        <string name="waitingRoom_caption_estimatedTime">Estimate as of</string>
        <string name="waitingRoom_message_readyPhotoId">Keep the app open, and when your provider is ready you\'ll be notified. Please have your photo ID ready.</string>
        <string name="waitingRoom_link_cancelVisit">Cancel this virtual visit</string>
        <string name="chatView_hint_emptyChat">Type here…</string>
        <string name="chatView_button_send">Send</string>
        <string name="dialog_waitingRoomCancelConfirm_title_cancelCall">Cancel Call</string>
        <string name="dialog_waitingRoomCancelConfirm_message_cancelCallConfirmation">Are you sure you want to cancel this virtual visit?</string>
        <string name="dialog_waitingRoomCancelConfirm_button_confirm">Confirm</string>
        <string name="dialog_waitingRoomCancelConfirm_button_cancel">Cancel</string>
        <string name="waitingRoom_chatView_title_navigation">Chat</string>
        <string name="dialog_visitEndConfirm_title">Confirm</string>
        <string name="dialog_visitEndConfirm_message">Are you sure you want to end the call?</string>
        <string name="dialog_visitEndConfirm_button_confirm">End call</string>
        <string name="dialog_visitEndConfirm_button_cancel">Cancel</string>
        <string name="waitingRoom_body_userTyping">%s is typing, &#8230;</string>
        <string name="dialog_lostConnection_title">Sorry, we lost the connection.</string>
        <string name="dialog_lostConnection_message">We are attempting to reconnect.</string>
        <string name="dialog_reconnectError_title">Sorry, we couldn\'t reconnect.</string>
        <string name="dialog_reconnectError_provider_message">A provider will call you shortly.\nIn the meantime:\n\n1. Please try reconnecting to the internet.\n\n 2. Use the confirmation email we sent you to reconnect. \n\n If you still need help, please call\n%1$s.</string>
        <string name="dialog_reconnectError_button_confirm">Ok</string>
        <string name="dialog_cancelError_title">Error</string>
        <string name="dialog_cancelError_message">Unable to cancel visit. Please try again later.</string>
        <string name="dialog_permission_title">Permissions required</string>
        <string name="dialog_permission_body_message">In order to start your visit:\nPlease allow camera and microphone access to start your virtual visit with a provider.</string>
        <string name="dialog_permission_button_confirm">OK</string>
        <string name="dialog_permission_button_appSettings">APP SETTINGS</string>
        <string name="dialog_visitPermission_title_joinedElsewhere">Connection lost</string>
        <string name="dialog_visitError_body_joinedElsewhereMessage">It seems you have joined the virtual visit from another device. You can continue using the other device. We have ended this session now.</string>
        <string name="visit_toast_providerVideoDisabled">The provider has temporarily disabled their video.</string>
        <string name="visit_toast_providerVideoEnabled">The provider has enabled their video.</string>
        <string name="dialog_visitDeclined_title">Visit declined</string>
        <string name="dialog_visitDeclinedMessage_message">You will not be billed for an incomplete Virtual Visit.</string>
        <string name="dialog_visitDeclined_button_confirm">Ok</string>
    

Authentication

In order to use the DexCare services, the SDK requires an access token.

Currently, Auth0 is the only supported authentication platform for DexCare services. Additional authentication platforms can potentially be supported in the future.

  • To set the access token for the DexCare SDK to use, you need to call DexCareSDK.signIn(accessToken: String) method.

    let dexcareSDK = DexcareSDK(configuration: ...)
    dexcareSDK.signIn(accessToken: "myAuth0AccessToken")
    

    The token can be revoked from the SDK by calling the DexCareSDK.signOut() method.

    let dexcareSDK = DexcareSDK(configuration: ...)
    dexcareSDK.signOut()
    
  • To set the access token for the DexCare SDK to use, you need to call DexCareSDK.signIn(accessToken: String).

    These calls are synchronous, so subscribing for results is not needed.

    DexCareSDK.signIn("myAuth0AccessToken")
    

    The token can be revoked from the SDK by calling the DexCareSDK.signOut() method.

    Note: calling signOut also will remove any cache that the SDK has.

    DexCareSDK.signOut()