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:
CleanShot.2023-03-26.at.13.29.29.mp4
Untitled.mov
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.
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.
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.
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.
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:
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!
I tried ChatGPT with some basic project setup questions and it was helpful:
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.
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!
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.
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!
Later on for the iOS app, however, ChatGPT was way off:
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.
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:
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.
This was too much work so I added a random rate (actually duration) offset and moved on.
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.
ChatGPT successfully taught me about timers in Swift.
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:
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.
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:
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:
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.
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...
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.
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.
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:
🤷
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:
- Most of the Swift code was written by ChatGPT 3.5
- The orb image and background images for the app and screnshots were made by Midjourney
- water bottle shaked.ogg by pbimal is the shaking sound
- Magic eight ball.png from Wikimedia Commons was used mostly as a placeholder
- Eight Ball 3D model from RoutineStudio via Sketchfab
- abstract ball 3D model by sonic art was used as a placeholder
- iOS & Android App Icon Template and App Store Screenshots from the Figma community
I couldn't find a usable, free magic 8-ball 3D model, so I used a nice regular 8-ball model.