Back to Projects
Back to Projects
OFFLINE CAMPUS NAVIGATOR

NTUSync

An offline campus transit optimizer and academic scheduler for NTU Singapore. All routing and schedule data lives on-device — the app makes zero network requests — with A* pathfinding, Live Activities, and monsoon-aware travel profiles.

github.com/Thet9354/NTUSync
NTUSync — offline NTU campus transit optimizer & scheduler

The Thesis & The Problem

Getting across a large campus between back-to-back classes is a routing problem the usual map apps handle badly — they don't know the sheltered walkways that matter in monsoon season, the link bridges, the shuttle headways, or which route is step-free. NTUSync models the NTU campus as a graph and solves it properly, entirely on-device: zero network requests, ever.

It pairs that with an academic scheduler that understands NTU's teaching-week structure, and Live Activities that put your active trip on the Lock Screen and Dynamic Island with a bus-boarding countdown.

Four travel profiles: Fastest, Rain-safe (weights sheltered walkways for monsoon season), Step-free, and Min-walk — all solved by A* over a hand-modelled graph of buildings, walkways, link bridges, stairs, and shuttle stops, with time-dependent Campus Loop shuttle costs.

Architecture

The campus graph is an immutable value type bundled as JSON — never in the database — so the A* hot loop can't fault managed objects and the whole routing layer is thread-safe by construction. Search states are (node, shuttle line) pairs, so boarding waits and transfers between Loop Red and Blue are costed correctly.

SwiftUI ─→ TripSessionCoordinator (@MainActor) ─→ LiveActivityCoordinator ─→ Widgets.appex │ TripAutopilot (pure) (ActivityKit txn mgr) (Dynamic Island) │ RouteProgressEstimator (pure) ▼ RouteEngine (actor) ── A* over CampusGraph (immutable, Sendable) ▲ SwiftData (SchemaV1, versioned) ── graphNodeID string joins

Trip Autopilot & Live Activities

  • Autopilot: GPS fixes advance a trip through its phases (walk → wait → ride → walk → arrived) automatically; in GPS-denied basements it falls back to pedometer dead reckoning constrained 1-D along the route geometry.
  • Live Activities: state is pushed only on plan transitions and ticking time is rendered by the system — a full trip costs at most six ActivityKit pushes.
  • Timetable: courses and sessions stored fully offline in SwiftData, with NTU's 13-week teaching structure (recess after week 7, odd / even-week sessions) encoded as a 13-bit mask.

Testing

The test suite doubles as the data contract: graph integrity (edge lengths vs haversine, foot-network connectivity, timetable coverage), an A* ≡ Dijkstra equivalence property test, autopilot transition rules, the ActivityKit push budget, and crash-recovery snapshot rebinding. The generated campus graph derives its edge lengths from coordinates so those validation tests stay green.