Getting Started with Zync SDK

📦 Check the latest releases for the most recent version.

Table of contents

  1. Prerequisites
  2. Installation
    1. Android
    2. iOS
      1. CocoaPods
      2. Swift Package Manager
  3. Basic Setup
    1. Initialize the SDK
    2. Session Management
    3. Viewing Logs
    4. Accessing SDK Features
    5. Dependency Injection
  4. Key Concepts
    1. Offline-First Architecture
    2. Automatic Synchronization
    3. Data Persistence
  5. Next Steps

Welcome to the Zync SDK! This guide will help you quickly integrate our offline-first synchronization SDK into your mobile application.

Prerequisites

  • Android: minSdk 24 or higher
  • iOS: iOS 13.0 or higher
  • Kotlin 2.0.21 or higher

Installation

Android

Add the Zync SDK dependency to your module’s build.gradle.kts:

dependencies {
    implementation("co.zuper.mobile:zync-android:VERSION")
}

iOS

CocoaPods

Add to your Podfile:

pod 'Zync', '~> VERSION'

Swift Package Manager

Add the package dependencies:

dependencies: [
    .package(url: "https://github.com/ZuperInc/zync-sdk.git", from: "VERSION"),
    // Required for async/await support with Kotlin coroutines
    .package(url: "https://github.com/rickclephas/KMP-NativeCoroutines.git", from: "1.0.0-ALPHA-31")
]

⚠️ Important for iOS: Do NOT import the offline-engine library separately in your iOS project. Zync SDK includes all necessary offline-engine components and will provide them to your app automatically. Adding offline-engine as a separate dependency will cause namespace collisions.

Note: The Zync SDK uses Kotlin coroutines internally. To use the SDK with Swift’s async/await or Combine, you’ll need to add KMP-NativeCoroutines as a dependency. Choose either:

  • Swift Concurrency: For async/await support (recommended)
  • Combine: For reactive programming with Combine framework

Basic Setup

Initialize the SDK

import zync.Zync
import co.zuper.mobile.shared.offline.engine.OfflineEngineConfig
import co.zuper.mobile.shared.offline.engine.OfflineEngineFileSystem
import co.zuper.mobile.shared.offline.utils.AppInfoProvider
import co.zuper.mobile.shared.offline.utils.InternetConnectivityValidator

// Create required platform implementations
val fileSystem = OfflineEngineFileSystem(/* platform-specific file system */)
val connectivityValidator = InternetConnectivityValidator(/* platform-specific validator */)
val appInfoProvider = AppInfoProvider(/* app version, build info */)

// Initialize Zync with OfflineEngine integration
val zync = Zync.initialize(
    enableLogging = true,
    fileSystem = fileSystem,
    internetConnectivityValidator = connectivityValidator,
    appInfoProvider = appInfoProvider,
    enableRemoteLogging = false,
    offlineEngineConfig = OfflineEngineConfig()
)

// SDK initialized successfully with OfflineEngine integration
import Zync
// OfflineEngine types are available through Zync - no separate import needed

// Initialize Zync with OfflineEngine integration  
let zync = Zync.shared.initialize(
    enableLogging: true,
    fileSystem: OfflineEngineFileSystem(),
    internetConnectivityValidator: OfflineInternetConnectivityValidator(),
    appInfoProvider: AppInfoProvider.init(),
    enableRemoteLogging: true,
    offlineEngineConfig: OfflineEngineConfig.init(
        logLevel: .none, 
        baseUrl: UserDefaults.appUrl + "/api/", 
        isDebugMode: false
    ),
    httpClientConfig: DefaultHttpClientConfiguration(interceptors: []),
    logWriterProvider: OfflineLogWriteProvider()
)

// SDK initialized successfully with OfflineEngine integration

Session Management

// Set user session after authentication
zync.setSession(
    accessToken = "your-access-token",
    userUid = "user-12345",
    companyUid = "company-67890",
    region = "us"
)

// Check if session is valid
if (zync.hasValidSession()) {
    // Session is valid, can use SDK features
}

// Handle session expiry (preserves user data)
zync.sessionExpired()

// ⚠️ Logout and purge all data (permanent deletion)
zync.logout()
// Set user session after authentication
zync.setSession(
    accessToken: "your-access-token",
    userUid: "user-12345",
    companyUid: "company-67890",
    region: "us"
)

// Check if session is valid
if zync.hasValidSession() {
    // Session is valid, can use SDK features
}

// Handle session expiry (preserves user data)
zync.sessionExpired()

// ⚠️ Logout and purge all data (permanent deletion)
zync.logout()

Viewing Logs

The SDK uses Kermit for logging with the tag prefix “Zync:”. To view logs:

Android (Logcat):

adb logcat -s "Zync:*"

iOS (Console): Look for logs with “Zync:” prefix in Xcode console or device logs.

Accessing SDK Features

// Access available managers
val attachmentManager = zync.attachments
val userManager = zync.users
val companyManager = zync.companies
val jobManager = zync.jobs

if (attachmentManager != null) {
    // Use attachment operations
}
// Access available managers
if let attachmentManager = zync.attachments,
   let userManager = zync.users,
   let companyManager = zync.companies,
   let jobManager = zync.jobs {
    // Use SDK operations
}

Dependency Injection

For production apps, use dependency injection to manage the Zync SDK instance:

// Module providing Zync instance
@Module
@InstallIn(SingletonComponent::class)
object ZyncModule {

    @Provides
    @Singleton
    fun provideZync(
        fileSystem: OfflineEngineFileSystem,
        connectivityValidator: InternetConnectivityValidator,
        appInfoProvider: AppInfoProvider
    ): Zync {
        return Zync.initialize(
            enableLogging = BuildConfig.DEBUG,
            fileSystem = fileSystem,
            internetConnectivityValidator = connectivityValidator,
            appInfoProvider = appInfoProvider
        )
    }
}

// Inject in your classes
@AndroidEntryPoint
class JobRepository @Inject constructor(
    private val zync: Zync
) {

    fun getAttachments() = zync.attachments
    fun getUserManager() = zync.users
    fun getCompanyManager() = zync.companies
    fun getJobManager() = zync.jobs
}
// Register Zync with Resolver
extension Resolver {
    static func registerZyncServices() {
        register { () -> Zync in
            return Zync.shared.initialize(
                enableLogging: true,
                fileSystem: OfflineEngineFileSystem(),
                internetConnectivityValidator: OfflineInternetConnectivityValidator(),
                appInfoProvider: AppInfoProvider.init(),
                enableRemoteLogging: true,
                offlineEngineConfig: OfflineEngineConfig.init(
                    logLevel: .none,
                    baseUrl: UserDefaults.appUrl + "/api/",
                    isDebugMode: false
                ),
                httpClientConfig: DefaultHttpClientConfiguration(interceptors: []),
                logWriterProvider: OfflineLogWriteProvider()
            )
        }.scope(.shared)
    }
}

// Usage in your classes
class JobRepository {
    @Injected private var zync: Zync

    func getAttachments() -> ZyncAttachmentManager? {
        return zync.attachments
    }

    func getUserManager() -> ZyncUserManager? {
        return zync.users
    }

    func getCompanyManager() -> ZyncCompanyManager? {
        return zync.companies
    }

    func getJobManager() -> ZyncJobManager? {
        return zync.jobs
    }
}

// Call during app initialization
Resolver.registerZyncServices()

Key Concepts

Offline-First Architecture

The SDK follows an offline-first approach:

  • Local database is the primary source of truth
  • Data is fetched from local storage first
  • Background sync updates local data
  • Changes are queued and uploaded when online

Automatic Synchronization

The SDK handles synchronization automatically:

  • Initial prefetch on first launch
  • Delta sync for incremental updates
  • Real-time updates via WebSocket
  • Smart conflict resolution [TBD]

Data Persistence

All data is securely stored locally:

  • SQLCipher encryption for security
  • Automatic cache management

Next Steps

Continue with these detailed guides:


Copyright © 2025 Zuper Inc. All rights reserved. This software is proprietary and confidential.