Setup
Call it after the app launches and before you start sleep tracking, and call Asleep.initAsleepConfig() after you receive setupDidComplete().
Asleep.setup(apiKey:, productInfo:, delegate:) ← passes the authentication info and the device info
└ setupDidComplete()
└ Asleep.initAsleepConfig(userId:, delegate:) ← the authentication info can be omitted (it is inherited from setup)
└ userDidJoin(userId:, config:)
└ createSleepTrackingManager → startTracking
The existing way of calling only initAsleepConfig(apiKey:) without setup still works.
To use Product registration, you have to call setup first.
Setup
Asleep.setup()
let apiKey: String = "YOUR_API_KEY"
let baseUrl: URL?
let callbackUrl: URL?
let service: String?
let productInfo: Asleep.ProductInfo?
let delegate: AsleepSetupDelegate = self
Asleep.setup(apiKey: apiKey,
baseUrl: baseUrl,
callbackUrl: callbackUrl,
service: service,
productInfo: productInfo,
delegate: delegate)| Property Name | Type | Description |
|---|---|---|
| apiKey | String | Enter the value obtained from the Generate API key |
| baseUrl | URL? | Enter the proxy server address. If nil, default base url is used. |
| callbackUrl | URL? | Enter the URL of the server to receive sleep session analysis results. |
| service | String? | Enter the app name |
| productInfo | Asleep.ProductInfo? | Device (Product) information. If you pass it, the device is registered during setup. See Product Registration below |
| delegate | AsleepSetupDelegate? | Delegate to receive the setup result |
Token authentication
Instead of an API Key you can authenticate with app credentials (appId and appSecret). Every API after setup works the same way regardless of which method you use.
Asleep.setup(appId: "YOUR_APP_ID",
appSecret: "YOUR_APP_SECRET",
productInfo: productInfo,
delegate: self)| Property Name | Type | Description |
|---|---|---|
| appId | String | App ID issued from the dashboard |
| appSecret | String | App Secret issued from the dashboard |
| isTestEnvironment | Bool? | Set to true only when using the test environment |
| baseUrl | URL? | Uses the default server when nil |
| callbackUrl | URL? | Server URL to receive the sleep session analysis result |
| service | String? | Application name |
| productInfo | Asleep.ProductInfo? | Device (Product) information. See Product Registration below |
| delegate | AsleepSetupDelegate? | Delegate that receives the setup result |
Differences from the API Key method
| Item | API Key | Token |
|---|---|---|
| Authentication header | x-api-key | Authorization: Bearer |
| Token refresh | None | Refreshed automatically by the SDK (5 minutes before expiry) |
| Authentication failure (401) | Error delivered | Reissued automatically and retried |
setupDidFailis called immediately whenappIdorappSecretis an empty string.- Both methods share the same re-entrancy guard. A Token setup is ignored while an API Key setup is in progress.
- Token failures are delivered as the
AsleepErrorcases below.
| AsleepError | Description |
|---|---|
| tokenIssueFailed | Failed to issue the token |
| tokenRefreshFailed | Failed to refresh the token |
| tokenInvalidCredentials | Invalid appId or appSecret |
| tokenNetworkError | Network error during a token request |
AsleepSetupDelegate
protocol AsleepSetupDelegate {
func setupDidComplete()
func setupDidFail(error: Asleep.AsleepError)
func setupInProgress(progress: Int)
}-
setupDidComplete()
Called when setup has finished. If you passedproductInfo, it is called only after the device registration has also finished. -
setupDidFail()
Called when setup has failed. In this casesetupDidComplete()is not called.Property Name Type Description error Asleep.AsleepError Error Codes -
setupInProgress()
It is not called during the Product registration process. You can leave it as an empty implementation.
Call rules
| Situation | Behavior |
|---|---|
Calling setup again while setup is in progress | It is ignored (no callback). Call it after you receive setupDidComplete / setupDidFail. Calling it inside the callback is fine |
Calling setup during sleep tracking | It is ignored (no callback). Call it after you stop tracking |
apiKey is an empty string | setupDidFail (unknown) immediately |
Omitting apiKey and the others in initAsleepConfig after setup | The values passed to setup are inherited. When the app is launched again, call setup first again |
Product Registration
Product registration is a feature that registers the device the SDK runs on with the Asleep server. Once registered, the server records which session was measured on which device.
- There is no separate API. Pass
productInfotosetupand the device is registered. - When the registration succeeds, the SDK stores the registration information on the device and automatically includes it in requests such as session creation and data upload. There is no value for the app to handle.
- If you call
setupwithoutproductInfo, no registration request is sent.
Asleep.ProductInfo
let productInfo = Asleep.ProductInfo(
model: "MODEL_NAME",
identifierType: .serial,
identifierValue: "SERIAL_NUMBER"
)public struct ProductInfo: Equatable {
public let model: String
public let identifierType: ProductIdentifierType
public let identifierValue: String
}
public enum ProductIdentifierType: String {
case serial
case macAddress
}| Property Name | Type | Description |
|---|---|---|
| model | String | Product model name (1~100 characters) |
| identifierType | ProductIdentifierType | The kind of value that identifies the device. .serial (serial number) or .macAddress (MAC address) |
| identifierValue | String | Serial number or MAC address (1~255 characters) |
Please make sure of the following
- Use a value for
identifierValuethat is unique per device and does not change.- Always pass it in the same format. The SDK does not convert letter case, separators (
:/-) or leading and trailing spaces, and if the string differs even slightly it treats it as a different device and sends a new registration request.- An empty value, a value with only spaces, or a value that exceeds the length fails with
setupDidFail(productRegisterRejected)without a server request.
How it works
If you pass productInfo, the device registration becomes a step of setup, and setupDidComplete() is called only after the registration has finished.
Asleep.setup(apiKey:, productInfo:, delegate:)
│
├ ① Check the stored registration information
│ Already registered with the same API Key and the same productInfo → completes immediately without a registration request
│
├ ② Check the input values
│ model / identifierValue violates the conditions → setupDidFail (productRegisterRejected)
│
├ ③ Send the registration request to the server
│ Network error or server error → retries up to 3 times, after 2, 4 and 8 seconds
│
└ ④ Success → setupDidComplete()
Failure → setupDidFail (productRegisterFailed or productRegisterRejected)
| Situation | Behavior |
|---|---|
| First launch | Registers with the server and stores the registration information |
From the next launch (same API Key, same productInfo) | Completes immediately without a registration request |
productInfo has changed (e.g. the connected device changed) | Registers again with the new productInfo. On success, sessions created from then on are recorded with the new device |
| The API Key has changed | Deletes the existing registration information and registers again with the new API Key |
| Reinstalled after the app was deleted | The stored registration information is deleted as well, so it registers again at the next setup |
Call setup with the same productInfo every time the app launches. From the second launch it completes immediately without a registration request.
Time taken
- A device that is already registered: completes immediately without a registration request.
- First registration: it usually finishes with a single request.
- When the server does not respond and every retry is spent:
setupDidFail(productRegisterFailed)is called after about 75 seconds with the API Key method, and later than that with the Token method, which sends two requests per attempt.
We recommend showing a loading screen while you wait for setupDidComplete().
When to start tracking
Which device a session was measured on is determined when the session is created (startTracking).
- Always start tracking after you receive
setupDidComplete(). - Do not start tracking if you received
setupDidFail. Even when the registration fails, the previously stored registration information remains, so if you track anyway the session can be recorded with the previous device. setupis ignored during sleep tracking. If the connected device has changed, callsetupwith the newproductInfoafter you stop tracking.
Stored information
- The registration information is stored in an SDK-only area of the app's
UserDefaults. - The serial number and the MAC address themselves are not stored. Only a hash used to check whether the value has changed is stored.
Error codes
A registration failure is delivered through setupDidFail(error:), and it is divided into two cases that the app has to handle differently.
| AsleepError | Meaning | What the app should do |
|---|---|---|
productRegisterFailed | A temporary failure. Network error, server error (5xx), or too many requests (429). This is the result after the SDK has already retried | Guide the user about the network status and call setup again later |
productRegisterRejected | Rejected. Invalid input, authentication failure, or no permission to register. Retrying gives the same result | Check productInfo and the API Key |
unknown | apiKey is an empty string | Check the API Key |
The message of an error is for checking the cause (logging) and its wording can change.Branch your app logic on the error case (productRegisterFailed / productRegisterRejected).
Example
import AsleepSDK
final class SleepSDKController: AsleepSetupDelegate, AsleepConfigDelegate {
private let apiKey: String = "YOUR_API_KEY"
private let userId: String? = nil
private var config: Asleep.Config?
func start() {
let productInfo = Asleep.ProductInfo(
model: "MODEL_NAME",
identifierType: .serial,
identifierValue: "SERIAL_NUMBER"
)
Asleep.setup(apiKey: apiKey,
productInfo: productInfo,
delegate: self)
}
// MARK: - AsleepSetupDelegate
func setupDidComplete() {
// Called only after the device registration has finished.
Asleep.initAsleepConfig(userId: userId, delegate: self)
}
func setupDidFail(error: Asleep.AsleepError) {
switch error {
case .productRegisterFailed:
// A temporary failure — check the network and call setup again later
break
case .productRegisterRejected:
// Rejected — check productInfo / API Key (retrying gives the same result)
break
default:
break
}
}
func setupInProgress(progress: Int) { }
// MARK: - AsleepConfigDelegate
func userDidJoin(userId: String, config: Asleep.Config) {
self.config = config // Now you can start tracking.
}
func didFailUserJoin(error: Asleep.AsleepError) { }
func userDidDelete(userId: String) { }
}Updated about 3 hours ago
