blog.iankulin.com

Xcode14

Moonshot Challenges

My solutions to the three wrap-up challenges for the Moonshot app from the 100 Days of SwiftUI course, an information app about the Apollo missions. My work covers displaying formatted launch dates, extracting the crew view and a custom divider into separate structs, and adding a toolbar toggle between grid and list mission layouts, with some notes on the tradeoffs of splitting views out...

iExpense Feedback

I compare my iExpense SwiftUI challenge solutions against Paul Hudson’s, covering preferred-currency formatting, styling expense amounts by value, and splitting the list into personal and business sections. After investigating why my ForEach-based split deletes the correct item despite warnings about offset mismatches, I find that SwiftUI’s onDelete already passes correct array indexes and conclude that my approach beats Paul’s filtered-array solution...

SwiftLint

Prompted by a video on effective developer habits, I finally add a linter to my Swift workflow. I cover installing SwiftLint and hooking it into Xcode builds, adjusting rules via a swiftlint.yml config file, and selectively disabling rules with code comments. My approach is to enable all optional rules up front, then decide for each violation whether to change the code or drop the rule...

Testing, testing

A walkthrough of adding unit tests to an existing Swift project in Xcode, using my CodeTrimmer macOS utility as the example. I cover adding a unit testing target, writing XCTest functions for the stripSpaces() method, and running the tests to see the results...

Where's My App?

My short guide to building a release version of a macOS app in Xcode and finding the resulting .app bundle. I cover creating a new scheme set to Release builds, running the build, and using “Show Build Folder in Finder” to locate the .app file so it can be copied into the Applications folder...

Customizing the default About dialog for MacOS apps

A short how-to on how I customize the default About dialog in a macOS app built with Xcode: add a Credits.rtf (or .html or .rtfd) file to the project, and its contents appear in the dialog after a rebuild...

CodeTrimmer - First MacOS App

Inspired by a StackTrace podcast episode about automating small development tasks, I built my first macOS app with SwiftUI: a utility that strips excess leading indentation from code copied out of Xcode, a chore I previously did by hand before pasting code samples into my blog posts. Screenshots show the paste-and-strip workflow, and I found the move from SwiftUI iOS development to macOS nearly effortless. My source code is linked...

Design Challenge

I give a progress update on translating an external designer’s UI into SwiftUI, covering the rounded-rectangle elements I’ve completed and the .offset modifier I used to create an overlapping layout. My remaining work includes a custom picker and a combined picker/progress indicator...

iExpense Challenges

Day 38 of my 100 Days of SwiftUI challenge covers three exercises on the iExpense app: showing amounts in the user’s preferred currency (navigating a deprecated Locale API), applying conditional styling based on expense value, and splitting the expense list into personal and business sections. The list-splitting required me to wrap conditionals in a Group to satisfy the compiler’s ViewBuilder type checks...

Times Tables -Day 35 Challenge

My write-up of the Day 35 challenge from 100 Days of SwiftUI: building a times tables drilling app. I cover creating a custom number keypad and replacing the standard iOS modal with a ZStack-based overlay, finding that tap events pass through very transparent overlays but not more solid ones. I also note the finished app is plain-looking and that improving visual design is now a goal...

Gitting Xcode to Push

I explain how to fix Xcode failing to push to GitHub after GitHub stopped accepting RSA keys that use SHA-1. My solution, based on an Apple Developer forum answer, is to switch to a new ECDSA SSH key — with the one step the forum post missed being a restart of Xcode to make it take effect...

User Defaults & Horizontal Pickers

Day 35 of the 100 Days of SwiftUI challenge, which I spent building a multiplication tables drill app for kids. I cover persisting the user’s table selection with UserDefaults (including an enum to avoid hard-coded key strings and a fallback for missing values), plus a Stack Overflow trick for building a compact horizontal wheel picker using paired rotationEffects...

Animating Guess The Flag

This is a write-up of Project 6 of 100 Days of SwiftUI, which adds animations to the earlier Guess the Flag app. The tricky part was that all three flags are built in a ForEach, so animations applied to every button at once; the fix was storing each flag’s animation magnitude separately and animating unclicked flags by zero. I also cover re-animating the flags once the alert closes, along with my criticism of the tutorial’s alert UI...

Animations in Views

A short walkthrough of three ways to animate SwiftUI views, written as part of my progress through the 100 Days of SwiftUI series: implicit animation via the .animation() modifier, animation bound to controls like sliders, and explicit animation for coordinating simultaneous changes. Each approach is illustrated with example code and a demo video...

Don't Use Stupid Project Names

While working through Day 32 of 100 Days of SwiftUI — Project 6, a set of animation tutorials rather than a full app — I name a new Xcode project “Project 6 - Animation” and hit seven build errors caused by an unreplaced ___PACKAGENAME macro. Renaming the project without the dash fixes it, and since a web search turned up nothing, I include the exact error message for anyone else who names projects with dashes...

Recording the Simulator

A short note in which I replace QuickTime-based screen recordings with the iOS simulator’s built-in recording, which captures gestures and exports animated GIFs. The technique comes from a linked post by Sarun W...

Changing Xcode Font Size

Here’s a short tip on changing the code font size in Xcode: rather than adjusting each content type manually through the themes preferences, I use Ctrl + Plus and Ctrl + Minus to increase and decrease the font size directly...

Project 5 - Word Scramble

I built a Scrabble-like word game as a 100 Days of SwiftUI project. I cover bundling a large text file and loading it into an array at view launch, plus a brief detour into UIKit to use UITextChecker. My source code is on GitHub...

Word Scramble Feedback

After finishing the Word Scramble challenges in Hacking with Swift’s 100 Days of SwiftUI, I review Paul Hudson’s subscriber-only solution and pick up two improvements. The first is a clearer way of resetting the used-words array; the second replaces my bottom-toolbar score display with a safeAreaInset that initially seemed overcomplicated but looked better in practice...