Skip to main content

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.

PropertyTypeDescription
userIdNSString *Application-side identifier; current device profile payloads do not transmit it
nameNSString *Application-side display name; current device profile payloads do not transmit it
genderTSUserGenderReads may return Unknown; setting only accepts Female or Male
ageUInt8Whole years; Fit/NPK/Fw accept 0-127, while other providers use their own limits
heightCGFloatCentimeters; must be finite and nonnegative, with 0-256 used by Fit/NPK/Fw
weightCGFloatKilograms; must be finite and nonnegative, with 0-512 used by Fit/NPK/Fw

Enumerations​

TSUserGender​

Enumeration defining possible gender values for user information.

ValueNumeric ValueDescription
TSUserGenderUnknown-1Gender not specified
TSUserGenderFemale0Female gender
TSUserGenderMale1Male gender

Callback Types​

TSUserInfoResultBlock​

Callback block type for user information retrieval operations.

typedef void(^TSUserInfoResultBlock)(TSUserInfoModel * _Nullable userInfo, NSError * _Nullable error);
ParameterTypeDescription
userInfoTSUserInfoModel * _NullableUser information model; nil if retrieval fails
errorNSError * _NullableError information; nil if successful

TSCompletionBlock​

Callback block type for general completion operations.

ParameterTypeDescription
successBOOLWhether the operation was successful
errorNSError * _NullableError 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;
ParameterTypeDescription
completionTSUserInfoResultBlockCallback 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;
ParameterTypeDescription
userInfoTSUserInfoModel *User information model with values to set
completionTSCompletionBlockCallback 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;
ParameterTypeDescription
completionTSUserInfoResultBlockCallback 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:

TypeDescription
NSError * _Nullablenil 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::

ProviderAgeHeight (cm)Weight (kg)
Fit / NPK / Fw0-1270-2560-512
CRP1-1200-2500-500
SJWatchUInt8 rangeNSInteger rangeNSInteger 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:

TypeDescription
floatCalculated 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​

  1. Asynchronous Operations: All API methods operate asynchronously. Always provide completion handlers and do not assume immediate results.

  2. Validation Before Setting: validate catches transport-structure errors early. The provider can still return a device-specific range error from setUserInfo:completion:.

  3. Valid Ranges: Use the active provider's protocol range. Do not hard-code a universal 220 cm height limit in the app layer.

  4. Notification Registration: Pass nil to registerUserInfoDidChangedBlock: to unregister from change notifications and prevent memory leaks.

  5. 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.

  6. Error Handling: Always check the error parameter in completion blocks. Different error codes may indicate device communication failures, validation errors, or permission issues.

  7. Thread Safety: Completion callbacks may be executed on background threads. Update UI only on the main thread by dispatching to dispatch_get_main_queue().

  8. BMI Policy: BMI is a calculation helper only and does not determine whether SDK setting succeeds.

  9. Identifier and Name Metadata: userId and name are carried by the common model but are not part of current device profile setting payloads.

  10. 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.