Facy

SwiftUI MVP for Estheticians.

Overview & Requirements

Stacy Stewart (a practicing esthetician in San Francisco) and her fiancé Stephen Butler approached me to help bring their MVP of a smart and simple digital assistant for estheticians to market. Stacy was frustrated that there was no simple way for her independent practice to keep track of clients and schedule follow-ups.

The goal was to design and develop an iOS app to help estheticians take their practice to the next level by keeping track of client sessions, taking clinical notes, capturing image markups, and scheduling timely follow-up reminders.

They already fleshed out a nearly complete wire-frame of how the MVP would be laid-out and what the initial features were.

Tech Stack

I took my unique full-stack position to plan a holistic approach that would push my learning while also meeting the time and financial goals for the project. I decided to use a declarative based UI with a reactive data flow. This can have huge time savings in building, updating and laying-out app interfaces, but with a drawback of more upfront learning.

Swift UI

I chose to use Apple’s new declarative SwiftUI framework over the traditional UIKit because of its relative simplicity and composability. The newness of SwiftUI meant having to deal with odd quirks, bugs, and the frustration of dealing with something new.

View Magnifier

One of the most complex aspects of the SwiftUI views was the client image magnifier feature. Building this from scratch taught me a lot about small nuances of SwiftUI modifiers, gestures, coordinate spaces, and view reusability. The magnifier I built ended up being way more flexible than initially intended. Swift’s composability means that the magnifier will work on any view passed into it like Images, Nav Controllers, Buttons, or custom-built views

Magnifier view expands and moves over dog, showing its magnified face.
struct MagnifierView: View {
    @Binding var point:Identified<CGPoint>

    var body: some View {
        Image().magnify(point)
    }
}
    

View Source Code

One of the hardest learning curves that came along with SwiftUI was the paradigm shift to reactive data. It ensures that the data viewed is the same as the backing data. When the data updates the view updates instantly to reflect the change.

Data Stack

The first goal I set after picking SwiftUI with a reactive data approach was doing research on how to store the data locally. This MVP was planned to be iOS with local data only at first with the possibility to expand to cross-platform devices. I decided against CoreData as it’s iOS only and not designed to handle reactive data. I also wanted something mature and established in the dev community with ways to integrate with Apple’s Combine framework.

I ended up picking Realm because I had dabbled with it previously and it met all the requirements:

Combine with Realm

After picking Realm as the storage option, I needed to figure out how to fit it in with Combine and SwiftUI. Many hours of trial, error, and research led to a relatively simple 4-layer data flow from Realm to SwiftUI.

Facy v1.0 data layers.

After the low-level storage layer of Realm, I built a generic DataObserver layer. Its job is to observe Realm for changes and convert the changed data to abstracted structs and push them through Combine publishers so the DataStores can subscribe. This was needed because Realm on iOS had no native support for Combine at the time of building.

The DataStore layer is just grouped relational instances of DataObservers. These stores are accessed by SwiftUI through the EnvironmentObject or ObservedObject property wrappers. These wrappers auto-update the corresponding views when the underlying publishers send new data.

Once I had the proper data stack in place, polishing the interface and experience was natural and quick. Through the process of both designing and developing I made a choice to try and skip over pinning down exact design and moving directly to building product. This lack of understanding led to confusion and wasted time later in the process.

Facy MVP

Through the whole process of building Facy I had a blast learning, building, and communicating with Stacy and Stephen to bring this simple but delightful product to market. You can install and see it firsthand if you have an iOS device running 13.2 or later.

See on App Store

Stephen Butler

Sassy Labs

If you are like Stacy and I we couldn't recommend Eli Slade highly enough for effectively getting an MVP out the door. He has a great way of delivering aesthetics that serve the functionality of the product in a timely and professional manner.