blog.iankulin.com

Posts

SwiftUI provides

After nearly shelving my SwiftUI tickets app over concerns that exporting tickets was beyond my expertise, I discover an iOS 16 feature that makes the task straightforward, plus existing code examples for rendering SwiftUI views to PDF. The post reflects on the lesson of investigating before assuming something is hard, and notes remaining work on layout and share behaviour...

Committed

A reflective look at my GitHub commit graph, noting that Tuesday nights are unexpectedly my most productive coding time and expressing my appreciation for git and GitHub’s free tier. My first commits date to July 10, the same month I started blogging daily, a streak now at 154 days. I’m on day 64 of 100 Days of SwiftUI, admitting the hour-per-day pace hasn’t held, but I’m pleased with my overall commitment...

Ticket to ride

This is a progress update on my SwiftUI behaviour ticket app. Rather than the eventual goal of rendering tickets to PDFs or images for a share sheet, I cover exporting ticket data as a CSV text file, using a FileDocument struct adapted from Paul Hudson and SwiftUI’s fileExporter modifier, with code included...

Pi Server

My two Raspberry Pi 3Bs serve as an AllStar radio node and a small web server running Node.js, PHP, and MySQL, with Pi-hole recently added to block ads network-wide. I also weigh whether the Pi shortage makes a repurposed laptop or refurbished mini PC a better choice, considering setup effort and idle power draw...

Towards MVVM

Prompted by a Fireside Swift episode on SOLID principles and the arrival of Core Data in the 100 Days of SwiftUI course, I reflect on when architecture should enter an iOS developer’s toolkit. Drawing on a long-standing habit of wrapping external dependencies for easy replacement, I conclude that scalable code suits real apps but not learning—which is likely why Paul Hudson defers architecture until later in the course...

Deep Linking

After listening to a podcast episode about NFC tags, I look at using them for home automation but find an iPhone SE2 can only read NFC inside an app rather than in the background. A digression covers my past experience with injectable RFID tags in emus, and I close the post with some resources on deep linking in iOS, covering both UIKit and SwiftUI...

Project Based Learning

Reflecting on podcast advice that building a real app beats endless tutorials, I share what a day and a half of working on my own SwiftUI project turned up in my search history, covering topics like Core Data filtering, file exports, date formatting, and NavigationView quirks. The experience supports the podcasters’ point: a real app forces you to push through hard problems you would otherwise sidestep when just noodling around...

Regex to split a string with two different characters

A walkthrough of using Swift 5.7’s regex support as the separator argument to String.split(), in order to parse a string like “Some behaviour (expectation)” into its two parts. I build the expression up step by step, covering escaping of brackets and spaces and the use of the pipe for OR, and note that the Playgrounds app doesn’t yet support Swift 5.7...

Copying a file via SSH

I copy a sample JSON file from my Mac to a Raspberry Pi on the home network using the scp command, after noting that drag-and-drop into an SSH session isn’t possible. I include the basic command syntax with a brief explanation of its arguments...

Mock Data

Needing mock student data for an iOS app without using real records, I try Mockaroo, a web-based test data generator with configurable field types and download options including JSON and a REST API. My writeup ends with a privacy caution that schemas saved on the service are publicly visible...

Tickets on Myself

My habit tracker app, built as a JSON tutorial exercise with UserDefaults persistence, has motivated me to tackle a more substantial Core Data app for teachers to record student reward tickets. I outline the planned design with Tickets and Students entities, searchable student records, and categorised ticket types. Outstanding data problems include importing student and category data via JSON from a local school webserver, and exporting records as PDF or text files...

FriendFace 61 Feedback

I compare my attempt at a Core Data caching challenge—storing fetched user data so the app can still display it after network failures—against Paul’s model solution. Differences covered include adding a merge policy for handling constraint conflicts, keeping ids as UUIDs, and placing MainActor.run inside the network fetch rather than after it...

61 Done

I complete Day 61 of #100DaysOfSwiftUI, decoding JSON and backing it up into a Core Data graph for display. I get stuck on one:many relationships and an id type mismatch, plus some unexplained Core Data console warnings that linger despite the app working...

Core Data basics – Part Three

In part three of my Core Data basics series, I show how to add a one-to-many relationship so each Garden can have multiple Plants. I cover converting the generated NSSet of related plants into a sorted array via a computed property, displaying the plants in a list in the garden detail view, and linking plant instances to a garden when creating sample data...

Core Data basics - Part Two

Part two of my series on Core Data basics, in which I convert a SwiftUI master/detail garden-list app from structs to Core Data. I walk through defining entities in the Xcode data model, generating editable NSManagedObject subclasses, setting up a DataController with NSPersistentContainer, and fetching and saving data with @FetchRequest. I defer one-to-many relationships to the next part, and I draw much of the code from Paul Hudson’s 100 Days of SwiftUI...

Core Data basics - Part One

In the first part of my series on learning Core Data basics, I build a simple SwiftUI master/detail app that lists gardens and their plants using structs and arrays, as a starting point before converting it to Core Data in later parts. My code draws heavily on Paul Hudson’s 100 Days of SwiftUI course, with a GitHub link to the source...

Something weird 'append

A debugging story about a SwiftUI master/detail list where every row displays the first record’s data. While preparing to replicate my app in Core Data, I work through Swift’s value-type semantics, a Playground experiment, and print debugging before finding the real cause: mutating and reusing a single struct created duplicate UUIDs that broke ForEach, despite a console warning early on...

Tough Day

Day 61 of the 100 Days of SwiftUI course presents a Core Data challenge that exposes gaps in my understanding, leading me to write out my current mental model of Core Data — object persistence, data models, code generation, and managed object contexts. Rather than push ahead, I plan to build a simple comparison of array-based storage versus Core Data before redoing the challenge...

iOS 16 Developer Mode

After updating my iPhone to iOS 16, I found my app would no longer run until Developer Mode was enabled. I briefly cover where to find the setting (in Privacy and Security) and note that it requires a reboot and re-authentication...

iOS Dev Twitter

I reflect on following iOS and Swift developers on Twitter, a habit I picked up from Sean Allen’s advice that became an enjoyable way to discover resources like iOS Dev Weekly and developers like Erica Sadun. I also consider the sense of community in iOS Dev Twitter, noting that despite Twitter’s broader problems, it enabled such groups to form and thrive...