Fit@Home
Fit@Home allows members to submit selfies as proof of at-home workouts. The host app captures a camera preview screenshot, converts it to bytes, and sends it through the SDK for server-side analysis.
UI Reference
Present a camera viewfinder with a face guide overlay and a capture button. After capture, show a preview and upload the image via submitSelfie().
Design guidelines:
- Use a circular or oval guide overlay to help the member position their face.
- Keep the capture button large and centered (minimum 64pt / 48dp touch target).
- Show the camera grid as a subtle background element, not a prominent overlay.
- Display a preview of the captured image before uploading so the member can retake.
- Do not add filters, watermarks, or overlays -- the server strips them during processing.
How It Works
- Capture -- The host app presents a camera preview and takes a screenshot. Use a lightweight screen capture rather than a full-resolution photo to minimize upload time.
- Submit -- Pass the image bytes, a UTC timestamp, and optional location coordinates to
submitSelfie(). - Verify -- The server processes the image and records the activity. Results appear in the member's Activities history.
The SDK transmits the image but does not provide camera UI. Your app is responsible for the camera preview and capture logic. Third-party camera libraries can simplify this.
Avoid overlays or watermarks on the image. Additional data increases upload time and is stripped during processing.
Permissions
Camera permission is required to capture the selfie.
- Android (Kotlin)
- iOS (Swift)
AFPermissions.requestPermission(Permission.CAMERA)
try await AFPermissions.shared.requestPermission(permission: .camera)
Submit a Selfie
Upload a selfie for Fit@Home check-in validation. The submission includes the raw image bytes, a UTC epoch timestamp, and optional latitude/longitude coordinates.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
media | ByteArray | Yes | Raw image bytes from the camera capture. |
timestampInSeconds | Long | Yes | UTC epoch timestamp of the workout. |
lat | Double? | No | Device latitude at time of capture. |
lng | Double? | No | Device longitude at time of capture. |
- Android (Kotlin)
- iOS (Swift)
lifecycleScope.launch {
val selfieBytes = capturePreviewSnapshot() // ByteArray from camera
val timestamp = Clock.System.now().epochSeconds
val result = withContext(Dispatchers.IO) {
AFCore.fitAtHome().submitSelfie(
media = selfieBytes,
timestampInSeconds = timestamp,
lat = location?.latitude,
lng = location?.longitude
)
}
if (result.status) {
showSuccess("Workout submitted")
refreshActivities()
} else {
showError("Could not submit selfie: ${result.statusMessage}")
}
}
let snapshotData = capturePreviewSnapshot() // Data from camera
let timestamp = Int64(Date().timeIntervalSince1970)
let result = try await AFCore.shared.fitAtHome().submitSelfie(
media: snapshotData,
timestampInSeconds: timestamp,
lat: location?.coordinate.latitude,
lng: location?.coordinate.longitude
)
if result.status {
showSuccess("Workout submitted")
refreshActivities()
} else {
showError("Could not submit selfie: \(result.statusMessage ?? "Unknown error")")
}
Delete a Selfie
Remove a previously submitted selfie for a given date. The date must be formatted as YYYY-MM-DD in UTC.
- Android (Kotlin)
- iOS (Swift)
lifecycleScope.launch {
val result = withContext(Dispatchers.IO) {
AFCore.fitAtHome().deleteSelfie(date = "2026-02-13")
}
if (result.status) {
showSuccess("Selfie deleted")
refreshActivities()
} else {
showError("Could not delete selfie: ${result.statusMessage}")
}
}
let result = try await AFCore.shared.fitAtHome().deleteSelfie(date: "2026-02-13")
if result.status {
showSuccess("Selfie deleted")
refreshActivities()
} else {
showError("Could not delete selfie: \(result.statusMessage ?? "Unknown error")")
}
Best Practices
- Use a camera preview overlay with a capture button. Show a thumbnail of the captured image before uploading so the member can retake if needed.
- Keep images small. A screen capture from the camera preview is sufficient. Full-resolution photos increase upload time without improving validation.
- Confirm before deleting. Show a confirmation dialog before calling
deleteSelfiesince the action is permanent. - Show upload progress. Image uploads may take a few seconds on slower connections. Display a progress indicator to keep the member informed.
Quick Reference
- Android (Kotlin)
- iOS (Swift)
AFCore.fitAtHome().submitSelfie(media, timestampInSeconds, lat, lng)
AFCore.fitAtHome().deleteSelfie(date)
try await AFCore.shared.fitAtHome().submitSelfie(media:timestampInSeconds:lat:lng:)
try await AFCore.shared.fitAtHome().deleteSelfie(date:)