blog.iankulin.com

Xcode14

Sharing is caring

Continuing my SwiftUI demo project, I use ShareLink to let users share a view rendered as an image via the standard share sheet, with SharePreview supplying the thumbnail and title. I also cover adding the Photo Library Additions usage description so a Save Image option appears, along with the permission prompt users see on first use...

Console spam - No wall clock alignment

A debugging session traces a recurring console message in my SwiftUI app, “No wall clock alignment provided,” to the .date style when formatting dates in a Text view. I reproduce the issue with a minimal code snippet, find little documentation online beyond an old Reddit thread, and file my first Radar bug report with Apple...

FriendFace

A write-up of my Day 60 milestone challenge in the 100 Days of SwiftUI course: I build a small app that fetches a JSON file of users, decodes it into Codable structs (including ISO-8601 dates), and displays them in a list with a detail view. I share my fetch and view code, note some friction with nested do/catch error handling, and add profile pictures via AsyncImage, deciding against implementing image caching in order to keep the challenge simple...

Project 12 Challenges

My solutions to the three wrap-up challenges from Project 12 of the Hacking with Swift SwiftUI series, which involve a FilteredList subview whose @FetchRequest is built dynamically in its initializer. The tasks add a predicate format parameter, replace the hard-coded predicate string with an enum using raw values, and support an array of SortDescriptor objects...

Bookworm Feedback

I compare my SwiftUI solutions to a coding challenge series with Paul Hudson’s, finding the first two nearly identical and only minor differences on the third. I weigh hiding text with opacity to reserve space against using an if-let, and note that Hudson’s abbreviated date formatting handles locale differences my manual approach didn’t...

Bookworm Challenges

My solutions to the Project 11 challenges from the 100 Days of SwiftUI course, applied to Bookworm, a CoreData-based book tracking app. I add validation so books can’t be saved without a title or author, highlight one-star ratings in the book list, and add a date attribute to the Book entity that’s formatted in the detail view...

CoreData and the Preview

My CoreData project from Day 53 of the 100 Days of SwiftUI course ran fine in the simulator but crashed in Xcode’s SwiftUI preview, which lacked a managed object context. I describe a workaround I found on the Hacking with Swift forums for supplying a context to the preview...

Cupcake Corner Feedback

A comparison of my solutions to Paul Hudson’s for a SwiftUI challenge covering address validation, alerts for failed POST requests, and wrapping a struct in an observable class. I find Paul’s String extension approach to whitespace checking neater than my brute-force version, and I highlight Paul’s use of @dynamicMemberLookup with key paths to shorten chained property access like order.data.street down to order.street...

Cupcake Corner challenges

My solutions to the day 52 challenges for the Hacking with Swift Cupcake Corner app: trimming whitespace before validating the order address, showing an alert when the order submission to the API fails instead of just printing, and converting the Order class to a struct inside an ObservableObject wrapper to eliminate the manual Codable code. I present each change with Swift code snippets and links to the corresponding GitHub commits...

Day 50 - @State vs @Observed again

I revisit my ongoing confusion between SwiftUI’s @StateObject and @ObservedObject property wrappers. A tutorial video states the standard rule — @StateObject where the object is created, @ObservedObject everywhere else — but I note that my MVVM app still worked with @ObservedObject on the single data model instance. Attempting to resolve this, I use Xcode’s jump-to-definition to compare the wrappers and find an extra Wrapper struct in @ObservedObject’s implementation, which I set aside to revisit later...

Day 47 - Habits App

I wrap up my Habits app as an MVP, the first of my own apps I have actually installed on my phone, after 120 days on the 100 Days of SwiftUI course with only day 47 completed. Possible future features include setting habits due at a specific time, like 6pm, rather than a fixed interval after the last completion. A growing backlog, including a custom picker for a times table app, remains deferred...

Why?

In this short post, I ask why the Xcode preview window has to be resized every time it opens, with the answer provided as an embedded YouTube video...

JSON encode/decode

Progress on my SwiftUI habit tracking app built for the 100 Days challenge, covering UI refinements like a fading checkmark and the shift from simulator testing to daily use on a real iPhone. Persistence uses Swift’s built-in JSON encoding with UserDefaults, which works well until the struct changes — I discuss the resulting decode failures and the lack of a simple way to decode missing properties using default values...

Refreshing SwiftUI Views

Ways to force a SwiftUI view to redraw, demonstrated with a sample app that tracks a list of cars and their counts. The core technique is toggling a @State property that gets passed into subviews, which I then trigger via pull-to-refresh with .refreshable(), on app activation by watching scenePhase with .onChange, and on an interval with a published Timer and .onReceive...

You need to enjoy puzzles

After converting a SwiftUI subview from a function to a struct, list items in my habit list app stopped updating correctly. Suspecting a value versus reference type issue, I distilled the problem into a minimal ObservableObject example, only to find that both the example and the original app now worked. The post walks through the code and the debugging process but ends without an explanation of what caused or fixed the bug...

Purple warning - "Publishing changes"

I hit SwiftUI’s publishing changes from within view updates purple warning in Xcode 14 when a button in a list updates a model, and after research I conclude it’s likely an Xcode bug rather than a code mistake. Adding a button style modifier silences the warning as a temporary workaround, with newer Xcode versions possibly fixing the issue...

Drawing Feedback

I compare my solutions to the Project 9 drawing challenges from Paul Hudson’s 100 Days of SwiftUI course, covering an Arrow shape, making its shaft width animatable using AnimatableData, and a ColorCyclingRectangle with a controllable gradient. My closing aside considers whether to use US or UK spellings like “color” in Swift code...

Project 9 - Drawing

This is my #100DaysOfSwiftUI journal entry covering days on custom drawing: paths, shapes, transforms, ImagePaint, drawingGroup with Metal, blurs, blend modes, and animatableData. I walk through the challenge solutions, building an Arrow shape with animatable line thickness and a ColorCyclingRectangle whose gradient endpoint is controlled by sliders, and I note the lesson I learned from not using git for scratch code...

When it Works

A short reflection on what makes coding enjoyable: the steady stream of small problems to solve on the way to a bigger goal. I note the urge to build a simple drawing app hits in every new language I learn, from Visual C++ and MFC to SwiftUI...

Moonshot Feedback

A comparison of my SwiftUI solution to the Hacking With Swift Moonshot challenge against Paul Hudson’s, covering choices like whether to extract sub-views into separate files and using a List versus a ScrollView with HStacks. The key difference I discuss is a toolbar toggle built with a Button instead of an Image with a tap gesture, since using standard controls as intended gives screen readers the information they need for accessibility...