I’m extremely happy to introduce my second SwiftUI app. I call it Snack Plan and It’s a way for you to track the snacks you’re planning to eat when you visit a theme park.
I wanted to write an app where 99% of people would say “Huh?” when I described what it did and I really feel like I’ve achieved that goal.
The Press Kit contains raw screenshot images and info found in the App Store description.
OK, it does what?
This is actually something I wrote for myself. When you’re someone who REALLY loves going to theme parks and goes a lot, many of the visits become centered around things that are totally different from people that go rarely/infrequently. A lot of the visits can be centered around food. For example, theme parks will have special desserts to celebrate a particular season sold at unique places throughout the park. It can be hard to remember where they are located. Even if snacks are sold year-round they aren’t always sold in obvious places. Cronut (or “croissant doughnut”) fans that go to Epcot know that where it’s sold can move.
And then there’s food festivals. People that aren’t theme park enthusiasts might be surprised to learn that food festivals have become a huge part of the theme park experience. As I’m writing this in March 2022 I can easily think of four that are happening right now. Epcot is holding their Flower and Garden Festival where temporary structures are spread throughout World Showcase selling unique snack items. At the Disneyland resort the Disney California Adventure Food and Wine Festival just kicked off. At Universal Studios Florida it’s Mardi Gras time with specialty treats such as King Cakes and beignets! And SeaWorld in Florida is now holding their Seven Seas Food Festival.
It is impossible for me to eat everything that I want to in one visit to a festival so I needed a way to keep track of what I didn’t get to eat. I also needed a way to track what dishes are served because snacks that normally aren’t sold throughout the year are sold at festivals and they’re sold from temporary structures that aren’t always there. I was frustrated that I didn’t have an easy way to keep a list of the snacks I had on my agenda that would work offline (I have had some painful connectivity issues with WiFi and cellular when the parks are packed). I also wanted a way to copy/modify plans and track what was unfinished in plans That’s what inspired me to write this app.
The app lets you create a list of your favorite snacks. The theme park veterans know that one type of snack is NOT the same throughout the park. For example, theme park experts Carly Caramanna and Houston know that tracking down the best pretzel in a theme park can be tricky.
This might be a little-known secret, but there are only two food stands in @UniversalORL that have the best soft pretzels out of all the parks in Florida. They're true Bavarian style... not your run of the mill "superpretzel" like all the other stands. One is in Jurassic Park.
— Houston on PRIDE Radio (@radiohouston) January 31, 2022
If the best pretzels are in a certain part of a park the app lets you record facts such as that in the notes section of each snack. The pro version of the app populates your list with many popular snacks to get you started. Of course you can easily delete those and create your own from scratch if you want. After you’ve entered details of the park you’re going to visit you can create a plan. When your day is done you can see what snacks you missed. You can easily reuse that plan or copy it to make another plan for later.
Fun stuff
I have been dying to build something fun and silly. I’m actually still somewhat surprised that my first app, Museum Shuffle, was about such a “serious” topic (museum artwork). The fact that it was my final project for a course and that I had a hard requirement to use someone else’s API pretty much forced my hand. I initially wanted to make an app about theme park wait times, but couldn’t find a solid API that reported that data. I’m proud of what I created with my first app and I still enjoy tweaking it once in a while but it’s completely nerve wracking being 100% dependent on someone else’s service. If the Rijksmuseum decided that they didn’t want to provide an API any more then my app’s functionality would be killed also. That’s hundreds of hours of work down the drain. For my second app I wanted to not rely on a third party for its primary function.
There’s lots of inspiration for making silly things. Rafael Conde always makes me laugh with his marketing material and his creations are so much fun. Daniel Storm has a whole catalog of silly creations. Josh Holtz comes up with bonkers concepts such as an emoji photo cropping tool with a 💩 forecast that change what emoji you get. Emin Grbo took something as mundane as an egg timer and made it silly.
Another goal of mine has been to eventually be able to make fun, whimsical user interfaces like Dan Gauthier has done with his Oh Bother and Up Ahead apps.
Elevated levels of whimsy detected; proceed with caution pic.twitter.com/XPSuIi72XC
— Dan Gauthier (@danielmgauthier) November 11, 2021
He can make even the most mundane items look great. I’m nowhere near that goal but I feel that I’ve taken a step (albeit a baby step) towards that goal. I tried my best to make the UI fun and interesting.
That icon though!
I think a key fun factor of the app concerns the app icon. I came up with a concept that I was really happy with. I had been leaning towards putting a doughnut in it and when I realized that a ferris wheel is also a round shape the idea solidified. If I would have hired a well known designer it would have been very expensive. That didn’t make sense for a silly pet project app. I tried using a cheap designer but I wasn’t crazy about the artwork I received. I showed it to Emin and asked him for his opinion. In a ridiculously short time later he wrote back and said “This is what I would have done” and attached the app icon I’m using. I still love it and it is exactly how I wanted it to look. I’m so grateful for his help.
Geeky details
Touch here if you’d rather skip past the geeky details of how the app was built.
The app is 95% SwiftUI. Because it’s a brand new app I’m creating for myself I had complete freedom to make iOS 15 the target. I got to learn how to use many new SwiftUI features. Building something is completely different than following along with tutorials and I’ve found that I can only effectively concentrate on one or the other. When you’re building something you constantly have to learn how to overcome issues that crop up, whether that be a bug or a concept you have not learned yet. When I’m building something I’ll eventually start to feel that I’m falling behind on learning things from tutorials. However, when I’m focusing on tutorials I’ll start to get the longing to build something. It can be a difficult conundrum to flip between these two states.
Every year Paul Hudson makes a handy list of all of the new SwiftUI changes announced during WWDC. Each year I like to go slowly through his list and get experience with the changes. Working on this app was a great way to learn about (and incorporate) many of these new additions. Here are some of the new iOS 15 SwiftUI features I was able to make use of:
- MainActor
- I got to start to learn about the newest additions to concurrency in Swift. I found it delightful that all I had to do was add a Swift @MainActor to the ObservableObject in my app and then I never have to worry about if something that updates the UI with it is running on the main thread. Code that wouldn’t be will be flagged by the compiler.
@MainActor
final class AllData : ObservableObject {
- swipeActions()
- This new modifier let me add custom swipe modifiers to my Lists. You can specify colors, what actions are performed, if full swipes are allowed, etc.
If you add a .swipeActions to a List with SwiftUI (iOS 15) and perform a long swipe it is the same as if you revealed the button and pressed it. You get this functionality without having to do anything extra. Nice! pic.twitter.com/YT0dtEemiG
— Chris Wu (@MuseumShuffle) January 12, 2022
- ForEach from a Binding
- SwiftUI now lets us use Binding with ForEach and List. That’s how I was able to have the app remember what parts of a DisclosureGroup are opened or closed.
- ButtonRole
- You can now specify a button’s role. For example, when you mark a button in a swipeAction as destructive it will automatically be colored red.
- New buttonStyle
- New styles for buttonStyle such as .borderedProminent give more options on how to display buttons.
- New Alert Format
- The way you create alerts in SwiftUI changed with iOS 15. Also alert(item:content:), which I made extensive use of in the app, was deprecated. While it would still work for now, I took this as an opportunity to learn the new syntax and changed my code to use it.
- confirmationDialog
- I used this new way to ask a user if they were sure they wanted to perform destructive actions in the app.
- submitLabel()
- This let me change the “Return” button on the keyboard into a “Done” button.
- Markdown
- This was something I already knew from creating this blog, but it’s lovely to be able to use Markdown with SwiftUI.
- task()
- I need to call some asynchronous code for purchases or to check if the paid version has been unlocked and this new addition to SwiftUI was very handy for that. It starts when the View is displayed and is cancelled when the View goes away.
- listRowSeparator()
- SwiftUI give us more fine control over lists. This modifier lets you hide list row separators. You can also use listRowSeparatorTint() to change their color.
One more thing to learn….
- In-App Purchases
- I knew absolutely nothing about in-app purchases when I started writing this app. I had seen successful indie developers mention how RevenueCat had worked well for them. I knew that Josh Holtz had started working for them recently and reached out to him after poring over their documentation. Josh patiently answered a LOT of questions and got me up and running.
Build it yourself!
Something that I had desperately hoped would be new in iOS 15 would be an emoji picker. When that didn’t happen I wrote my own, which ended up also being a great learning experience.
The first version I wrote was “ok” but it had a huge flaw. It had just stored simple food emojis for the app to use, but I didn’t know how to handle emojis with multiple variations (skin tone, etc.).
I'm currently debating if I should spend time improving this clunky emoji picker I wrote in SwiftUI. I have a feeling that if I do they'll introduce one with iOS 15. pic.twitter.com/giYy1IXHXs
— Chris Wu (@MuseumShuffle) April 15, 2021
Stewart Lynch found an emoji JSON file and Jordi Bruin wrote some code to decode it. With that I went about building my own emoji picker for the app. See my previous posts “Building an emoji picker” part 1 and part 2 if you want to know more details. I’m pretty happy with what I came up with but would happily rip it all out if we got an emoji picker with iOS 16!
Perfection isn’t required
I think when you’re building something fun it’s important to remember that it’s not going to be perfect. The perfectionist in me didn’t want to release this app until everything was perfect. There are some things in the app that I don’t like that are limitations caused by bugs I’ve reported or functionality that doesn’t exist with SwiftUI yet. There are some limitations in the app that I don’t like because of the way I initially designed it. I’ve learned that is all ok. I think it’s more important to put your work out there and be satisfied with the untold hours you spent on it.
Build in public?
Many indie devs like to build in public and it’s interesting following their progress. A large number of my blog posts and many Tweets have actually been about what I’ve learned and dealt with while building this app. Moving items in multiple sections of a SwiftUI List? It was me experimenting with how to display my data. It was no coincidence I used Walt Disney World in an example. Building an emoji picker part 1 and part 2? Something I had to do for the app since I made emojis so prevalent. Working with DisclosureGroup? It’s how I ended up displaying the data in the app. Using AppStorage with complex objects and SwiftUI Pickers? This was me building part of my settings the user can control in the app. 🎡 and 🎢 were in the example. Swift computed properties can be tuples? It’s how one section of my app deals with saved settings. I’ve been “kind of” building this app in public. 😏
Building something for yourself
These Tweets by Matthew Bischoff and Brian Michel really spoke to me.
💯 I’ve been deeply feeling the urge to build an app for myself since late last year, even if no one else uses it and it makes no money.
— mb (@mb) February 6, 2022
Just making something small and custom and beautiful for yourself and/or your friends can be so rewarding. https://t.co/6nRmnOSKvP
I built this app for myself and some family and friends. The functionality is super basic. The target audience is probably tiny. All of that is just fine! I learned a ton writing this app and now I have another app on the App Store. That’s a win-win as far as I’m concerned. If you’re trying to think of an idea for an app that is for enjoyment and learning I’d recommend focusing on something that really interests you. Who cares if there are many similar apps already? Put your own spin on things and go for it. When you’re interested in the project it makes it easier to go back to it when you’re having hard days. I think those hard days might be an interesting blog post in the future.
Conclusion
If this post was helpful to you I’d love to hear about it! Find me on Twitter.