Midpoint Internship Report: Finding the Ground Before Building Up
When I wrote the initial proposal, the core goal of the internship felt straightforward: connect the Scribe client applications (iOS and Android) to the Scribe server so language data could be downloaded on demand instead of being bundled in the app. In practice, the first half of the internship turned out to look very different from that plan.
Within the first week, it became clear that a lot of groundwork was needed before any meaningful server integration could happen, especially on iOS. Scribe-iOS didn’t yet have an established Download screen, which meant that before I could even think about downloading data, I first had to work on the user-facing flow that would eventually make that possible. This wasn’t something I had planned for in my original timeline.
A few days before the internship officially started, my mentors helped me break the project down into initial tasks for the first week. Before I really got into those, I spent some time building a small proof of concept to see whether I could connect to the Scribe server and write the returned data into a local SQLite database. That work was the closest I came early on to the goals described in my proposal.
Even though much of the first half focused on preparation rather than full server integration, I was still able to make meaningful progress.
Weeks 1–2: Learning the Surface and the Edges
In the first week, I worked on adding an “update” state to the download button on the Scribe-Android Download screen. This task helped me understand how the screen was structured, how state was handled, and how the UI responded to different download conditions.
This week, I also fixed an inconsistent border radius issue that appeared on iOS 26 devices and simulators. What initially looked like a small visual bug turned out to be more complex: the affected cell relied on system-managed styling, which applies default corner radii that are difficult to override directly. The solution was to wrap the original cell content in a custom container view and apply the corner radius there instead. This ensured consistent behavior across iOS versions and gave me a better understanding of how UIKit applies system styles under the hood.
In Week 2, I focused on creating a tooltip-style confirmation dialog for selecting the translation source language. When users attempt to download a language for the first time, the app will ask them to confirm whether they want to use the currently saved translation source language or change it. This work involved building a reusable confirmation dialog component in both Kotlin and SwiftUI, which was a valuable exercise in designing shared, configurable UI components.
Week 3: Untangling Navigation and Shared State
In Week 3, I integrated the confirmation dialog into the Download screen and added navigation to the translation source language settings. While working on this flow, I realized that an additional confirmation dialog was also needed within the translation language settings itself, before a download could actually begin. To support this behavior, I extracted the Download button component and its state handler from the Download screen. Since the same download logic is now used across multiple screens, the state needs to persist as users move between them.

Weeks 4–5: Localization and the iOS Download Screen
Week 4 began with converting Scribe-i18n from a Git subtree into a Git submodule. Both Scribe-iOS and Scribe-Android depend on Scribe-i18n for application text localization. Previously, while there was a script to update the subtree from the main Scribe-i18n repository, any actual changes to localization keys or values had to be made in a separate local copy, outside the client repositories.
Switching Scribe-i18n from a Git subtree to a submodule made day-to-day localization work a lot more practical. Instead of editing localization keys in a separate copy and syncing them back in, we can now add, remove, and update strings directly inside the Scribe-iOS and Scribe-Android projects. That made it easier to keep the UI and its translations in sync.
For the rest of Week 4 and into Week 5, most of my time went into building the iOS Download screen itself. I decided to write the screen fully in SwiftUI, even though it lives inside the Installation tab, which is still built with UIKit and Storyboards. Getting those two worlds to work together wasn’t straightforward, especially around navigation. A lot of time went into making sure screens were presented and dismissed correctly and that the flow didn’t feel broken or inconsistent.
Week 6: Stabilization and Bug Fixes
Week 6 was mostly about fixing issues that came up once the download flow was wired together. Some of these were navigation bugs, others were UI problems that only showed up after moving back and forth between screens. It wasn’t very visible progress, but it helped stabilize the flow and made it clearer what still needs to be done before server integration can move forward safely.
Looking Back: What Took Longer Than Expected
In practice, I wasn’t able to make direct progress on several parts of my original proposal during the first half of the internship. Much of that work depended on UI and navigation infrastructure that didn’t yet exist, particularly on iOS. Before server integration could even be considered, the Download screen and its surrounding flows had to be designed, built, and stabilized.
I underestimated how much foundational work this would require. Mixing SwiftUI into an existing UIKit app also turned out to be more complex than I thought. As a result, the first half of the internship focused less on implementing the proposal itself and more on creating the groundwork needed to support it.
If I were starting over, I would spend more time at the beginning understanding the existing client architecture and explicitly planning for UI groundwork before committing to server-side goals. That would have made my early milestones more realistic.
Revised Plan for the Second Half of the Internship
For the second half of the internship, I’m narrowing the scope and focusing mainly on Scribe-iOS. The plan is to:
Integrate the iOS client with the Scribe server to download available language data (currently limited to nouns and verbs).
Store that data in a local SQLite database.
Make sure the downloaded data can live alongside the existing on-device database without breaking current features.
Update the keyboard so it reads nouns and verbs from the new database when they’re available, while still falling back to the existing database for anything that isn’t supported yet.
Improve user-facing messaging around downloads, especially when language data needs to be downloaded before it can be used.
By focusing on getting this flow working end-to-end on iOS, the work from the first half of the internship can serve as a stable base for moving closer to the original goal of downloading language data dynamically.
