# BLE SDK for iOS

# Introduction

The NBIoTBleKit SDK allows you to build your own APP for controlling segway vehicles via Bluetooth quickly.

# Get Started

# Step 1: Get an SDK key and operator code

Follow the steps in this guide to download the NBIoTBleKit SDK for iOS, to add the library and its dependencies to your app, and to get a SDK key and operator code.

First of all, you should get the SDK key and operator code. You’ll be able to find your key in the backend following these steps.

Click the icon to bring up the drop-down menu, then click the Basic information item.

Scroll to the bottom, you can see the View button following the Bluetooth SDK key box.

Click the View button and type your password to confirm.

Good job, now you can see your key, and you can copy that through a quick button.

Done, any problem please contact us.

# Step 2: Get the latest version of Xcode

To build a project using the NBIoTBleKit SDK for iOS, you need:

1、Xcode version 12.0 or later

2、Cocoapods

# Step 3: Install the SDK

To install the API in a new project , follow these steps:

# Use Cocoapods

The NBIoTBleKit SDK for iOS is available as a CocoaPod pod, NBIoTBleKit, which contains all bluetooth control bike functionality.

CocoaPods is an open source dependency manager for Swift and Objective-C Cocoa projects. If you don't already have the CocoaPods tool, install it on macOS by running the following command from the terminal. For details, see the CocoaPods Getting Started guide.

sudo gem install cocoapods

Create a Podfile for the NBIoTBleKit SDK for iOS and use it to install the SDK and its dependencies

  • If you don't have an Xcode project yet, create one now and save it to your local machine. (If you're newer to iOS development, create a new project and select the iOS App template. In Xcode 11.7 or earlier, create a Single View Application.)

  • Create a file named Podfile in your project directory. This file defines your project's dependencies.

  • Edit the Podfile and add your dependencies along with their versions. Here is an example which specifies your application target name, and the name of the NBIoTBleKit pod:

target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
  pod 'NBIoTBleKit', '~> 1.1.0'
end

Make sure to regularly run pod outdated to detect when there is a newer version to ensure you're always on the latest.

  • Save the Podfile
  • Open a terminal and go to the directory containing the Podfile:
cd <path-to-project>
  • Run the pod install command. This will install the APIs specified in the Podfile, along with any dependencies they may have.
pod install
  • Close Xcode, and then open (double-click) your project's .xcworkspace file to launch Xcode. From this time onwards, you must use the .xcworkspace file to open the project.

To update the API for an existing project, follow these steps:

  • Open a terminal and go to the project directory containing the Podfile.
  • Run the pod update command. This will update all of the APIs specified in the Podfile to the latest version.

# Step 4: Add privacy to info.plist

  • Add Privacy - Bluetooth Peripheral Usage Description to info.plist
  • Add Privacy - Bluetooth Always Usage Description to info.plist

# Step 5: Start writing code

You can click code samples to download sample project.

For more details to use SDK, see the Dev Guide.

# Dev Guide

# Step 1: Adding the SDK key and operator code to your APP

In the following examples, replace YOUR_API_SECRET with your SDK key, and YOUR_OPERATOR_CODE with your operator code.

Add your SDK key and operator code to your AppDelegate.swift(or AppDelegate.m ) as follows:

  • add the following import statement:
//swift
import NBIoTBleKit
//objective-c
#import <NBIoTBleKit/NBIoTBleKit.h>
  • Add the following to your application(_:didFinishLaunchingWithOptions:) method, replacing YOUR_API_SECRET with your SDK key, and YOUR_OPERATOR_CODE with your operator code:
///swift
NBIoTBleService.shared().start(withOperatorCode: "YOUR_OPERATOR_CODE", andSecret: "YOUR_API_SECRET") { isSuccess, error in
    if isSuccess {
        print("Register successfully")
    }
    
    if let error = error {
        print("\(error)")
    }
}
//objective-c
[NBIoTBleService.shared startWithOperatorCode:@"YOUR_OPERATOR_CODE" andSecret:@"YOUR_API_SECRET" completionHanlder:^(BOOL isSuccess, NSError * _Nullable error) {
    if (isSuccess) {
        NSLog(@"Register successfully");
    } else {
        NSLog(@"%@", error);
    }
}];

# Step 2: Use SDK methods in your code

# Vehicle API Guide

# Init

In your ViewController, create a NBIoTBle property to call functons. And implement proxy methods to handle the returned results

import UIKit
import NBIoTBleKit

class ViewController: UIViewController {    
    lazy var iotControllTool: NBIoTBle = {
        let controllTool = NBIoTBle()
        controllTool.delegate = self
        return controllTool
    }()
}

# Connect a vehicle

You can click code samples to download sample project.

Connect the vehicle via IMEI and MAC address, make sure the vehicle is not connected to another bluetooth device before connecting.

WARNING

Before calling this method, you need to register the SDK

//swift
iotControllTool.connectDevice(byIMEI: "VEHICLE_IMEI", macAddress: "VEHICLE_MAC_ADRESS", andDeviceKey: "DEVICE_KEY")
//objc
[self.iotControllTool connectDeviceByIMEI: @"VEHICLE_IMEI"
                           macAddress:@"VEHICLE_MAC_ADRESS"
                         andDeviceKey:@"DEVICE_KEY"];

# Disconnect a vehicle

//swift
iotControllTool.disconnect()
//objc
[self.iotControllTool disconnect];

# Handle the command result

//swift
extension ViewController: NBIoTBleDelegate {
    func bluetoothStateChanged(_ state: CBManagerState) {
        log("bluetooth state changed: \(state.rawValue)")
    }
    
    func connectionStateChange(_ state: ConnectionState) {
        log("connection state changed: \(state.rawValue)")
    }
    
    func connectDevice(onError error: Error?) {
        log("connect device on error: \(error.debugDescription)")
    }
    
    /// handle the unlock result.
    func unlockScooterResult(_ isSuccess: Bool, withError error: Error?) {
        if isSuccess {
            log("unlock successful!")
        } else {
            log("unlock failed! \(error?.localizedDescription ?? "")")
        }
    } 
}
// objc
@interface ViewController () <NBIoTBleDelegate>

@end

@implementation ViewController
- (void)bluetoothStateChanged:(CBManagerState)state {
}

- (void)connectionStateChange:(ConnectionState)state {
}

- (void)connectDeviceOnError:(NSError *)error {
}

- (void)unlockScooterResult:(BOOL)isSuccess withError:(NSError *)error {
}
@end

WARNING

Before using the following methods, you need to register the SDK and keep the Bluetooth device connected.

# Unlock

//swift
iotControllTool.unlock()
//objc
[self.iotControllTool unlock];

# Handle the command result

// objc
- (void)unlockScooterResult:(BOOL)isSuccess withError:(NSError *)error {
    if (isSuccess) {
        NSLog(@"unlock success");
    } else {
        NSLog(@"unlock failed");
    }
}
// swift
func unlockScooterResult(_ isSuccess: Bool, withError error: Error?) {
    if isSuccess {
        print("unlock successful!")
    } else {
        print("unlock failed! \(error?.localizedDescription ?? "")")
    }
}

# Lock

//swift
iotControllTool.lock()
//objc
[self.iotControllTool lock];

# Handle the command result

// objc
- (void)lockScooterResult:(BOOL)isSuccess withError:(NSError *)error {
    if (isSuccess) {
        NSLog(@"lock success");
    } else {
        NSLog(@"lock failed");
    }
}
// swift
func lockScooterResult(_ isSuccess: Bool, withError error: Error?) {
    if isSuccess {
        print("lock successful!")
    } else {
        print("lock failed! \(error?.localizedDescription ?? "")")
    }
}

# Query IoT information

//swift
iotControllTool.queryIoTInformation()
//objc
[self.iotControllTool queryIoTInformation];

# Handle the command result

// objc
- (void)queryIoTInfomationResult:(NBIoTInfo *)iotInfo withError:(NSError *)error {
    if (iotInfo) {
       NSLog(@"%@", iotInfo);
    }
}
// swift
func queryIoTInfomationResult(_ iotInfo: NBIoTInfo?, withError error: Error?) {
    if let iotInfo = iotInfo {
        print("query IoT info success:\n \(iotInfo.description)")
    } else {
        print("open tail box failed! \(error?.localizedDescription ?? "")")
    }
}

attached:'NBIoTInfo'

Field Type Description Note
voltage int current voltage of IoT, unit: mV supported from v1.1.0
isLocked boolean YES/true = locked, NO/false = unlocked supported from v1.1.0
majorVersionNumber int major versionNumber supported from v1.1.0
minorVersionNumber int minor versionNumber supported from v1.1.0
updateTimes int IoT device software version update times. supported from v1.0.0
voltageH int use `voltage` instead deprecated from v1.1.0
voltageL int use `voltage` instead deprecated from v1.1.0
powerStatus NBIotPowerStatus use `isLocked` instead deprecated from v1.1.0
mainVersion int use `majorVersionNumber` instead deprecated from v1.1.0
secondVersion int use `minorVersionNumber` instead deprecated from v1.1.0

# Query vehicle information

//swift
iotControllTool.queryVehicleInformation()
//objc
[self.iotControllTool queryVehicleInformation];

# Handle the command result

// objc
- (void)queryVehicleInformationResult:(NBVehicleInfo *)vehicleInfo withError:(NSError *)error {
    if (vehicleInfo) {
       NSLog(@"%@", vehicleInfo);
    }
}
// swift
func queryVehicleInformationResult(_ scooterInfo: NBVehicleInfo?, withError error: Error?) {
    if let scooterInfo = scooterInfo {
        print("query scooter info success:\n \(scooterInfo.description)")
    } else {
        print("open tail box failed! \(error?.localizedDescription ?? "")")
    }
}

attached:'NBVehicleInfo'

Field Type Description Note
powerPercent int battery percentage, 80->80% supported from v1.1.0
speedMode int speed mode(NBSpeedModeLowSpeed, NBSpeedModeMediumSpeed, NBSpeedModeHighSpeed) supported from v1.0.0
currentSpeed int current speed, unit: km/h supported from v1.1.0
totalRange int total range, unit: 10m supported from v1.1.0
remainingRange int remaining range, unit: 10m supported from v1.1.0
power int use `powerPercent` instead deprecated from v1.1.0
speed int use `currentSpeed` instead deprecated from v1.1.0
mileage int use `totalRange` instead deprecated from v1.1.0
rangeAvailable int use `remainingRange` instead deprecated from v1.1.0

# Open the battery cover

//swift
iotControllTool.openBatteryCover()
//objc
[self.iotControllTool openBatteryCover];

# Handle the command result

// objc
- (void)openBatteryCoverResult:(BOOL)isFinished withError:(NSError *)error {
    if (isFinished) {
        NSLog(@"open battery cover successfully")
    }
}
// swift
func openBatteryCoverResult(_ isFinished: Bool, withError error: Error?) {
    if isFinished {
        print("open battery cover successful!")
    } else {
        print("open battery cover failed! \(error?.localizedDescription ?? "")")
    }
}

# Open the saddle

//swift
iotControllTool.openSaddle()
//objc
[self.iotControllTool openSaddle];

# Handle the command result

// objc
- (void)openSaddleResult:(BOOL)isFinished withError:(NSError *)error {
    if (isFinished) {
        NSLog(@"open saddle successfully")
    }
}
// swift
func openSaddleResult(_ isFinished: Bool, withError error: Error?) {
    if isFinished {
        print("open saddle successful!")
    } else {
        print("open saddle failed! \(error?.localizedDescription ?? "")")
    }
}

# Open the tailbox

//swift
iotControllTool.openTailBox()
//objc
[self.iotControllTool openTailBox];

# Handle the command result

// objc
- (void)openTailboxResult:(BOOL)isFinished withError:(NSError *)error {
    if (isFinished) {
        NSLog(@"open tailbox successfully")
    }
}
// swift
func openTailboxResult(_ isFinished: Bool, withError error: Error?) {
    if isFinished {
        print("open tail box successful!")
    } else {
        print("open tail box failed! \(error?.localizedDescription ?? "")")
    }
}

# Unlock Pre-installed Helmet Lock

//swift
iotControllTool.unlockHelmet()
//objc
[self.iotControllTool unlockHelmet];

# Handle the command result

// objc
- (void)unlockHelmetResult:(BOOL)isSuccess withError:(NSError *)error {
    if (isSuccess) {
        NSLog(@"unlock success");
    } else {
        NSLog(@"unlock failed");
    }
}
// swift
func unlockHelmetResult(_ isSuccess: Bool, withError error: Error?) {
    if isSuccess {
        print("unlock successful!")
    } else {
        print("unlock failed! \(error?.localizedDescription ?? "")")
    }
}

# Lock Pre-installed Helmet Lock

//swift
iotControllTool.lockHelmet()
//objc
[self.iotControllTool lockHelmet];

# Handle the command result

// objc
- (void)lockHelmetResult:(BOOL)isSuccess withError:(NSError *)error {
    if (isSuccess) {
        NSLog(@"lock success");
    } else {
        NSLog(@"lock failed");
    }
}
// swift
func lockHelmetResult(_ isSuccess: Bool, withError error: Error?) {
    if isSuccess {
        print("lock successful!")
    } else {
        print("lock failed! \(error?.localizedDescription ?? "")")
    }
}

# Helmet Lock API Guide

# Init supported from v1.1.0

In your ViewController, create a NBHelmetBle property to call functons. And implement proxy methods to handle the returned results

import UIKit
import NBIoTBleKit

class ViewController: UIViewController {    
    lazy var helmetControllTool: NBHelmetBle = {
        let controllTool = NBHelmetBle()
        controllTool.delegate = self
        return controllTool
    }()
}

# Connect a Helmet Lock supported from v1.1.0

You can click code samples to download sample project.

Connect the vehicle via IMEI and MAC address, make sure the vehicle is not connected to another bluetooth device before connecting.

WARNING

Before calling this method, you need to register the SDK

//swift
helmetLockController.connectDevice(byMacaddress: "macaddress" , andDeviceKey: "device key")
//objc
[self.helmetTool connectDeviceByMac: @"HELMET_MAC_ADRESS" andDeviceKey:@"DEVICE_KEY"]

# Disconnect a Helmet Lock supported from v1.1.0

//swift
helmetLockController.disconnect()
//objc
[self.helmetTool disconnect];

# Handle the command result supported from v1.1.0

//swift
extension ViewController: NBHelmetBleDeleagate {
    func bluetoothStateChanged(_ state: CBManagerState) {
        log("bluetooth state changed: \(state.rawValue)")
    }
    
    func connectionStateChange(_ state: ConnectionState) {
        log("connection state changed: \(state.rawValue)")
    }
    
    func connectDevice(onError error: Error?) {
        log("connect device on error: \(error.debugDescription)")
    }
}
// objc
@interface ViewController () <NBHelmetBleDeleagate>

@end

@implementation ViewController
- (void)bluetoothStateChanged:(CBManagerState)state {
}

- (void)connectionStateChange:(ConnectionState)state {
}

- (void)connectDeviceOnError:(NSError *)error {
}
@end

WARNING

Before using the following methods, you need to register the SDK and keep the Bluetooth device connected.

# Unlock supported from v1.1.0

//swift
helmetLockController.unlock()
//objc
[self.helmetTool unlock];

# Handle the command result supported from v1.1.0

// objc
- (void)unlockHelmetLockResult:(BOOL)isSuccess withError:(NSError *)error {
    if (isSuccess) {
        NSLog(@"unlock successfully");
    } else {
        NSLog(@"unlock failed");
    }
}
// swift
func unlockHelmetLockResult(_ isSuccess: Bool, withError error: Error?) {
    if isSuccess {
        log("unlock successful!")
    } else {
        log("unlock failed! \(error?.localizedDescription ?? "")")
    }
}

# Query Helmet Lock Status supported from v1.1.0

//swift
helmetLockController.queryLockStatus()
//objc
[self.helmetTool queryLockStatus];

# Handle the command result supported from v1.1.0

// objc
- (void)queryHelmetLockStatusResult:(NBHelmetLockStatus *)helmetLockStatus withError:(NSError *)error {
    if (isSuccess) {
        NSLog(@"%@", helmetLockStatus);
    } else {
        NSLog(@"unlock failed");
    }
}
// swift
func queryHelmetLockStatusResult(_ helmetLockStatus: NBHelmetLockStatus?, withError error: Error?) {
    if let status = helmetLockStatus {
        log("get helmet lock status successful! \(status)")
    } else {
        log("failed! \(error?.localizedDescription ?? "")")
    }
}

attached:'NBHelmetLockStatus'

Field Type Description Note
isLocked Bool true/YES = locked, false/NO = unlocked
voltage int current voltage of the lock, unit: mV

# Query Helmet Lock Infomation supported from v1.1.0

//swift
helmetLockController.queryLockInfo()
//objc
[self.helmetTool queryLockInfo];

# Handle the command result supported from v1.1.0

// objc
- (void)queryHelmetLockInfomationResult:(NBHelmetLockInfo *)helmetLockInfo withError:(NSError *)error {
    if (isSuccess) {
        NSLog(@"%@", helmetLockInfo);
    } else {
        NSLog(@"unlock failed");
    }
}
// swift
func queryHelmetLockInfomationResult(_ helmetLockInfo: NBHelmetLockInfo?, withError error: Error?) {
    if let info = helmetLockInfo {
        log("get helmet lock info successful! \(info)")
    } else {
        log("failed! \(error?.localizedDescription ?? "")")
    }
}

attached:'NBHelmetLockInfo'

Field Type Description Note
powerPercent int battery percentage, 80->80%
firmwareVersion String firmware version

# Release Note

# v1.1.2

  1. Add interface of lock helmet for the new device of Helmet & Cable lock

# v1.1.1

  1. Add event callback when disconnected from the device

# v1.1.0

  1. Add status of lock in the interface of Query IoT information
  2. Add field description in the query result
  3. Add support for helmet lock

# v1.0.0

  1. initial version