-
Notifications
You must be signed in to change notification settings - Fork 1
UniSaarApp 2.0 Modernization Plan
Welcome to the UniSaarApp wiki!
UniSaar 2.0 started as a student project at Saarland University's Software Engineering Chair. I led the team and built the iOS app with a simple motto: by students, for students. The app launched in 2020 and was published as the official Saarland University iOS app, available in German, English, and French, covering everything students need: Mensa menus with allergen filtering, campus maps, staff directory, university news, and events. It included accessibility features like adjustable fonts and a colorblind mode, with no user data collected.
In 2025, the university released their own official app, UdS-App. They didn't push it as an update to UniSaar, so thousands of legacy users may still have it on their phones. The UniSaar iOS app still runs today; only the news feed was affected due to uni server-side changes (fixed).
Coming back to it in 2026, the codebase was following 2019 design standards: CocoaPods, completion handlers, manual delegate wiring, no real concurrency model, and legacy UIKit patterns. It compiled and ran, but it was the kind of code I know I'd write differently today.
So I decided to modernize it properly, not just to make it compile on a newer SDK, but to use this as a learning experience to teach myself how modern iOS development is done in 2026, and to actually understand and apply everything Swift and iOS have become. This wiki tracks that journey.
This represents the full modernization track, moving from upgrading the Swift & iOS foundation to completely rebuilding the view layer in SwiftUI.
- Current Status: The live iOS app works. Users are unaffected.
- Scope: Everything happening here is internal—upgrading how the code is written, not what it does. No drama.
-
Execution: Three milestones. Each one builds on the previous. Phase 3 cannot start until the first two are done.
SwiftUIviews built against unstable API contracts create rework.
Swift 6 strict concurrency doesn't just ask you to update syntax; it forces you to reason about thread safety in a way the old code never did. Understanding where @MainActor isolation sits, what Sendable actually means, and how @Observable replaces the old delegate and binding patterns took real iteration.
The goal isn't just compiling under Swift 6. The goal is to complete the MVVM audit. ViewModels are @Observable, Models and Networking are clean of UIKit and NSObject, and SwiftyJSON is replaced with Codable. By the end of this milestone, the persistent layers are fully clean and ready for the SwiftUI migration.
The original worked but was fragile. I decided to fully rewrite it with FastAPI and Pydantic v2 as a chance to learn a modern Python backend stack properly.
This architecture includes type-safe data contracts aligned to iOS models, async scrapers, rate limiting, and a full CI pipeline. The new server replaces the current one without disruption to the live app.
Everything in the first two milestones was preparation for this. We are executing a full replacement of ViewControllers, storyboards, and XIBs with SwiftUI views. ViewModels and Networking survive unchanged.
-
Full SwiftUI Rewrite: Not an incremental
UIHostingControllerhybrid. The ViewModel layer is already@Observableand framework-agnostic, making a clean swap viable. -
Swift 6 Strict Concurrency: We are not just compiling under
Swift 6. The goal is full compliance:@MainActorisolation,Sendablemodels, and zero unsafe workarounds.
UniSaar Modernization Plan (v2.x)