Discovering towers#
Initializing the SDK and setting your access token#
Tip
In order to communicate with the tower you will need an access token. Get Access Tokens
Initializing your SDK and setting your access token.#
// call setAccessToken() and pass 2 arguments, the first being your sdkToken and the second being your environment.
HarborLockersSDK.setAccessToken(sdkToken, environment); // Your token should be a very long string, and the environment will be either `production`, or `sandbox`, Case sensitive, all lowercase.
class YourClass: HarborSDKDelegate, HarborLoggerDelegate {
func setupHarborSDK() {
HarborSDK.setDelegate(self)
HarborSDK.setOutputConsole(self)
HarborSDK.setEnvironment(.SANDBOX)
let token = "your-access-token" // Replace with your actual access token
HarborSDK.setAccessToken(token)
// Enable logging (optional & not in prod)
HarborSDK.shared.setupLogger(delegate: self, level: .debug)
}
class YourClass : HarborSDKDelegate, HarborLoggerDelegate {
fun setupHarborSDK() {
HarborSDK.setDelegate(this)
HarborSDK.setOutputConsole(this)
HarborSDK.setEnvironment(Environment.SANDBOX)
val token = "your-access-token" // Replace with your actual access token
HarborSDK.setAccessToken(token)
// Enable detailed logging (optional & do not use in production)
HarborSDK.shared.setupLogger(this, LogLevel.DEBUG)
}
}
Here’s a full example of how to set up your delegate.
HarborLockersSDK.initializeSDK();
class YourClass: HarborSDKDelegate, HarborLoggerDelegate {
func setupHarborSDK() {
HarborSDK.setDelegate(self)
HarborSDK.setOutputConsole(self)
HarborSDK.setEnvironment(.SANDBOX)
HarborSDK.setAccessToken(token)
// Set up HarborSDK Logger
HarborSDK.shared.setupLogger(delegate: self, level: .debug)
}
// Implement HarborSDKDelegate protocol
func harborDidDiscoverTowers(_ towers: [HarborLockersSDK.Tower]) {
// handle your tower discovery
}
// Implement HarborLoggerDelegate protocol
func harborDidLog(message: String, logType: HarborLockersSDK.HarborLogLevel, context: [String: Any]?) {
print("Harbor Logger: \(message)" )
}
}
class YourClass : HarborSDKDelegate, HarborLoggerDelegate {
fun setupHarborSDK() {
HarborSDK.setDelegate(this)
HarborSDK.setOutputConsole(this)
HarborSDK.setEnvironment(HarborEnvironment.SANDBOX)
HarborSDK.setAccessToken(token)
// Set up HarborSDK Logger
HarborSDK.shared.setupLogger(this, HarborLogLevel.DEBUG)
}
// Implement HarborSDKDelegate protocol
override fun harborDidDiscoverTowers(towers: List<HarborSDK.Tower>) {
// Handle tower discovery
}
// Implement HarborLoggerDelegate protocol
override fun harborDidLog(message: String, logType: HarborSDK.HarborLogLevel, context: Map<String, Any>?) {
println("Harbor Logger: $message")
}
}
Finding towers#
Connecting to a specific tower#
HarborLockersSDK.connectToTowerWithIdentifier(towerId)
Finding nearby towers#
This step varies by what you are using.
HarborLockersSDK.startTowersDiscovery()
// listens to response from nearby towers after casting the startTowerDiscovery() func
fun harborDidDiscoverTowers(towers: List<HarborSDK.Tower>) {
// Handle tower discovery
}
// Listens to response from nearby towers after casting the startTowerDiscovery() func
func harborDidDiscoverTowers(_ towers: [HarborLockersSDK.Tower]) {
// Handle tower discovery
}
These methods will return a list of towers that are in range of your bluetooth connection.
Find towers in a specific area#
You can find a list of locations in a certain area with gps coordinates.
curl -X 'GET' \
'https://api.harborlockers.com/api/v1/locations/?start=38.3498,-121.6181&end=38.6857,-121.3466' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {access token}'
In this code there is ?start=38.3498,-121.6181&end=38.6857,-121.3466 on the end of the url. Where start and end are two points that form a rectangular area where to show towers. This is what controls the towers that will be shown the the user. The coordinates provided will give the user all towers in Sacramento California.
Note
You can find more specfic api calls and even test run them in our api docs
Once the user has selected a location. We should detemine what kind of user they are.
Session roles#
You will want to connect to the tower and establish your session role.
Session roles include:
1 - locker_pickup - allowed to open specific lockers, request must be separately signed by the server
2 - locker_delivery - allowed to open any locker with the correct token, or any ‘available’ locker. No additional server signing required.
3 - owner - can run most configuration and diagnostic commands
4 - technician - can run almost all configuration and diagnostic commands
5 - developer - can run all commands and perform “unsafe” operations
You can establish your session with our SDK by passing a number.
HarborLockersSDK.sendRequestSession(4)
Establishing session and Connecting to a tower#
In order to get information about the tower, you will need to connect to it. This can be done with either sendRequestSession or establishSession depending on what you are using.
const connectToMyTower = towerId => {
HarborLockersSDK.connectToTowerWithIdentifier(towerId)
.then(_ => {
HarborLockersSDK.sendRequestSession(
4, // this is our session role.
(errorCode, errorMessage) => {
displayAlert(
`Error establishing session - ${errorCode}`,
errorMessage,
);
},
() => {
waitForTowerToCompleteSync(TOWER_SYNC_TIMEOUT);
},
);
})
};
HarborSDK.shared.connectToTower(tower) { result, error in
// Check if there was an error in connecting to the tower
guard error == nil else {
print("Error connecting to tower: \(error!.localizedDescription)")
return
}
// Connection to the tower was successful, now establish a session
HarborSDK.shared.establishSession(towerId: nil, sessionPermissions: Constants.SESSION_ROLE) { success, error in
// Handle the success or failure of establishing a session
if success {
print("Session established successfully")
} else {
print("Failed to establish session: \(error?.localizedDescription ?? "Unknown error")")
}
}
}
HarborSDK.shared.connectToTower(tower) { result, error ->
// Check if there was an error in connecting to the tower
if (error != null) {
println("Error connecting to tower: ${error.localizedMessage}")
return@connectToTower
}
// Connection to the tower was successful, now establish a session
HarborSDK.shared.establishSession(null, Constants.SESSION_ROLE) { success, error ->
// Handle the success or failure of establishing a session
if (success) {
println("Session established successfully")
} else {
println("Failed to establish session: ${error?.localizedMessage ?: "Unknown error"}")
}
}
}
Tower Syncing#
In the React Native example you may have noticed waitForTowerToCompleteSync
. While connecting to the tower the harbor SDK will establish a sync session with the tower.
You can check this with:
HarborLockersSDK.isSyncing()
This will return a boolean called syncing, you will not be able to send any more requests before the tower is done syncing. Your app will need to handle waiting for syncing to be false before sending more requests.
Here is an example from our React Native Example App on how to handle syncing.
const waitForTowerToCompleteSync = retryCount => {
HarborLockersSDK.isSyncing(syncing => {
if (retryCount === 0) {
displayAlert('Timeout exceeded', 'Tower could not sync');
} else if (syncing) {
setTimeout(() => {
waitForTowerToCompleteSync(retryCount - 1);
}, 1000);
} else {
setAccessConfig({...accessConfig, my_tower_is_synced: true});
}
});
};
Disconnecting from a tower#
You can only connect to one tower a time. So if you ever need to end your connection with a tower, you can call sendTerminateSession in your code and send a value of ‘0’ and then a string explaining the reason.
HarborLockersSDK.sendTerminateSession(0, 'Session terminated by user');
Now that you found your tower and synced, time to Make a delivery!