TSUserInfo
The TSUserInfo module retrieves, sets, and observes user demographic data such as height, weight, gender, and age. It provides transport-safety validation and an independent BMI calculation helper.
Prerequisites
- iOS 11.0 or later
- TopStepInterfaceKit framework properly imported
- Active connection to a compatible TopStep device
- User must have appropriate permissions to access and modify user information on the device
Data Models
TSUserInfoModel
Shared SDK model for user profile data. validate checks transport structure, and the active provider validates its setting range before transmission.
| Property | Type | Description |
|---|---|---|
userId | NSString * | Application-side identifier; current device profile payloads do not transmit it |
name | NSString * | Application-side display name; current device profile payloads do not transmit it |
gender | TSUserGender | Reads may return Unknown; setting only accepts Female or Male |
age | UInt8 | Whole years; Fit/NPK/Fw accept 0-127, while other providers use their own limits |
height | CGFloat | Centimeters; must be finite and nonnegative, with 0-256 used by Fit/NPK/Fw |
weight | CGFloat | Kilograms; must be finite and nonnegative, with 0-512 used by Fit/NPK/Fw |
Enumerations
TSUserGender
Enumeration defining possible gender values for user information.
| Value | Numeric Value | Description |
|---|---|---|
TSUserGenderUnknown | -1 | Gender not specified |
TSUserGenderFemale | 0 | Female gender |
TSUserGenderMale | 1 | Male gender |
Callback Types
TSUserInfoResultBlock
Callback block type for user information retrieval operations.
typedef void(^TSUserInfoResultBlock)(TSUserInfoModel * _Nullable userInfo, NSError * _Nullable error);
| Parameter | Type | Description |
|---|---|---|
userInfo | TSUserInfoModel * _Nullable | User information model; nil if retrieval fails |
error | NSError * _Nullable | Error information; nil if successful |
TSCompletionBlock
Callback block type for general completion operations.
| Parameter | Type | Description |
|---|---|---|
success | BOOL | Whether the operation was successful |
error | NSError * _Nullable | Error object if operation fails; nil if successful |
API Reference
Check whether reading user information is supported
- (BOOL)isSupportGetUserInfo;
Returns whether the current device supports reading user information. This does not describe write support.
Retrieve user information from device
Fetches basic user information stored on the connected device, including height, weight, gender, and age. The operation is performed asynchronously and returns results via completion callback.
- (void)getUserInfoWithCompletion:(nullable TSUserInfoResultBlock)completion;
| Parameter | Type | Description |
|---|---|---|
completion | TSUserInfoResultBlock | Callback block returning user information or error |
Code Example:
id<TSUserInfoInterface> userInfoInterface = (id<TSUserInfoInterface>)self.userInfoService;
[userInfoInterface getUserInfoWithCompletion:^(TSUserInfoModel * _Nullable userInfo, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to get user info: %@", error.localizedDescription);
return;
}
TSLog(@"User Info Retrieved:");
TSLog(@"Name: %@", userInfo.name);
TSLog(@"Gender: %ld", (long)userInfo.gender);
TSLog(@"Age: %d", userInfo.age);
TSLog(@"Height: %.1f cm", userInfo.height);
TSLog(@"Weight: %.1f kg", userInfo.weight);
float bmi = [userInfo calculateBMI];
TSLog(@"BMI: %.2f", bmi);
}];
Set user information to device
Configures user demographic information on the connected device. The shared model validates transport-safe structure, then the active provider validates its device protocol range. Both validation and communication failures are returned through the completion callback.
- (void)setUserInfo:(TSUserInfoModel *)userInfo
completion:(TSCompletionBlock)completion;
| Parameter | Type | Description |
|---|---|---|
userInfo | TSUserInfoModel * | User information model with values to set |
completion | TSCompletionBlock | Callback block returning operation result |
Code Example:
TSUserInfoModel *userInfo = [[TSUserInfoModel alloc] init];
userInfo.name = @"John Doe";
userInfo.gender = TSUserGenderMale;
userInfo.age = 28;
userInfo.height = 180.5;
userInfo.weight = 75.0;
// Validate before sending
NSError *validationError = [userInfo validate];
if (validationError) {
TSLog(@"Validation failed: %@", validationError.localizedDescription);
return;
}
id<TSUserInfoInterface> userInfoInterface = (id<TSUserInfoInterface>)self.userInfoService;
[userInfoInterface setUserInfo:userInfo completion:^(BOOL success, NSError * _Nullable error) {
if (error) {
TSLog(@"Failed to set user info: %@", error.localizedDescription);
return;
}
if (success) {
TSLog(@"User info set successfully");
}
}];
Register for user information change notifications
Subscribes to real-time notifications when user information is modified on the device. Pass nil to unregister from receiving further notifications.
- (void)registerUserInfoDidChangedBlock:(nullable TSUserInfoResultBlock)completion;
| Parameter | Type | Description |
|---|---|---|
completion | TSUserInfoResultBlock | Callback block triggered on information change; pass nil to unregister |
Code Example:
id<TSUserInfoInterface> userInfoInterface = (id<TSUserInfoInterface>)self.userInfoService;
// Register for notifications
[userInfoInterface registerUserInfoDidChangedBlock:^(TSUserInfoModel * _Nullable userInfo, NSError * _Nullable error) {
if (error) {
TSLog(@"Error receiving user info notification: %@", error.localizedDescription);
return;
}
TSLog(@"User info changed on device:");
TSLog(@"Name: %@", userInfo.name);
TSLog(@"Height: %.1f cm", userInfo.height);
TSLog(@"Weight: %.1f kg", userInfo.weight);
}];
// Later, to unregister
[userInfoInterface registerUserInfoDidChangedBlock:nil];
Validate user information
Validates transport-safe structure only. Gender must map to the protocol, and height and weight must be finite nonnegative values. It does not apply a universal human range or BMI health policy.
- (nullable NSError *)validate;
Returns:
| Type | Description |
|---|---|
NSError * _Nullable | nil if validation succeeds; NSError object with detailed reason if validation fails |
Validate the standard device range
Fit, NPK, and Fw use one shared standard-device validator. It first performs validate, then checks age 0-127, height 0-256 cm, and weight 0-512 kg.
- (nullable NSError *)validateStandardDeviceRange;
CRP and SJWatch have different protocol limits and do not use this method.
Provider ranges used by setUserInfo:completion::
| Provider | Age | Height (cm) | Weight (kg) |
|---|---|---|---|
| Fit / NPK / Fw | 0-127 | 0-256 | 0-512 |
| CRP | 1-120 | 0-250 | 0-500 |
| SJWatch | UInt8 range | NSInteger range | NSInteger range |
Code Example:
TSUserInfoModel *userInfo = [[TSUserInfoModel alloc] init];
userInfo.age = 25;
userInfo.height = 175.0;
userInfo.weight = 70.0;
userInfo.gender = TSUserGenderMale;
NSError *validationError = [userInfo validate];
if (validationError) {
TSLog(@"Validation failed - Code: %ld, Message: %@",
(long)validationError.code,
validationError.localizedDescription);
} else {
TSLog(@"User information is valid");
}
Calculate BMI value
Computes the Body Mass Index using the standard formula: BMI = weight(kg) / height(m)². Returns -1 if height or weight values are invalid.
- (float)calculateBMI;
Returns:
| Type | Description |
|---|---|
float | Calculated BMI value; -1 if calculation fails due to invalid height or weight |
Code Example:
TSUserInfoModel *userInfo = [[TSUserInfoModel alloc] init];
userInfo.height = 170.0; // cm
userInfo.weight = 65.0; // kg
float bmi = [userInfo calculateBMI];
if (bmi < 0) {
TSLog(@"BMI calculation failed - invalid height or weight");
return;
}
TSLog(@"BMI: %.2f", bmi);
// Interpret BMI according to WHO standards
if (bmi < 16) {
TSLog(@"Severe thinness");
} else if (bmi < 17) {
TSLog(@"Moderate thinness");
} else if (bmi < 18.5) {
TSLog(@"Mild thinness");
} else if (bmi < 25) {
TSLog(@"Normal weight");
} else if (bmi < 30) {
TSLog(@"Overweight");
} else {
TSLog(@"Obese");
}
Important Notes
-
Asynchronous Operations: All API methods operate asynchronously. Always provide completion handlers and do not assume immediate results.
-
Validation Before Setting:
validatecatches transport-structure errors early. The provider can still return a device-specific range error fromsetUserInfo:completion:. -
Valid Ranges: Use the active provider's protocol range. Do not hard-code a universal 220 cm height limit in the app layer.
-
Notification Registration: Pass nil to
registerUserInfoDidChangedBlock:to unregister from change notifications and prevent memory leaks. -
BMI Calculation: The BMI calculation uses metric units (weight in kg, height in cm converted to meters). Ensure height and weight are set before calculating BMI.
-
Error Handling: Always check the error parameter in completion blocks. Different error codes may indicate device communication failures, validation errors, or permission issues.
-
Thread Safety: Completion callbacks may be executed on background threads. Update UI only on the main thread by dispatching to
dispatch_get_main_queue(). -
BMI Policy: BMI is a calculation helper only and does not determine whether SDK setting succeeds.
-
Identifier and Name Metadata:
userIdandnameare carried by the common model but are not part of current device profile setting payloads. -
Persistent Storage: User information modifications are persisted on the device and survive device reboots. Changes made via the app will be reflected in future retrievals.