Travvir capture SDK
Our SDK enables 3D scanning and capture functionality in your mobile applications. It supports both Android and iOS, with a unified API to create immersive 3D experiences.
Platform Support
- Android: API 26+ (Android 8.0)
- iOS: iOS 16.0+
Request Access
Fill out the form below to request SDK access & credentials.
Android SDK
Requirements
Android Versions
- Minimum SDK:
- Target SDK:
- Compile SDK:
Permissions
- Camera:
- Storage: : Android 10 and below
- Notifications: : Android 13+
Hardware
- Camera:
- Accelerometer sensor:
- Gyroscope sensor:
Installation
1) Add Repository
Add the Travvir SDK repository to your project's build.gradle.kts
(Project level):
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
mavenLocal() // Add this for local SDK
}
}
2) Extract SDK to Local Maven Repository
Extract the provided SDK zip file to your local Maven repository:
# Create the .m2 directory if it doesn't exist
mkdir -p $HOME/.m2/repository
# Extract the SDK zip file to the local Maven repository
# Replace 'travvir-sdk.zip' with the actual name of your SDK zip file
unzip travvir-sdk.zip -d $HOME/.m2/repository/
3) Add Dependency
Add the SDK dependency to your app's build.gradle.kts
(Module level):
dependencies {
implementation("com.travvir:sdk:0.1")
// Required dependencies
implementation("androidx.core:core-ktx:1.15.0")
implementation("androidx.appcompat:appcompat:1.7.1")
implementation("androidx.activity:activity-ktx:1.10.1")
}
4) Update AndroidManifest.xml
Add the required permissions and features:
<!-- Required permissions -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- Storage permission for Android 10 and below -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
<!-- Required hardware features -->
<uses-feature
android:name="android.hardware.sensor.accelerometer"
android:required="true" />
<uses-feature
android:name="android.hardware.sensor.gyroscope"
android:required="true" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<!-- Optional hardware features -->
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
Quick Start
1) Initialize Session
import com.travvir.sdk.api.ApiClient
import com.travvir.sdk.api.SessionCreationResult
import com.travvir.sdk.activity.Camera3DActivity
class MainActivity : AppCompatActivity() {
private val sdkKey = "your-sdk-key-here" // Replace with your actual SDK key
private fun startScanning() {
ApiClient.generateSessionId(sdkKey = sdkKey) { result ->
when (result) {
is SessionCreationResult.Success -> launchCamera(result.sessionId)
is SessionCreationResult.Error -> handleError(result.error)
}
}
}
private fun launchCamera(sessionId: String) {
val intent = Intent(this, Camera3DActivity::class.java).apply {
putExtra("sessionId", sessionId)
putExtra("sdkKey", sdkKey)
}
startActivity(intent)
}
}
2) Handle Permissions
private val requiredPermissions = mutableListOf<String>().apply {
add(Manifest.permission.CAMERA)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
add(Manifest.permission.POST_NOTIFICATIONS)
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
}
private val permissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
val deniedPermissions = permissions.filterValues { !it }.keys
if (deniedPermissions.isEmpty()) startScanning() else handlePermissionsDenied(deniedPermissions)
}
API References
Client SDK
ApiClient.generateSessionId(
sdkKey: String,// Your SDK key
sceneName: String? = null,// Optional scene name
metadata: Map<String, String>? = null, // Optional metadata
callback: (SessionCreationResult) -> Unit // Result callback
)
Response Types
sealed class SessionCreationResult {
data class Success(val sessionId: String) : SessionCreationResult()
data class Error(val error: String) : SessionCreationResult()
}
Camera
val intent = Intent(context, Camera3DActivity::class.java).apply {
putExtra("sessionId", sessionId)
putExtra("sdkKey", sdkKey)
}
startActivity(intent)
Upload Management
// Start upload service manually (usually automatic)
Utility.startUploadService(this, sdkKey)
// Stop upload service to conserve battery/bandwidth
Utility.stopUploadService(this)
// Check upload progress
Utility.getUploadProgress(context, sessionId) { progress ->
// -1 = no files, 0..100 = progress
}
iOS SDK
Requirements
Environment
- Minimum iOS Version: iOS 16.0+
- Xcode: 15.0+
- Swift: 5.9+
Permissions
- Camera access
Installation
1) Add Framework to Project
- Extract the provided
TravvirSDK.framework.zip
file - Drag and drop
TravvirSDK.framework
into your Xcode project - Select Copy files to destination (or Move files to destination)
- Ensure your app target is selected under Targets
2) Configure Framework Settings
Project ➜ Target ➜ General ➜ Frameworks, Libraries, and Embedded Content:
- Find
TravvirSDK.framework
- Set embed option to Embed & Sign
3) Update Info.plist
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to perform 3D scanning</string>
4) Import Framework
import TravvirSDK
Quick Start
1) Initialize Session
import SwiftUI
import TravvirSDK
import AVFoundation
struct ContentView: View {
@State private var sessionId: String?
@State private var showingCamera = false
@State private var cameraPermissionGranted = false
private let sdkKey = "your-sdk-key-here" // Replace with your actual SDK key
var body: some View {
VStack {
if cameraPermissionGranted {
Button("Start 3D Scanning") { generateSession() }
.padding().background(Color.blue).foregroundColor(.white).cornerRadius(10)
} else {
Button("Grant Camera Permission") { requestCameraPermission() }
.padding().background(Color.orange).foregroundColor(.white).cornerRadius(10)
}
}
.fullScreenCover(isPresented: $showingCamera) {
if let sessionId = sessionId {
Camera3DView(sessionId: sessionId, sdkKey: sdkKey)
}
}
.onAppear { checkCameraPermission() }
}
private func generateSession() {
ApiClient.generateSessionId(
sdkKey: sdkKey,
sceneName: "My 3D Scan",
metadata: ["app_version": "1.0.0"]
) { error, sessionId in
if let sessionId = sessionId { self.sessionId = sessionId; self.showingCamera = true }
}
}
}
2) Handle Camera Permissions
private func checkCameraPermission() {
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized: cameraPermissionGranted = true
case .notDetermined: requestCameraPermission()
default: cameraPermissionGranted = false
}
}
private func requestCameraPermission() {
AVCaptureDevice.requestAccess(for: .video) { granted in
DispatchQueue.main.async { cameraPermissionGranted = granted }
}
}
API References
Client SDK
ApiClient.generateSessionId(
sdkKey: String, // Your SDK key
sceneName: String? = nil, // Optional scene name
metadata: [String: String]? = nil, // Optional metadata
completion: @escaping SessionCreationCompletion // Result callback
)
Response Types
public typealias SessionCreationCompletion = (ApiError?, String?) -> Void
public enum ApiError: Error {
case message(Int, String)
}
Camera
Camera3DView(sessionId: sessionId, sdkKey: sdkKey)
Upload Management
// Start upload manager (usually automatic)
UploadManager.sharedInstance.start(sdkKey: sdkKey)
// Stop upload manager
UploadManager.sharedInstance.stop()
// Check upload progress
UploadManager.sharedInstance.getUploadProgress(sessionId: sessionId) { progress in
// -1 = no files, 0..100 = progress, 100 = complete
}
Server-side API
Get Session Status
GEThttps://travvir.com/api/v3/sdk/{sessionId}
Retrieve the status, progress, and download URL for a capture session.
Headers
Authorization: Bearer {sdk-server-key}
Response
{
"status": 1,
"data": {
"sessionId": "kPKAOfh52g",
"metadata": {
"room_type": "cabin_area",
"property_id": "1231780"
},
"sceneName": "Cabin Area",
"status": "completed",
"progress": 100,
"downloadUrl": "https://example.com/download-url"
},
"message": "OK"
}
{
"status": 0,
"message": "Job not found"
}
Session Status Values
Status | Description | Progress Value |
---|---|---|
"created" | Session initialized, capture not started | 0 |
"captured" | 3D scanning complete, ready for upload | 0 |
"uploading" | Files being uploaded to server | 0-100 (calculated) |
"uploaded" | Upload complete, queued for processing | 0 |
"processing" | Server processing the scan data | 0-100 (calculated) |
"completed" | Processing finished, result ready | 100 |
"failed" | Error occurred at any stage | 0 |
Best Practices
Session Management
- Always create a new session for each scan
- Use descriptive scene names and include relevant metadata
Permission Handling
- Request permissions before launching camera
- Handle permission denials gracefully with guidance