Case Study: Building OnTrack Core - Enterprise Mobile App

By Harjot Singh Panesar | January 8, 2026 | 12 min read

OnTrack Core is an enterprise-grade mobile application for infrastructure inspection, maintenance management, and asset tracking. This case study explores the technical challenges, architectural decisions, and lessons learned while building this complex cross-platform solution.

50K+
Active Users
99.9%
Uptime
100K+
Inspections/Month
4.7
App Store Rating

Project Overview

OnTrack Core serves field workers in the utilities and infrastructure sectors who need to conduct inspections, track assets, and manage maintenance work orders - often in remote locations with limited or no connectivity.

Key Requirements

  • Full offline functionality with seamless sync
  • Photo and video capture with annotation
  • GPS tracking and geofencing
  • Complex form management with conditional logic
  • Integration with enterprise ERP systems
  • Cross-platform iOS and Android support
  • Enterprise security and compliance

Technology Stack

Swift Kotlin Core Data Room REST APIs MapKit Google Maps Firebase AWS

Technical Challenges

Challenge 1: Offline-First Architecture

Field workers spend hours in areas with no cell coverage. The app needed to function completely offline while ensuring data integrity when connectivity returns.

Solution: Conflict-Free Replicated Data Types (CRDT)

We implemented a CRDT-based sync engine that handles concurrent modifications gracefully:

// Simplified CRDT-based sync
struct InspectionRecord: Syncable {
    let id: UUID
    var data: InspectionData
    var vectorClock: VectorClock
    var lastModified: Date

    mutating func merge(with remote: InspectionRecord) -> InspectionRecord {
        // Compare vector clocks to determine order
        if vectorClock.happensBefore(remote.vectorClock) {
            return remote
        } else if remote.vectorClock.happensBefore(vectorClock) {
            return self
        } else {
            // Concurrent modification - merge fields
            return InspectionRecord(
                id: id,
                data: data.merge(with: remote.data),
                vectorClock: vectorClock.merge(remote.vectorClock),
                lastModified: max(lastModified, remote.lastModified)
            )
        }
    }
}

Key Learning: Traditional last-write-wins strategies lose data. CRDTs preserve all user work even when the same record is modified on multiple devices.

Challenge 2: Large Media Sync

Inspections include hundreds of photos and videos. Syncing gigabytes of media over spotty connections was problematic.

Solution: Chunked Upload with Resume

  • Split large files into 1MB chunks
  • Track upload progress per chunk
  • Resume from last successful chunk
  • Background upload with iOS background tasks
  • Compress images client-side before upload
class ChunkedUploader {
    private let chunkSize = 1024 * 1024 // 1MB

    func uploadFile(at url: URL) async throws {
        let fileHandle = try FileHandle(forReadingFrom: url)
        let fileSize = try fileHandle.seekToEnd()
        var offset: UInt64 = 0

        while offset < fileSize {
            try fileHandle.seek(toOffset: offset)
            let chunk = fileHandle.readData(ofLength: chunkSize)

            try await uploadChunk(
                chunk,
                offset: offset,
                totalSize: fileSize
            )

            offset += UInt64(chunk.count)
            saveProgress(offset: offset, for: url)
        }
    }
}

Challenge 3: Complex Form Engine

Inspection forms have hundreds of fields with complex conditional logic, validation rules, and calculated values.

Solution: JSON-Driven Form Renderer

We built a declarative form engine that renders forms from JSON schemas:

{
  "fields": [
    {
      "id": "pole_condition",
      "type": "select",
      "label": "Pole Condition",
      "options": ["Good", "Fair", "Poor", "Replace"],
      "required": true
    },
    {
      "id": "replacement_reason",
      "type": "text",
      "label": "Reason for Replacement",
      "showWhen": {
        "field": "pole_condition",
        "equals": "Replace"
      }
    }
  ]
}

This approach enabled:

  • Server-side form updates without app releases
  • A/B testing of form designs
  • Client-specific customization
  • Offline form availability

Architecture Decisions

Clean Architecture

We structured the codebase into clear layers:

OnTrackCore/
├── Presentation/     # Views, ViewModels
├── Domain/           # Business Logic, Use Cases
├── Data/             # Repositories, Data Sources
│   ├── Local/        # Core Data, SQLite
│   └── Remote/       # API Clients
└── Core/             # Utilities, Extensions

Dependency Injection

All dependencies are injected, enabling:

  • Easy unit testing with mocks
  • Swappable implementations (local vs remote)
  • Feature flags for gradual rollouts

Protocol-Oriented Design

protocol InspectionRepository {
    func getInspection(id: UUID) async throws -> Inspection
    func saveInspection(_ inspection: Inspection) async throws
    func syncPendingInspections() async throws
}

class OfflineFirstInspectionRepository: InspectionRepository {
    private let localDataSource: InspectionLocalDataSource
    private let remoteDataSource: InspectionRemoteDataSource
    private let syncEngine: SyncEngine

    // Implementation prioritizes local data, syncs in background
}

Performance Optimizations

Database Performance

  • Indexed frequently queried fields
  • Batch inserts for bulk operations
  • Lazy loading for large datasets
  • Background context for heavy writes

Memory Management

  • Image downsampling for thumbnails
  • NSCache for frequently accessed data
  • Automatic memory warning handling
  • Streaming for large file operations

Battery Optimization

  • Coalesced network requests
  • Intelligent GPS accuracy levels
  • Background task scheduling with BGTaskScheduler
  • Minimal background activity when battery is low

Security Implementation

Enterprise clients require strict security measures:

  • Data Encryption - SQLCipher for at-rest encryption
  • Secure Transport - Certificate pinning for all API calls
  • Authentication - OAuth 2.0 with refresh tokens
  • Biometric Lock - Face ID/Touch ID for app access
  • Remote Wipe - Admin can remotely clear device data
  • Audit Logging - All actions are tracked for compliance

Results

The app has been transformative for the client's field operations:

  • 40% faster inspection completion time
  • Zero data loss since offline-first implementation
  • 95% reduction in paper-based processes
  • Real-time visibility into field operations
  • Significant cost savings from improved efficiency

Lessons Learned

  1. Start offline-first - It's much harder to retrofit offline support
  2. Invest in sync testing - Edge cases in sync are subtle and destructive
  3. Build for low-end devices - Field workers don't always have latest hardware
  4. Plan for large datasets - What works with 100 records breaks at 100,000
  5. Document everything - Enterprise clients require detailed documentation

Need an Enterprise Mobile App?

I specialize in building complex, offline-capable enterprise applications. Let's discuss your project requirements.

Start a Conversation

Related Articles