Hey hey 👋
Hope you've had an awesome November so far! I've been hard at work since I rolled out the widgets update, adding new graphs to the Productivity tab in Focused Work.
It's been a much bigger challenge than anticipated, since I've rebuilt this screen completely in SwiftUI and learnt how to create bar charts and line charts along the way. I've always wanted to create a dashboard so I could quickly glance at my progression the last week, month, and last half of the year, and establish a baseline for my productivity to see how i'm tracking.
Here's a quick snippet of it in this tweet:
Because i'm building the charts in SwiftUI, it will be super easy to adjust them for iPhone and iPad screens, and gives me the option to add them to a widget.
I'm most of the way now, and aim to roll this update out during the next week or so 🙏 I also have more improvements I want to include based on feedback shared with me, that i've been super appreciative for! More on them soon..
In-between all of the above, I've finished writing Part 3 of Launching an Indie App focusing on the second month of my journey: "A Tiny MVP".
Here's the link to check it out in the browser, but i'll attach it below if you're interested in reading on.
Enjoy your week, and I look forward to sharing more news soon! 🙂
Launching an Indie App - Part 3: A Tiny MVP
I was ready to hit the ground running after doing my homework, but I encountered my first setback much sooner than expected. The pandemic wasn’t going to stick a fork in my momentum.
In this part of my journey, I dug my teeth into CloudKit to figure out how to holistically track my productivity history regardless of whether I used my iPhone or iPad, and then began building the core functionality of the app so I could actively use it every day.
During the first month, I covered quite a bit of ground and established a baseline for the app. Feel free to revisit the Part 2 article if you haven’t been following along, but here's a TLDR;
My venture began with installing 15 Pomodoro apps from the App Store so I could get a grasp of the market, and brain dumped all my thoughts into a Notion document.
I translated said braindump into rough sketches with my iPad Pro to get a rough visualisation of my spin on a productivity app, which was heaps of fun given my creative streak!
After deciding on Focus Group as the running name, I briefly defined my process that would be my guide for launching on the App Store.
I ran paper Pomodoro sessions to simulate the behaviour of the app (which were quite fascinating) and discovered a bunch of amazing resources from other indies that had already launched their apps.
Finally, I created the Xcode project. 🖥
The Second Month, beginning April 1st
Week 5 - Pandemic, Development, Architecture
After experiencing that high of creating the Xcode project and wanting to start writing code, reality came crashing down.
Literally the next morning.
I woke up to an email from my favourite client which mentioned the project that was due to kick off this coming week was to be postponed indefinitely because of the coronavirus impact on the travel industry.
While observing the pandemic the prior few months I held some notion we'd be sheltered this far down, considering I live closer to Antarctica than Darwin. Turns out that’s not the case.
I spent the rest of the day with a sinking pit in my stomach knowing I'll be missing a couple of months of income, but also because my clients business was going to struggle from factors outside their control. It was a real shit feeling.
I eventually realised there's a silver lining here.
I'm still alive and well, and there will be others that will do it tougher than me, but I know I wouldn't find a better opportunity to work on my very own product uninterrupted, full time.
I felt like I could cover a LOT more ground in the next couple of months, so I immediately got to work. 👨💻
I created a basic Timer UI that included; Start, Pause, Resume, and Cancel functionality.
I continued improving the smarts of the app by adding the ability to; move through each stage of the focus session, play a (low quality) tick-tock sound, adjust the volume with a slider, and add the option of entering your focus for the session.
From there, the next few additions were; adding a switch to ensure the screen remained switched on during a focus session, mid-session reminder alerts, and making sure the focus session would continue when the device was locked.
I discovered a Dependency Injection tool Resolved, to neatly glue together all the important responsibilities of the app. It was Swift 5.1 compatible, offered annotation injection, and was a performant upgrade over the Swinject / SwinjectStoryboard combo I've used for years. Sold.
Up until now, everything was wired together with spaghetti code, and I know too well the benefits of building a scalable architecture from the get-go.
I started decoupling the business logic from the screens into well-defined "services", so I could rapidly prototype the UI without worrying about tip-toe-ing around code.
This was my quick sketch laying out each service and how they'd interact with each other.
A couple of days later I had a nice six-hour stint working on the app and reached a flow-state for the first time. It felt awesome to be super productive!
I hardcoded some focus session combinations and added the option to pick a session for the task I was going to work on.
I then continued reading the book Hooked, completing the next chapter of the Hook Model which discussed the topic of “Action”: "Following the trigger, comes the action; the behaviour done in anticipation of a reward."
A possible “trigger” for my app would be to leverage the users current situation to encourage them to use the app. The following “action” would involve a way to motivate them to complete their daily Pomodoro goals.
I figured this idea can be implemented by first showing a message when a focus session is completed, and if they only have 2 sessions left to meet their daily goal, show an alert to remind them: "Only 2 more to go... you can do it!". The action would be them deciding to continue and begin another focus session.
Wrapping up the week I created a Github repo so I could save my work. After completing uni, I had a habit instilled into me of committing my changes to source control (a.k.a saving my work) when I create new features or make changes.
It has saved my ass so many times. (yes, intended 😆)
Week 6 - SlowKit, Rewards, a dash of paint
Having the ability to use the app on my iPhone or iPad and seamlessly share progress between both was something that appealed to me. I felt it'd be quite challenging to pull off and would require me to upskill in CoreData and CloudKit since they'd be my ticket.
Up until now my only experience with CoreData (an interface for the database) was during my uni days, creating dummy apps with iOS 7 and Objective-C. Can't say I share many fond memories of the latter.. 😉
CloudKit was supposedly similar to Firebase's Realtime Database, where if you make a change to something like a label or a setting on one device, the second device would reflect that change straight after.
I figured I'd get my hands dirty and try simulate this behaviour by starting a focus session on one device, and seeing how the second device would react. It worked, but I was expecting a delay of a few seconds, not between 10-30 seconds! So the "real-time" theory went out the window.
After placing this niche idea on the back burner, I narrowed my focus on creating an experience that caters to using a single device at a time.
Next, I decided to also add some very basic overall progression stats to the screen.
Moving on from a boring basic white screen was the next thing on the list, so I moved a few elements around, added larger fonts, contrasting colours, and created a select session screen.
Here’s a quick video of this in action! 🙂
Finally, the app was now looking somewhat iOS-ish! 👨🎨
Week 7 - Emojis, Second-hand inspiration, Cross-device struggles
Something that stood out to me with alternative focus timer apps, was their level of UI clutter whilst the focus session was live.
I felt that only the countdown timer, current goal, and level of session progress should be the necessary elements displayed. The focus should be on the task, not the app. I added this idea to the 🧠 Braindump board for later.
Two more screens were added; a focus session details screen (labelled "timer" at the time), and an emoji picker screen for prefixing the title of each session to make it more visually prominent.
Returning to my database challenge, although I couldn’t achieve realtime updates with CoreData & CloudKit I realised there's still some benefits for sharing data cross-device. Productivity stats, and if you complete a focus session on your iPad the result should reflect on your iPad.
It turns out it's possible to selectively sync parts of your data model via CloudKit, and keep the rest local. 🤔
It was a no-brainer to purchase and play around with on my iPhone and iPad, especially given the app was tailored to meet the goals of Jordan's article A Best in Class iOS App.
I spent an entire day from 10:30 am til 9:30 pm working on my apps sync functionality when creating and deleting focus sessions, and updating its stages.
I ran into so many issues reordering stages, updating stage durations, and propagating UI changes between the iPad's Master-Detail view. (the scrollable list on the left side, and the details section on the right side). And then I faced more cross-device syncing issues between my iPhone and iPad. 😴
I'm glad I had Jordan's app as an inspiration for eventually nailing this feature, but I needed to continue persevering with trial & error.
One area of CoreData that threw me off was that if you update an associated child object returned via a FetchedResultsController, the controller will not auto-refresh and that you will need to manually handle updating the UI. Adding/removing the child from the parent will however trigger a refresh.
By now I had created four main screens; Current Timer, Pick a Timer, Update Timer, and Settings, and then moved some navigation buttons into a bottom tab bar, to make the app easier to navigate.
Overall the week was a great learning experience, and I was happy it closed out with a new feature for creating a configuration of focus sessions & stages. Cheers to no hardcoded data! 🍻
49 consecutive days of working on the app came to an end, as I rewarded myself with an entire Sunday off!
Week 8 - v0.2 Phase, Using the app full-time, Cradling it
As the size of the app grew, so did the number of new bugs. I created a 🐞 Bugs Board on Notion to keep a note of issues that I need to go back and resolve.
Sidenote: In my previous article I mentioned I didn't have a picture of what my Notion board looked like at the time. Well, I managed to find an old screenshot while cleaning out my iPad’s Photo Library!
Now that I had ticked all boxes in the 🆕 v0.1 Features board, I began consolidating ideas inside the 🧠 Braindump board into a 🆕 v0.2 Features board for the next phase of work.
Up until now I mostly used competitor focus apps to help me focus while I worked on the app, as I didn't want to be distracted by app glitches. But I was confident it was at a stage where I could start using it every day and have it help me focus on building it.
I felt like a hamster running on a wheel of motivation, fuelled by my own desire to motivate myself. 🐹
I noticed I could also calculate the total focus session time before I started and begin placing artificial time constraints to avoid working past midnight. Suddenly I felt I had more control over how I spent my time.
Here's how Dark Mode looked when it kicked in for the first time on my spare iPhone SE!
I have a mini cradle on my desk that it sits in, but it must be placed sideways when charging. So it was a no-brainer to optimise for rotation support so I could have the timer screen displayed at all times.
I spent the remainder of the week adding more features;
- Distraction awareness alerts, which are mid-session reminders to keep on focusing. This was inspired by the paper Pomodoro sessions I ran last month.
- High quality ticking and stage transition bell sounds
- Marking a focus session as completed, if it was cancelled while close to completion
- A session completed screen, which appears with some confetti after the final stage of a session
I also added a focus mode feature that when tapped will hide most of the app's UI, which I had previously pondered over.
After another productive week, I ended the month with a lovely two-day break! 🤗 (Day 56/57)
That's it for Part 3, thanks again for following along!
If you have any questions, ask me below or reach out via Twitter.
Life was a little busy for me between Part 2 and now, so I hope to share Part 4 with you sooner! 🤗