Virtual Fitness (Video On-Demand)
Virtual Fitness connects members to third-party video content providers -- currently NEOU and Lifetime Digital. Members can browse on-demand workout classes through partner platforms. The SDK handles registration, sign-up URL generation, and profile disconnection.
How It Works
- Check registration -- Determine if the member is already linked to a provider.
- Get sign-up details -- Retrieve the partner's sign-up URL, redirect URL, and promo code.
- Register -- Create the member's profile with the provider.
- Watch content -- Load the provider's content in a WebView or redirect to their app.
- Disconnect -- Unlink the member's profile when they no longer want the service.
Data Model
VirtualFitnessSignUpDetails
Returned by getNEOUSignUpDetails() and getLifetimeSignUpDetails().
| Field | Type | Description |
|---|---|---|
signUpUrl | String? | URL of the partner's sign-up page. |
redirectUrl | String? | URL to return to after sign-up completes. |
promoCode | String? | Promotional code applied during registration. |
NEOU
Check Registration
- Android (Kotlin)
- iOS (Swift)
// Android
val registered = AFCore.virtualFitness().isMemberRegisteredToNeou()
// iOS
let registered = try await AFCore.shared.virtualFitness().isMemberRegisteredToNeou()
Get Sign-Up Details
Retrieve the NEOU sign-up URL and promo code. Use this to present the sign-up page in a WebView.
- Android (Kotlin)
- iOS (Swift)
// Android
val details = AFCore.virtualFitness().getNEOUSignUpDetails()
webView.loadUrl(details.signUpUrl ?: "")
// iOS
let details = try await AFCore.shared.virtualFitness().getNEOUSignUpDetails()
if let urlString = details.signUpUrl, let url = URL(string: urlString) {
webView.load(URLRequest(url: url))
}
Register
- Android (Kotlin)
- iOS (Swift)
// Android
val success = AFCore.virtualFitness().registerNEOUProfile()
// iOS
let success = try await AFCore.shared.virtualFitness().registerNEOUProfile()
Disconnect
- Android (Kotlin)
- iOS (Swift)
// Android
val disconnected = AFCore.virtualFitness().disconnectNEOUProfile()
// iOS
let disconnected = try await AFCore.shared.virtualFitness().disconnectNEOUProfile()
Lifetime Digital
Check Registration
- Android (Kotlin)
- iOS (Swift)
// Android
val registered = AFCore.virtualFitness().isMemberRegisteredToLifetimeDigital()
// iOS
let registered = try await AFCore.shared.virtualFitness().isMemberRegisteredToLifetimeDigital()
Get Sign-Up Details
- Android (Kotlin)
- iOS (Swift)
// Android
val details = AFCore.virtualFitness().getLifetimeSignUpDetails()
webView.loadUrl(details.signUpUrl ?: "")
// iOS
let details = try await AFCore.shared.virtualFitness().getLifetimeSignUpDetails()
if let urlString = details.signUpUrl, let url = URL(string: urlString) {
webView.load(URLRequest(url: url))
}
Register
- Android (Kotlin)
- iOS (Swift)
// Android
val success = AFCore.virtualFitness().registerLifetimeDigitalProfile()
// iOS
let success = try await AFCore.shared.virtualFitness().registerLifetimeDigitalProfile()
Disconnect
- Android (Kotlin)
- iOS (Swift)
// Android
val disconnected = AFCore.virtualFitness().disconnectLifetimeDigitalProfile()
// iOS
let disconnected = try await AFCore.shared.virtualFitness().disconnectLifetimeDigitalProfile()
Integration Example
A typical flow checks registration first, then either shows content or presents the sign-up page.
- Android (Kotlin)
- iOS (Swift)
lifecycleScope.launch {
try {
if (AFCore.virtualFitness().isMemberRegisteredToNeou()) {
// Member is registered -- show NEOU content
navigateToNEOUContent()
} else {
// Not registered -- show sign-up page
val details = AFCore.virtualFitness().getNEOUSignUpDetails()
val registered = AFCore.virtualFitness().registerNEOUProfile()
if (registered) {
webView.loadUrl(details.signUpUrl ?: "")
} else {
showError("Could not register with NEOU")
}
}
} catch (e: Exception) {
showError("Virtual Fitness unavailable: ${e.message}")
}
}
do {
if try await AFCore.shared.virtualFitness().isMemberRegisteredToNeou() {
navigateToNEOUContent()
} else {
let details = try await AFCore.shared.virtualFitness().getNEOUSignUpDetails()
let registered = try await AFCore.shared.virtualFitness().registerNEOUProfile()
if registered, let urlString = details.signUpUrl, let url = URL(string: urlString) {
webView.load(URLRequest(url: url))
} else {
showError("Could not register with NEOU")
}
}
} catch {
showError("Virtual Fitness unavailable: \(error)")
}
Best Practices
- Open partner content in a WebView. Keep the experience within your app rather than opening an external browser.
- Explain the partner relationship. Let members know that Virtual Fitness content is provided by a third party and may require a separate account.
- Handle partner downtime gracefully. If registration or sign-up details fail, show a clear message and offer a retry option.
- Confirm before disconnecting. Show a dialog explaining that disconnecting removes access to the partner's content.
Quick Reference
- Android (Kotlin)
- iOS (Swift)
// Android -- NEOU
AFCore.virtualFitness().isMemberRegisteredToNeou()
AFCore.virtualFitness().getNEOUSignUpDetails()
AFCore.virtualFitness().registerNEOUProfile()
AFCore.virtualFitness().disconnectNEOUProfile()
// Android -- Lifetime Digital
AFCore.virtualFitness().isMemberRegisteredToLifetimeDigital()
AFCore.virtualFitness().getLifetimeSignUpDetails()
AFCore.virtualFitness().registerLifetimeDigitalProfile()
AFCore.virtualFitness().disconnectLifetimeDigitalProfile()
// iOS -- NEOU
try await AFCore.shared.virtualFitness().isMemberRegisteredToNeou()
try await AFCore.shared.virtualFitness().getNEOUSignUpDetails()
try await AFCore.shared.virtualFitness().registerNEOUProfile()
try await AFCore.shared.virtualFitness().disconnectNEOUProfile()
// iOS -- Lifetime Digital
try await AFCore.shared.virtualFitness().isMemberRegisteredToLifetimeDigital()
try await AFCore.shared.virtualFitness().getLifetimeSignUpDetails()
try await AFCore.shared.virtualFitness().registerLifetimeDigitalProfile()
try await AFCore.shared.virtualFitness().disconnectLifetimeDigitalProfile()