loading...

October 30, 2021

So You Want to Recreate an App Part 1

Preface:

For quite a long time now I’ve gotten questioned regarding how I’ve gone about building OldOS’s apps. Each time, whether it be a conversation, DM, or tweet, I struggled to fully capture how they were developed. As I’ve said before, one of my chief missions in creating OldOS was to educate on the power of SwiftUI. Of late, I’ve been inspired by the build-in-public movement, and therefore have decided to chronicle my exploits in building a new app for OldOS: Mail. Sit back, relax, and enjoy So You Want to Recreate an App Part 1

The beginings:

Welp where to begin. I guess I’ll start by making this completely plain: I’ve never built an email app like this before. I know about email protocols (IMAP, SMTP, POP), but that’s about it. I also know, having used apps such as Spike and Spark, that modern email sign-in requires some form of an OAuth flow. What I don’t know is A) how these are implemented B) if I can hold true to the original OS C) what the development process for any of this will look like. 

Alright, so let’s just try to load an email:

Usually, when I build an app for OldOS I fuss about the UI first, trying to build the entire app with dummy data before dealing with live server-side and/or on-device data. However, this time around I settled on the latter first. Why? Like I said before, I’ve never built something like this, so I’d prefer to research and educate myself before diving into the UI (which I’d maintain is the easier part here). 

The first question that always pops into my mind is “what frameworks/libraries are already available?” My approach to answering this question is simple and repeatable: 

1. Browse Google, read Stack Overflow, see what solutions others have used successfully.
2. Search GitHub for popular frameworks/libraries. Learning to use GitHub properly is one of the most powerful things a developer can do.
3. Research frameworks/libraries that look promising. Read through the code. See if there are any samples built.
4. Build a list of possible solutions and alternatives. 

In the context of the Mail app, I started off researching IMAP and SMTP. I tried to learn fairly extensively how they function before I did any other work. Once I felt somewhat satisfied I began browsing GitHub, reading code, and building samples. In the end, I came up with two potential email frameworks I’d use: MailCore2 and Postal.

So, I first got Postal installed on OldOS and tried loading some emails. I was excited, Postal looked promising — the documentation was good, it looked relatively simple, and did most of what I needed (at least I thought so, more on this later). I set up a simple login and fetch emails from inbox function and entered in my email and password as per the documentation. I was stunned at how easy this all seemed and was extremely excited. I clicked build, eagerly waited for it to launch, and started the mail app. I checked the console only to see the error “Unable to authenticate.” Realizing this wasn’t right I tried using a different email address, this time Yahoo instead of Gmail. Same result. I tried another email address, this time Outlook. Huzzah, it was a success. I was puzzled, to say the least. I spent a good hour reading about the differences between the email providers, only to realize that Google and Yahoo require app-specific passwords. So, I set up an app-specific password for yahoo first, and…no luck. Then, it hit me. OAuth…I need OAuth. I knew Google had an OAuth key builder website, so I tried it out, plugged the key I generated in, and low and behold, it worked. But now, we have a new issue: we need to build OAuth into the app. But how?

We repeat the same process for finding email frameworks with OAuth. My first inclination was to use GoogleSignIn. Why? I had used it before, the documentation is fantastic, and it’s a great way to experiment with OAuth. I built a simple function to retrieve the OAuth token and pass it to the fetch email function. In the end, it took me all of ten minutes to get it up and running. But, here’s the issue: it works by opening a WebView sheet in the app. We have no control over this sheet, and, as you might expect, it uses iOS 15 UI components. Thus, we end up breaking a core tenant of OldOS — to make a perfect visual recreation of iOS 4. So, I needed to do more research and find an alternative.

After much work, I settled on P2’s OAuth2. This is an astoundingly powerful framework that allows us to control every aspect of our OAuth integration. By the same token (no pun intended), it doesn’t just limit us to Google OAuth — we can use any email provider. Using OAuth2, the flow I’ve settled upon for now I believe is a best of both worlds approach. When a user wants to log in, we link out of OldOS to the Safari app. We then use a custom URLScheme to redirect back to OldOS. Once the user is logged, OAuth2 does all the work managing our tokens and generating new ones for us. We have the backbone of our app working: we can sign in, fetch emails, and load their contents. 

In part 2 we’ll go over:

• Transitioning to MailCore2
• A general implementation (model) for how we are going to go about managing emails.
• Building the basic UI.
• And an efficient system for fetching emails and caching them.
Posted in Projects