A Magic 8 Ball App for watchOS & iOS – Mostly Generated by ChatGPT

I wanted to try learning a new topic and building a relatively simple project using ChatGPT as a coding assistant. Before starting this project, I had no prior knowledge of Swift and my last time doing iOS development was 2013. I wanted to see if ChatGPT could teach me to build a simple app for iPhone and Apple Watch and it did.

The final result after a total of ~10 hours of hacking — Yes, the animation is awful, but I think I’ve done enough for now:

I’m not particularly obsessed with magic 8-balls — it just seemed like an easy thing to make with some fun polishing edge cases. Here’s a video if you’re wondering what’s inside one.

Summary

While “peer programming” with ChatGPT I found it to be about 75% useful. While not always giving me correct or up-to-date code, it successfully taught me the bits of Swift I needed and gave me solutions to the high-level problems I described. It wrote code for me that eventually worked after some amount of fixing (like casting types) or explanation (like asking it to give me an implementation of a function it referenced. Even when its code wasn’t right, it gave me ideas to google for, which was much more time-efficient than digging through docs hoping to stumble across a breakthrough.

Overall, this feels like having a superpower. ChatGTP is like a mostly-knowledgable coworker telling me what to do (although sometimes getting it wrong) and saved me many hours of learning on my own.

Development Log

Here’s an abridged list of the ChatGPT questions I asked in rough chronological order. All of it was in a single ChatGPT chat. I also had to ask a lot of clarifying questions or sometimes would ask it things instead of googling. These are the most notable bits.

Background Knowledge

I started by making sure ChatGTP knew what a magic 8-ball was. No problem there. It all sounds right but I never bothered to check its accuracy with Wikipedia.

CleanShot 2023-03-26 at 13 50 17

Scaffolding the Watch App

I hadn’t used Xcode in years, I had no knowledge of Swift, and I only started wearing an Apple Watch a few months ago. So I needed to start from the beginning.

I asked it to tell me how to build an Apple Watch app that would show one of these random messages. Remember, this stemmed from the conversation about the magic eight ball, so it already had some context:

CleanShot 2023-03-26 at 21 25 01

It gave me Objective-C instructions at first, but then I told it I wanted to use Swift, and we were off. All of this worked and I had a working watch app that I could tap to display a random message. This was very promising and I was excited!

CleanShot 2023-03-26 at 13 50 48

I tried ChatGPT with some basic project setup questions and it was helpful:

CleanShot 2023-03-26 at 13 53 32 CleanShot 2023-03-26 at 13 53 41

Feature: Add a delay before showing the message

At the beginning of the project my knowledge of iOS and Swift was practically non-existant. It took me a lot of time to understand animations, threads, timers, contexts, and Swift closures. I wanted the message to appear after a delay and that took a lot of work to undestand. ChatGPT was helpful with generating code, but not helpful in teaching me about SwiftUI or whatever alien planet iOS/watchOS appears to have turned into.

CleanShot 2023-03-26 at 13 56 12 CleanShot 2023-03-26 at 13 56 32 CleanShot 2023-03-26 at 13 56 41 CleanShot 2023-03-26 at 13 56 52

Feature: Play a watery gurgling sound

If you’re shaking a container with liquid in it, it should sound like that, right? So I grabbed something that sounded approximately right, trimmed and faded it with Audacity, and exported it as.. wait, what formats are supported by Xcode? Let’s ask!

CleanShot 2023-03-26 at 13 58 15

Coding this was painful. First, ChatGPTs suggestions were out of date, then it was unclear to me where in the lifecycle I should be initializing things and setting up the player and whatever else I’m supposed to do.

CleanShot 2023-03-26 at 13 58 05 CleanShot 2023-03-26 at 13 58 22 CleanShot 2023-03-26 at 13 58 29 CleanShot 2023-03-26 at 13 58 44

Feature: Let me shake the watch to reveal an answer

Picking a random element from an array and displaying it in a Text view after being tapped was easy. But I wanted to shake my watch like a magic 8 ball and get a new mystical response. The watch has a gyroscope so this should be possible.

ChatGPT nailed this by creating the motionManager and checking the magnitude of the motion. And it added it by adding it to (what it thought was) my existing code!

CleanShot 2023-03-26 at 14 02 16 CleanShot 2023-03-26 at 21 36 08

Later on for the iOS app, however, ChatGPT was way off:

CleanShot 2023-03-26 at 21 37 55 CleanShot 2023-03-26 at 21 38 03 CleanShot 2023-03-26 at 21 38 08 CleanShot 2023-03-26 at 21 38 11 CleanShot 2023-03-26 at 21 38 42 CleanShot 2023-03-26 at 21 38 51

As far as I know, there’s no such thing as ShakeGesture and googling didn’t turn up anything. Hrmph. I ended up googling someone else’s solution.

Feature: Animate the eight ball

Hearing the water slooshing sound but not seeing anything move felt a little lifeless. So I wanted the eight ball image to jiggle a little when you asked for a new response.

There was a lot of back and forth here and I started to get a little frustrated. There were probably ~15 back and forths with ChatGPT and three times I said something like “OK, forget all that, let’s try again. Here’s my code.” Finally a breakthrough:

CleanShot 2023-03-26 at 14 08 26 CleanShot 2023-03-26 at 14 08 37 CleanShot 2023-03-26 at 14 08 42

Feature: Add some random variation to the sound

Usually you want to add some variation to a sound if you’re hearing it a lot so it doesn’t sound robotic. Usually adding a little bit of random pitch offset helps. I asked ChatGPT, but it’s responses were way off, and it made me go down a wrong path of trying to use AVAudioUnitTimePitch, which isn’t available on watchOS. It’s explanation of audioPlayer.rate is wrong and contradicts the explanation in the official docs.

CleanShot 2023-03-26 at 14 09 43 CleanShot 2023-03-26 at 14 10 58

This was too much work so I added a random rate (actually duration) offset and moved on.

Bug: Apple Watch coding is difficult

Dealing with activation/deactivation on the watch was annoying. I eventually scrapped the code, added lots of print()s, and at this point read Learn X in Y Minutes (where X=Swift) to try and learn things. ChatGPT gave me lots of ideas, so I spent a lot of time googling again. At least I was given some ideas of what to Google.

CleanShot 2023-03-26 at 14 12 47 CleanShot 2023-03-26 at 14 13 33

Bug: Timers

ChatGPT successfully taught me about timers in Swift.

CleanShot 2023-03-26 at 14 13 13

Feature: App Store marketing copy

I don’t really plan on spending $99 to put yet another magic eight ball app on the App Store. But I was thinking about all the screenshots and copy you need to make an app look presentable, so I enlisted ChatGPT’s help here.

I found a good Figma template for App Store screenshots and asked ChatGPT for some copy. Since it already had plenty of context from the conversation, this was perfect:

CleanShot 2023-03-26 at 14 15 23

Nice. Switch over to Midjourney fro some fortune telling background and some kind of, I dunno, weird “eight balls in space” kind image for the marketing background? Who really looks at that stuff? It just needs to be eye-catching. I think. I’m not an expert.

CleanShot 2023-03-26 at 21 56 28 CleanShot 2023-03-26 at 21 56 45 image

Scaffolding the iOS App

The watch app eventually felt good enough, and I had an itch to add a really cool 3D magic eight ball to the iOS version, which I knew could embed 3D models. So it was time to let ChatGPT write the iOS app, but first I wanted some instructions:

CleanShot 2023-03-26 at 21 59 27

Gah, this turned out to be all wrong. Xcode was angry. I gave up, copied the watchOS View, and deleted stuff until it worked on iOS.

Follow-up questions were where ChatGPT really helped. All of this seemed googleable, but this is where it really felt like peer programming. I just wanted someone (or something) to tell me the right thing to do:

CleanShot 2023-03-26 at 22 04 39 CleanShot 2023-03-26 at 22 04 49

Feature: Shake gesture on iOS

As mentioned earlier, ChatGPT gave me a lot of wrong info here, eventually making up something called ShakeGesture, which doesn’t seem to exist. Eventually I googled around and found a solution that was simple and seemed much more up to date than anything ChatGPT was generating.

CleanShot 2023-03-26 at 14 19 52 CleanShot 2023-03-26 at 14 19 59 CleanShot 2023-03-26 at 14 20 05

Feature: Fixing the text

I had no idea how to lay out text and make it bigger and whatnot. ChatGPT was super helpful here and I was able to continually ask it to tweak my code. This was one of my favorite parts of using ChatGPT because it felt like it was talking to an expert — or at least someone who had read a million tutorials and documentation pages…

CleanShot 2023-03-26 at 20 35 30 CleanShot 2023-03-26 at 22 12 19

Feature: 3D Eight Ball

I found an eight ball model on Sketchfab and asked ChatGPT what to do next. It was spot on, with one exception — ChatGPT said to use formats “such as” Collada and Alembic, so I was looking for Collada models. I didn’t know until now that not only does SceneKit work great with USDZ models, but that USDZ was actually an Apple and Pixar invention, and everything on Sketchfab gets converted to USDZ automatically.

CleanShot 2023-03-26 at 22 16 13

Unfortunately, after this I had a lot of trouble figuring out SceneKit. ChatGPT wasn’t very helpful here since this was a combination of my Swift/SceneKit inexperience and just general difficulty with APIs. For example, things I thought were problems with the model ended up being problems with my initialization and code paths. It was plain old debugging and code sleuthing for a while.

Feature: Animate the eight ball

What I wanted but didn’t get was some kind of shake or rotation animation that jiggled the eight ball and let it settle back to its origin position. That would have been cool, right? But no matter how hard I tried, I couldn’t get anything good working.

ChatGPT got me really close, though, and with more time I could probably turn it into something, but my effort and motivation has hit its limit. ChatGPT gave me a lot of things involving rotation and scale, but none of them did exactly what I wanted, or they kept doing the animation backwards for some reason, and switching the from: and to: parameters didn’t seem to work. ChatGPT was pretty wild here, and for a while it would give me an entirely different solution every time I asked, and many of the the solutions were incomplete and used made-up functions. I learned a lot but didn’t achieve my goal.

Some examples:

CleanShot 2023-03-26 at 20 41 11 CleanShot 2023-03-26 at 20 41 19 CleanShot 2023-03-26 at 20 41 38

?

Addendum: Midjourney

I used Midjourney to create some assets — I wanted an interesting background for the app like a fortune telling parlor, some kind of weird mystical background with eight balls for the hypothetical app store listing, and I really wanted just a royalty-free magic eight ball image with the blue upside-down triangle for the watch app which can’t use a 3D model.

Unfortunately, I simply couldn’t get a good magic eight ball image generated, or at least one with the triangle the way I wanted (like ▼ not ▲). So I took the best one it made, removed the background with removal.ai, and trimmed transparent pixels with Photopea.

Here are highlights with my progress there along with some of my favorite things that Midjourney came up with:

CleanShot 2023-03-26 at 20 45 07 CleanShot 2023-03-26 at 20 45 19 CleanShot 2023-03-26 at 20 45 30 CleanShot 2023-03-26 at 20 45 40 CleanShot 2023-03-26 at 20 45 58 CleanShot 2023-03-26 at 20 46 04 CleanShot 2023-03-26 at 20 46 09 CleanShot 2023-03-26 at 20 46 25 CleanShot 2023-03-26 at 20 46 43 CleanShot 2023-03-26 at 20 46 53 CleanShot 2023-03-26 at 20 46 59 CleanShot 2023-03-26 at 20 47 05 CleanShot 2023-03-26 at 20 47 17 CleanShot 2023-03-26 at 20 47 25 CleanShot 2023-03-26 at 20 47 33 CleanShot 2023-03-26 at 20 47 41 CleanShot 2023-03-26 at 20 47 50 CleanShot 2023-03-26 at 20 47 55 CleanShot 2023-03-26 at 20 48 02 CleanShot 2023-03-26 at 20 48 06 CleanShot 2023-03-26 at 20 48 20

Credits

I couldn’t find a usable, free magic 8-ball 3D model, so I used a nice regular 8-ball model.

GitHub

View Github