Patesian: A Full-Stack iOS Companion App for Schools

A deep dive of my develpment of a full-stack iOS application designed to streamline student life at Pate's Grammar School, featuring timetable integration, campus navigation, and a social feed.

Back when I was a student at Pate’s Grammar School, I was frantically navigating the school with a paper map, trying to match free periods with my friends by texting photos of our timetables, and keeping track of all the societies I signed up to. It was honestly a struggle but a struggle that I thought could be made more efficient for the students to come. This inspired my final school programming project: to build a modern, all-in-one solution to streamline these aspects of student life. Thus came Patesian, a full-stack iOS app designed specifically for the students and visitors of Pate’s.

The Problem

Whether you were a new student or a visitor, navigating a large school was daunting. Paper maps were provided but lacked the interactivitiy and instant repsonse of digital maps, as it can’t show your current location. Similarly, simple tasks like sharing timetables plan what friends would do during free periods were tedious, often sending screenshots to crowded snapchat groupchats. I wanted to create a solution that was:

  • Intuitive: Easy enought that anyone could pick up and use on their first day.
  • Efficient: Automated the process of accessing and sharing schedules.
  • Centralised: I wanted this to be the one app you needed to organise all parts of student life.

The Solution: A Full-Stack Approach

I developed a full-stack application with a Swift-based iOS frontend and a Node.js backend.

  • Frontend (iOS App): Built natively with Swift and SwiftUI, it provides a responsive and familiar user experience. It uses CoreData for on-device caching and communicates with two main APIs.
  • Backend Server: A Node.js and Express.js server powers a RESTful API, with a MongoDB database to store user data, posts, and user to user relationships.

The app’s core features include:

  1. An Interactive Campus Map: A live map showing the user’s current location on school grounds via GPS.
  2. Dynamic Timetables: Integration with student Microsoft accounts to automatically fetch and display personal timetables. - Achieved through Microsoft Graph API
  3. Friends System: Allowing students to add friends and view their timetables to easily find shared free periods.
  4. Social Feed: A dedicated space for societies to post announcements and updates.

Timetable

I started with what I anticipated would be the most difficult module: timetable integration. This required authenticating users with their school Microsoft accounts and pulling calendar data from the Microsoft Graph API.

Authentication was handled using the Microsoft Authentication Library (MSAL). An early bugfix was needed; the boilerplate code from Microsoft would crash the app if a user cancelled the login prompt. I implemented some more robust error handling to catch the empty token and display a user-friendly error message instead.

When fetching calendar data, I discovered the API returned a maximum of 10 events by default. To get the entire school year though, I had to modify the API call to request a much larger number ($top=100000). However, this resulted in a lmuch longer download time (over 10 seconds). To prevent the UI from freezing, I implemented the entire data-fetching process asynchronously, ensuring the app remained responsive while data was being downloaded in the background.

Broken Display Adhesive

Bluetooth to GPS

Initially, I had decided to use Bluetooth Low Energy (BLE) beacons. I was going to use ESP32 boards around the school to triangulate a user’s precise indoor location.

However, after building a prototype and testing it with a real iPhone, I found the RSSI (Received Signal Strength Indicator) values to be unresponsive due to a low refresh rate and inaccurate. The signal was easily obstructed by walls, making it too unreliable for accurate navigation.

Recognising this, I pivoted away from Bluetooth and instead use the iPhone’s built-in GPS with Apple’s MapKit. It was perfectly suited for the primary goal: helping users find their general location on the school grounds. For this, I used UIKit’s more feature-rich MapKit implementation and integrated it seamlessly into my SwiftUI app.

Ensuring a Snappy User Experience

My goal was to make the app feel fast and responsive. I achieved this in two main ways:

  1. Concurrency: As mentioned, heavy tasks like API calls were offloaded to background threads. This ensures the main thread is always free to handle UI rendering and user input, preventing the app from ever feeling “stuck.”
  2. Caching with CoreData: The app saves a user’s timetable, friends list, and posts to the device’s local storage using CoreData. When the app launches, it immediately displays this cached data for a near-instant load time. It then fetches fresh data from the server in the background and updates the UI if anything has changed.

Final Thoughts

Building the Patesian app was a time-consuming but fun project. It forced me to discover mobile development with full-stack architectures, use third-party APIs,and make sacrifices when needed. One of the most important lessons was on privacy - after discussing a location-sharing feature with a stakeholder, I decided against it to protect student data, a crucial consideration for any real-world application.

The feedback from fellow students was positive which confirmed that the app was intuitive and solved the problems I set out to address.

You can find the source code to both the server and client app on my repositories page!