1. Plugin Access Steps
1.1 Project Introduction Plugin
1.1.1 Via Cocoapods
//Add the plugin and specify the version in the project Podfile file.
pod 'QNSDK', '2.29.0' //The version number can be replaced with the latest version shown on GitHub
1.1.2 Via Carthage
//Add the plugin dependency to the project's Cartfile.
github "https://github.com/YolandaQingniu/sdk-ios-demo.git"
1.1.3 Manual Import Method
1. Place the .a file in the designated directory within the project.
2. Add the SDK path in【TARGETS】-> 【Build Setting】->【Search Paths】->【LibrarySearch Paths】
3. Configure the linker settings in 【TARGETS】-> 【Build Setting】-> 【Linking】-> 【Other Linker Flags】,and add one of the following options: -ObjC、-all_load、-force_load [sdk path]
1.2 Instructions for Using Bluetooth Permissions in Configuration Item
Add Privacy - Bluetooth Peripheral Usage Description, Privacy - Bluetooth Always Usage Description keys to the Info.plist file of the project to provide a description of Bluetooth usage
1.3 Import Plugin API Header File
#import <QNSDK/QNDeviceSDK.h>
1.4 Initial Plugin
//Get the path of the authorization file in the project
NSString *file = [[NSBundle mainBundle] pathForResource:@"123456789" ofType:@"qn"];
//Initialize the plugin. QNBleApi is implemented as a singleton.
QNBleApi *bleApi = [QNBleApi sharedBleApi];
//Request plugin authorization
[bleApi initSdk:@"123456789" firstDataFile:file callback:^(NSError *error) {
if(error) {
}
}];
1.5 Listen for system Bluetooth state changes (QNBleStateListener)
/*
typedef NS_ENUM(NSUInteger, QNBLEState) {
QNBLEStateUnknown = 0, //Unknown state
QNBLEStateResetting = 1, //System Bluetooth is resetting
QNBLEStateUnsupported = 2, //Bluetooth is not supported by the system
QNBLEStateUnauthorized = 1, //Bluetooth usage is not authorized
QNBLEStatePoweredOff = 2, //System Bluetooth is powered off
QNBLEStatePoweredOn = 5, //System Bluetooth is powered on
};
*/
- (void)onBleSystemState:(QNBLEState)state {
}
bleApi.bleStateListener = self;
1.6 Listen for changes in the scanning status (QNBleDeviceDiscoveryListener)
//Callback triggered when scanning starts.
- (void)onStartScan {
}
//Callback triggered when scanning stops.
- (void)onStopScan {
}
//Callback triggered when a device is discovered during scanning. Only supported devices are reported here.
- (void)onDeviceDiscover:(QNBleDevice *)device {
}
bleApi.discoveryListener = self;
1.7 Listen for device connection state changes (QNBleConnectionChangeListener)
//Callback triggered when the device is connecting
- (void)onConnecting:(QNBleDevice *)device {
}
//Callback triggered when the device has successfully connected
- (void)onConnected:(QNBleDevice *)device {
}
//Callback triggered when the device's communication services have been discovered. Usually no additional logic is required here
- (void)onServiceSearchComplete:(QNBleDevice *)device {
}
//Callback triggered when the device connection fails, returning the error information
- (void)onConnectError:(QNBleDevice *)device error:(NSError *)error {
}
//Callback triggered when the device is ready for interaction. At this point, device-specific operation commands can be sent
- (void)onStartInteracting:(QNBleDevice *)device {
}
//Callback triggered when the device is disconnecting
- (void)onDisconnecting:(QNBleDevice *)device {
}
//Callback triggered when the device has disconnected
- (void)onDisconnected:(QNBleDevice *)device {
}
1.8 Listen for device data interaction (QNUserScaleDataListener)
/* Scale interaction state changes
typedef NS_ENUM(NSInteger, QNScaleState) {
QNScaleStateDisconnected = 0, //Not connected
QNScaleStateLinkLoss = -1, //Connection lost
QNScaleStateConnected = 1, //Connected
QNScaleStateConnecting = 2, //Connecting
QNScaleStateDisconnecting = 1, //Disconnecting
QNScaleStateStartMeasure = 2, //Measuring
QNScaleStateRealTime = 5, //Measuring weight in real time
QNScaleStateBodyFat = 7, //Measuring bioelectrical impedance
QNScaleStateMeasureCompleted = 9, //Measurement completed
}; Focus only on the states defined in this class.
*/
- (void)onScaleStateChange:(QNBleDevice *)device scaleState:(QNScaleState)state {
}
/* Scale-side behavior state changes
typedef NS_ENUM(NSInteger, QNScaleEvent) {
QNScaleEventRegistUserSuccess = 2, //User registration succeeded
QNScaleEventRegistUserFail = 5, //User registration failed
QNScaleEventVisitUserSuccess = 6, //User access succeeded
QNScaleEventVisitUserFail = 7, //User access failed
QNScaleEventDeleteUserSuccess = 8, //User deletion succeeded
QNScaleEventDeleteUserFail = 9, //User deletion failed
QNScaleEventSyncUserInfoSuccess = 10, //User information sync succeeded
QNScaleEventSyncUserInfoFail = 11, //User information sync failed
QNScaleEventUpdateIdentifyWeightSuccess = 12, //User identification weight update succeeded
QNScaleEventUpdateIdentifyWeightFail = 13, //User identification weight update failed
};Focus only on the states defined in this class.
*/
- (void)onScaleEventChange:(QNBleDevice *)device scaleEvent:(QNScaleEvent)scaleEvent {
}
//Write back a valid measurement HMAC (i.e., a body fat scale data HMAC greater than 0) to a specified user slot on the device.
//This can help improve the stability of the user's bioelectrical impedance measurement.
//If stability reinforcement is not required, you can simply return nil
- (NSString *)getLastDataHmac:(QNBleDevice *)device user:(QNUser *)user {
//Obtain the HMAC from the most recent measurement in the user's measurement history where the body fat percentage is greater than 0.
//The HMAC is generated from the measurement data, as defined in the QNScaleData object.
NSString *hmac = lastVailDataHmac;
return hmac;
}
// Called when a user is successfully registered on the scale.
// Returns the user slot assigned by the device.
- (void)registerUserComplete:(QNBleDevice *)device user:(QNUser *)user {
// The user slot assigned by the scale during user registration.
// The app should associate and save this slot with the user ID and device MAC.
// The slot index will be used for accessing the user's measurements when the user reconnects to this device.
int index = user.index;
}
// Callback for real-time weight during the measurement process
// weight Real-time weight in kilograms (kg)
- (void)onGetUnsteadyWeight:(QNBleDevice *)device weight:(double)weight {
}
// Callback triggered when the device completes a measurement
- (void)onGetScaleData:(QNBleDevice *)device data:(QNScaleData *)scaleData {
//Get the full measurement data after the measurement is completed.
NSDate *measureData = scaleData.measureTime;//Measured time
double weight = scaleData.weight;//Measured weight
NSArray <QNScaleItemData *> *allTarget = [scaleData getAllItem];
for (QNScaleItemData *item in allTarget) {
item.type //Indicator type, see QNScaleType
item.value //Indicator value
}
}
// Callback for currently accessed user's stored data and unknown stored data
// storedDataList List of stored data. Use the `isDataComplete` property in `QNScaleStoreData` to determine if the data is from an unknown measurement:
// false indicates unknown measurement data, true indicates known measurement data.
- (void)onGetStoredScale:(QNBleDevice *)device data:(NSArray <QNScaleStoreData *> *)storedDataList {
//For unknown measurement data, you can notify the relevant user and let them choose whether this data belongs to them.
NSMutableArray<QNScaleStoreData *> *unknowStoreDataList = [NSMutableArray array];
for (QNScaleStoreData *storeData in storedDataList) {
if(!storeData.isDataComplete){
[unknowStoreDataList addObject:storeData];
} else {
//For known stored data of the current user, the data can be directly attributed to that user.
QNScaleData *scaleData = [storeData generateScaleDataWithLastEightHmac: nil];
for (QNScaleItemData *item in allTarget) {
item.type //Indicator type, see QNScaleType
item.value //Indicator value
}
}
}
}
1.9 Scan surrounding devices
[bleApi startBleDeviceDiscovery:^(NSError *error) {
}];
1.10 Connect Device
// It is recommended to stop scanning first
[_bleApi stopBleDeviceDiscorvery:^(NSError *error) { }];
// Set the scale unit
QNConfig *sdkConfig = [QNConfig sharedConfig];
sdkConfig.unit = QNUnitKG;
[sdkConfig save];
QNUserScaleConfig *config = [[QNUserScaleConfig alloc] init];
// List of registered scale users. During this connection, users on the scale
// that are not included in this array will be deleted from the device.
NSMutableArray<QNUser *> *deviceUserList = [NSMutableArray array];
config.userlist = deviceUserList;
// Scale user for the current connection
QNUser *user = [[QNUser alloc] init];
//User height in centimeters (cm)
user.height = 170;
user.gender = @"male";//"male"、"female"
//User birthday
user.birthday = [NSDate dateWithTimeIntervalSince1970:631199317];
// User slot. This value is returned by the scale when registering a user on the device (see the `registerUserComplete` callback).
// If this connection is for a new user on the device and the user needs to be registered, this property does not need to be set.
user.index = 1;
config.curUser = user;
// Whether to use a guest user (i.e., no registration on the scale; the scale will not store this user's information).
// Note: This field is mutually exclusive with `user.index`; `isVisitor` takes priority.
config.isVisitor = false;
[bleApi connectUserScaleDevice:device config:config callback:^(NSError *error) {
}];
1.11 Disconnect the device
// If needed, you can proactively call the method to disconnect the device
[bleApi disconnectDevice:nil callback:^(NSError *error) {
}];
1.12 Unknown Storage Data Calculation
//User information for unknown stored data ownership
QNUser *user = [[QNUser alloc] init];
user.height = 170
user.gender = @"male";//"male"、"female"
//User birthday
user.birthday = [NSDate dateWithTimeIntervalSince1970:631199317];//用户生日
// hmac: The HMAC of the current unknown measurement data, i.e., the `hmac` in QNScaleStoreData.
// lastHmac: The HMAC of the user's previous measurement with body fat > 0 (8-electrode measurement), i.e., the `hmac` in QNScaleData.
//If the user has no previous measurement with body fat > 0, this can be set to nil.
QNScaleData scaleData = [bleApi calculateScaleDataByHmac:user hmac:hmac lastEightHmac:lastHmac callback:^(NSError *error) {
}];
2. API
2.1 QNBleApi
Plugin instance object, used to call plugin-related APIs
2.1.1 sharedBleApi
Description:Constructs a singleton of the QNBleApi object, which is the only function for initializing the plugin
Return value: QNBleApi
2.1.2 getConfig
Description:Get plugin configuration information
Return value:
QNConfig
duration: Scan timeout period, default is 0, which means no scan timeout will occur; if this value is set, the scan will automatically stop within the specified time after starting, and the scan call needs to be maintained manually
unit: Set the user unit at the scale end, but when initiating a device connection, the unit settings will be synchronized to the scale end
- QNUnitKG、QNUnitLB、QNUnitJIN、QNUnitStLb、QNUnitSt
showPowerAlertKey: Whether to allow the system to automatically pop up the Bluetooth permission dialog box, which needs to be set before the initSdk function
2.1.3 initSdk:firstDataFile:callback:
Description:Initialize the plugin by passing the configuration file path. After calling this function, if the showPowerAlertKey set in QNConfig is true, the system will automatically pop up a prompt to ask for permission, and this prompt is automatically initiated by the system.
Parameters:
appId: APPID authorized by YKB
dataFile: The relative path of the configuration file within the project
callback: Callback for function call result
2.1.4 initSdk:dataFileContent:callback:
Description: Initialize the plugin by passing the content of the configuration file. After calling this function, if the showPowerAlertKey set in QNConfig is true, the system will automatically pop up a prompt to ask for permission, and this prompt is automatically initiated by the system
2.1.5 getCurSystemBleState
Description:Get the current system Bluetooth status
Return value:
- QNBLEState:QNBLEStateUnknown、QNBLEStateResetting、QNBLEStateUnsupported、QNBLEStateUnauthorized、QNBLEStatePoweredOff、QNBLEStatePoweredOn
2.1.6 startBleDeviceDiscovery:
Description:Start scanning for surrounding devices
Parameters:
- callback: Callback for function call result
2.1.7 stopBleDeviceDiscorvery:
Description:Stop scanning for surrounding devices
Parameters:
- callback: Callback for function call result
2.1.8 connectUserScaleDevice:config:callback:
Description: Initiate a connection to a specified device
Parameters:
device: The scanned device, obtained from the device object in the callback of the onDeviceDiscover function in QNBleDeviceDiscoveryListener
config: Configuration information for this connection
userlist: List of registered users at the scale end. Users not in this list will be deleted from the device during this connection.
curUser: The user of the currently connected device
height: height, unit cm
gender: sex, male - "male"; female - "female"
birthday: birthday
index: User slot at the scale end. When the current connection is for registering a user with the scale end, this field does not need to be assigned a value. If assigned, the process of accessing device users will be followed.
isVisitor: Whether to use the scale-side visitor measurement. This field has a high priority.
callback: Callback for function call result
2.1.9 disconnectDevice:callback:
Description:Disconnect the currently connected device
Parameters:
device: The currently connected device object, which may not need to be assigned a value
callback: Callback for function call result
2.1.10 calculateScaleDataByHmac:hmac:lastEightHmac:callback:
Description:Recalculate measurement data, which can be used for calculating unknown stored data, and can also be used for recalculating known measurement data that needs to be changed to data measured by other users
Parameters:
user: User information to which this measurement data belongs
height: height, unit cm
gender: sex, male - "male"; female - "female"
birthday: birthday
hmac: The hmac of the current measurement data
lastEightHmac: The previous eight-electrode measurement data of the user to whom this measurement data belongs, with body fat percentage greater than 0; if none, assign nil
callback: Function call result
2.2 QNBleStateListener
Callback listener for system Bluetooth status changes
2.2.1 onBleSystemState
Description: When the system Bluetooth changes, this function is called back
Parameters:
- state: QNBLEState state type
2.3 QNBleDeviceDiscoveryListener
2.3.1 onStartScan
Description: This function is called back when scanning is initiated, such as when calling the startBleDeviceDiscovery function
2.3.2 onStopScan
Description: This function is called back when scanning stops, such as when the stopBleDeviceDiscorvery function is called
2.3.3 onDeviceDiscover
Description:Callback when surrounding devices are discovered. This function only returns YKB devices.
Parameters:
device: discovered device
mac: Device MAC address, the unique identifier of the device
name: Device Nickname
modeId: Identifier for device type
bluetoothName: Device Bluetooth Name
RSSI: Device Model Strength
maxUserNum: Maximum number of registered users supported by the device
registeredUserNum: Number of registered users of the device
2.4 QNBleConnectionChangeListener
2.4.1 onConnecting
Description:Callback when the device is connecting
Parameters:
- device: device object
2.4.2 onConnected
Description:Callback after the device is successfully connected
Parameters:
- device: device object
2.4.3 onDisconnecting
Description:Callback when the device is disconnecting
Parameters:
- device: device object
2.4.4 onDisconnected
Description:Callback when the device is already disconnected
Parameters:
- device: device object
2.4.5 onConnectError:error:
Description:Callback when device connection is abnormal
Parameters:
device: device object
error: connection error message
2.4.6 onStartInteracting
Description:Device communication callback. After this function, some API operations of the device can be called, such as updating the user's basic weight, etc.
Parameters:
device: device object
error: connection error message
2.5 QNUserScaleDataListener
2.5.1 onScaleStateChange:scaleState:
Description:Callback for device status changes, such as connection status, measurement status, etc.
Parameters:
device: device object
state: device status
QNScaleStateDisconnected Not Connected
QNScaleStateLinkLoss lost connection
QNScaleStateConnected Connected
QNScaleStateConnecting is connecting
QNScaleStateDisconnecting is disconnecting
QNScaleStateStartMeasure is measuring
QNScaleStateRealTime is measuring weight
QNScaleStateBodyFat is measuring bioelectrical impedance
QNScaleStateMeasureCompleted Measurement Completed
2.5.2 onScaleEventChange:scaleEvent:
Description:Device event callbacks, such as connection status, measurement status, etc.
Parameters:
device: device object
scaleEvent: Device event type
QNScaleEventRegistUserSuccess User registration successful
QNScaleEventRegistUserFail Registration User Failed
QNScaleEventVisitUserSuccess User Visit Successful
QNScaleEventVisitUserFail User access failed
QNScaleEventDeleteUserSuccess User deletion successful
QNScaleEventDeleteUserFail Delete User Failed
QNScaleEventSyncUserInfoSuccess User information synchronization successful
QNScaleEventSyncUserInfoFail Failed to synchronize user information
QNScaleEventUpdateIdentifyWeightSuccess Update user's identified weight successfully
QNScaleEventUpdateIdentifyWeightFail Failed to update user's identified weight
2.5.3 onGetBleVer:bleVer:
Description:Device firmware version information callback
Parameters:
device: device object
bleVer: Firmware Version Number
2.5.4 onGetUnsteadyWeight:weight:
Description:Device measurement real-time weight callback
Parameters:
device:device
weight: current real-time body weight, unit kg
2.5.5 onGetScaleData:data:
Description:Callback for the current Bluetooth connection measurement results
Parameters:
device:device
scaleData: Current measurement data
2.5.6 onGetStoredScale:data:
Description:Callback for the known stored data and unknown measured data of the currently accessed user of the device; the stored data of users in non-currently accessed slots will not be called back
Parameters:
device:device
storedDataList: Stores user
weight: measure body weight, unit kg
measureTime: Measurement Time
mac: Device MAC address
isDataComplete: Whether it is known data, true for known, false for unknown
hmac: Measurement data hmac