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 NameTypeDescription
apiKeyStringEnter the value obtained from the Generate API key
baseUrlURL?Enter the proxy server address. If nil, default base url is used.
callbackUrlURL?Enter the URL of the server to receive sleep session analysis results.
serviceString?Enter the app name
productInfoAsleep.ProductInfo?Device (Product) information. If you pass it, the device is registered during setup. See Product Registration below
delegateAsleepSetupDelegate?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 NameTypeDescription
appIdStringApp ID issued from the dashboard
appSecretStringApp Secret issued from the dashboard
isTestEnvironmentBool?Set to true only when using the test environment
baseUrlURL?Uses the default server when nil
callbackUrlURL?Server URL to receive the sleep session analysis result
serviceString?Application name
productInfoAsleep.ProductInfo?Device (Product) information. See Product Registration below
delegateAsleepSetupDelegate?Delegate that receives the setup result

Differences from the API Key method

ItemAPI KeyToken
Authentication headerx-api-keyAuthorization: Bearer
Token refreshNoneRefreshed automatically by the SDK (5 minutes before expiry)
Authentication failure (401)Error deliveredReissued automatically and retried
  • setupDidFail is called immediately when appId or appSecret is 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 AsleepError cases below.
AsleepErrorDescription
tokenIssueFailedFailed to issue the token
tokenRefreshFailedFailed to refresh the token
tokenInvalidCredentialsInvalid appId or appSecret
tokenNetworkErrorNetwork error during a token request

AsleepSetupDelegate

protocol AsleepSetupDelegate {
    func setupDidComplete()
    func setupDidFail(error: Asleep.AsleepError)
    func setupInProgress(progress: Int)
}
  1. setupDidComplete()
    Called when setup has finished. If you passed productInfo, it is called only after the device registration has also finished.

  2. setupDidFail()
    Called when setup has failed. In this case setupDidComplete() is not called.

    Property NameTypeDescription
    errorAsleep.AsleepErrorError Codes
  3. setupInProgress()
    It is not called during the Product registration process. You can leave it as an empty implementation.

Call rules

SituationBehavior
Calling setup again while setup is in progressIt is ignored (no callback). Call it after you receive setupDidComplete / setupDidFail. Calling it inside the callback is fine
Calling setup during sleep trackingIt is ignored (no callback). Call it after you stop tracking
apiKey is an empty stringsetupDidFail (unknown) immediately
Omitting apiKey and the others in initAsleepConfig after setupThe 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 productInfo to setup and 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 setup without productInfo, 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 NameTypeDescription
modelStringProduct model name (1~100 characters)
identifierTypeProductIdentifierTypeThe kind of value that identifies the device. .serial (serial number) or .macAddress (MAC address)
identifierValueStringSerial number or MAC address (1~255 characters)
🚧

Please make sure of the following

  • Use a value for identifierValue that 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)
SituationBehavior
First launchRegisters 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 changedDeletes the existing registration information and registers again with the new API Key
Reinstalled after the app was deletedThe 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.
  • setup is ignored during sleep tracking. If the connected device has changed, call setup with the new productInfo after 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.

AsleepErrorMeaningWhat the app should do
productRegisterFailedA temporary failure. Network error, server error (5xx), or too many requests (429). This is the result after the SDK has already retriedGuide the user about the network status and call setup again later
productRegisterRejectedRejected. Invalid input, authentication failure, or no permission to register. Retrying gives the same resultCheck productInfo and the API Key
unknownapiKey is an empty stringCheck 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) { }
}

Did this page help you?