Discovering towers
Initializing the SDK and setting your access token
Initializing your SDK and setting your access token.
HarborSDK.shared.delegate = self
HarborSDK.shared.setupLogger(delegate: self, level: .debug) // Do not use in Production
HarborSDK.shared.setEnvironment(Environment.Sandbox)
HarborSDK.shared.setAccessToken(token)
HarborSDK.setDelegate(this)
HarborSDK.setOutputConsole(this)
HarborSDK.setEnvironment(Environment.SANDBOX) // This can be set to `PRODUCTION` or `SANDBOX`, case sensitive, all caps
HarborSDK.setAccessToken(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.
Here’s a full example of how to set up your delegate.
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")
}
}
HarborLockersSDK.initializeSDK();
Finding towers
Connecting to a specific tower
HarborLockersSDK.connectToTowerWithIdentifier(towerId)
Finding nearby towers
This step varies by what you are using.
// 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
}
HarborLockersSDK.startTowersDiscovery()
These methods will return a list of towers that are in range of your bluetooth connection.
Note
If you don’t see any towers returned, try moving closer to your tower. You should stay within 10 feet of your tower.
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 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 show 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 sesssion 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.
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"}")
}
}
}
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);
},
);
})
};
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!