Monitoring Transport Conditions

If syncing over Bluetooth LE is a critical part of your application you may want to warn the user if they are missing the permission or if the hardware is disabled. Ditto will help you by reporting conditions via a delegate or callback object.

First, while configuring Ditto, assign a delegate or a callback to receive notifications.

// Setting up inside a ViewController
ditto = Ditto()
ditto.delegate = self
ditto.setLicenseToken("...")
try! ditto.tryStartSync()
// Setting up inside a ViewController
DITDitto *ditto = [[DITDitto alloc] init];
ditto.delegate = self;
[ditto setLicenseToken: @"..."];
[ditto tryStartSync:nil];
// Setting up inside an Activity
val androidDependencies = DefaultAndroidDittoDependencies(applicationContext)
val ditto = Ditto(androidDependencies)
ditto.callback = this
ditto.setLicenseToken("...")
ditto.tryStartSync()
// Setting up inside an Activity
DefaultAndroidDittoDependencies androidDependencies = new DefaultAndroidDittoDependencies(getApplicationContext());
Ditto ditto = new Ditto(androidDependencies);
ditto.callback = this;
ditto.setLicenseToken("...");
ditto.tryStartSync();
// Setting up inside Main
Ditto ditto = new Ditto();
ditto.setLicenseToken("...");
ditto.tryStartSync();

const transportConditionsObserver = ditto.observeTransportConditions((condition, source) => {
    // Check `condition` and `source` and update your UI accordingly:
    console.log(`Transport condition changed: ${condition}, source: ${source}`)
})

ditto.updateTransportConfig((transportConfig) => {
    // Configure your transport here:
    transportConfig.connect.websocketURLs = ['wss://example.com']
})

ditto.startSync()

Here we are using either the ViewController or Activity to receive the condition callbacks. Extend the appropriate interface and implement the callback method. Condition events may occur multiple times.

Ditto callbacks come on the background thread. Controlling UI elements, such as making a Toast, requires posting that work onto the main thread on both iOS and Android.

A wide variety of potential problems is described through TransportCondition. Some of them are very unusual, or not applicable on some platforms. Handle only the cases that you are interested in.

extension ViewController: DittoDelegate {
    func transportConditionDidChange(transportID: Int64, condition: TransportCondition) {
        if condition == .BleDisabled {
            print("BLE disabled")
        } else if condition == .NoBleCentralPermission {
            print("Permission missing for BLE")
        } else if condition == .NoBlePeripheralPermission {
            print("Permission missing for BLE")
        }
    }
}
@interface ViewController () <DITDittoDelegate>

@end

@implementation ViewController

- (void)transportConditionChanged:(enum DITTransportCondition)condition forSubsystem:(enum DITConditionSource)source {
    if (condition == DITTransportConditionBleDisabled) {
        NSLog(@"BLE disabled");
    } else if (condition == DITTransportConditionNoBleCentralPermission) {
        NSLog(@"Permission missing for BLE");
    } else if (condition == DITTransportConditionNoBlePeripheralPermission) {
        NSLog(@"Permission missing for BLE");
    }
}

@end
class MainActivity : AppCompatActivity(), DittoCallback {
    // ...
    override fun transportConditionDidChange(transportId: Long, condition: TransportCondition) {
        var toastText: String? = null
        if (condition == TransportCondition.TRANSPORT_CONDITION_BLE_DISABLED) {
            toastText = "BLE disabled"
        } else if (condition == TransportCondition.TRANSPORT_CONDITION_NO_BLE_CENTRAL_PERMISSION) {
            toastText = "Permission missing for BLE"
        } else if (condition == TransportCondition.TRANSPORT_CONDITION_NO_BLE_PERIPHERAL_PERMISSION) {
            toastText = "Permission missing for BLE"
        }
        toastText?.let {
            Handler(mainLooper).post {
                Toast.makeText(this, it, Toast.LENGTH_LONG).show()
            }
        }
    }
}
public class MainActivity extends AppCompatActivity implements DittoCallback {
    @Override
    public void transportConditionDidChange(@NotNull DittoTransportCondition condition, @NotNull DittoConditionSource transportId) {
        String toastText = null;
        if (condition == DittoTransportCondition.BleDisabled) {
            toastText = "BLE disabled";
        } else if (condition == DittoTransportCondition.NoBleCentralPermission) {
            toastText = "Permission missing for BLE";
        } else if (condition == DittoTransportCondition.NoBlePeripheralPermission) {
            toastText = "Permission missing for BLE";
        }

        if (toastText != null) {
            String finalToastText = toastText;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(MainActivity.this, finalToastText, Toast.LENGTH_LONG).show();
                }
            });
        }
    }
}


We are using a TCP example for JavaScript since there is no access to
Bluetooth hardware when running in the browser.

const transportConditionsObserver = ditto.observeTransportConditions((condition, source) => {
    if (condition === 'CannotEstablishConnection' && source === 'TCP')
    console.error(`Couldn't establish a TCP connection.`)
})
Top