What is a JSON feed? Learn more

JSON Feed Viewer

Browse through the showcased feeds, or enter a feed URL below.

Now supporting RSS and Atom feeds thanks to Andrew Chilton's feed2json.org service



Recent content on TrozWare

A feed by Sarah Reichelt


SwiftUI for Mac 2022

Permalink - Posted on 2022-06-17 04:18

In December 2019, I wrote a series of articles about using SwiftUI to build a Mac app. And in July 2020, I re-visited the sample app to apply the new SwiftUI features made available in macOS BigSur. Now that macOS Ventura and Xcode 14 are in beta, it’s time to build the app again while learning how to incorporate the new APIs.

Right now, it’s June 2022 and I’m using macOS Ventura 13 beta 2 (22A5286j) with Xcode 14 beta 2 (14A5229c). There will undoubtedly be changes before release, but I’ll try to update this article or add notes to point out any major differences.

I don’t intend to cover features that haven’t changed much, but here are the new APIs that I am interested in:

Note: In Xcode 14 beta 2, the SwiftUI Previews are crashing unless I go to Project > Target > Signing & Capabilities and select my developer team and set Signing Certificate to Development. So if you can’t see the Previews, make these changes, or run the app directly.

The first version of this app used a two pane layout with a sectioned list in the sidebar leading to a detail view in the main area. With the Big Sur version, I switched to a three pane layout because the sections were not displaying neatly. This time, I’ve reverted to two panes with sections. As before, I’m using HTTP Cats which is a site that serves up a cat image to match almost every HTTP status code.

Previous versions used NavigationLinks inside a NavigationView. NavigationView is now deprecated and we should use either NavigationStackView or NavigationSplitView. NavigationStackView is better suited to a small screen where each view is pushed on to a stack and can be popped off to navigate back. I am going to use NavigationSplitView which works well for bigger displays with all the panes visible at once.

My data model is exactly the same as I developed originally and consists of an array of HttpSections, each containing an array of HttpStatuses. So I was able to render my navigation like this:

NavigationSplitView {
  List(httpSections, selection: $selectedStatus) { section in
    Section(header: Text("\(section.headerCode) - \(section.headerText)")) {
      ForEach(section.statuses) { status in
        SidebarRowView(code: status.code, title: status.title)
  .frame(minWidth: 250)
} detail: {
  DetailView(sectionTitle: sectionHeader, httpStatus: selectedStatus)

The NavigationSplitView takes various parameters, depending on the result you want. In this case, the first parameter lays out the sidebar, which is a List. The detail parameter contains the detail view. For the List, I loop through the sections, adding a section header for each one and a custom SidebarRowView to display the individual status entries. The List selection is bound to an optional HttpStatus. The key here is to give each row a tag that maps to the status displayed in that row. If you omit the tag, the sidebar draws but none of the entries are selectable.

Interestingly, when you create a navigation setup like this, Xcode automatically adds a toolbar with a button to toggle the sidebar. This has always been essential as there is a long-standing bug where a hidden sidebar cannot be dragged back into view. But adding it manually meant digging into AppKit to find a method to call.

Not so interestingly, the sidebar is often hidden on app launch. I tried giving NavigationStackView its optional columnVisibility parameter, but no setting made it appear consistently.

With the detail, right now there is a bug where you cannot unwrap a conditional and show a view based on that. One workaround is to wrap the entire detail in a ZStack, but in the interest of keeping my ContentView code simple and as short as possible, I added an intermediary view. DetailView takes optional parameters and it decides whether to show the StatusView or a placeholder. Note: the bug may have gone in beta 2, but as I want to display other UI elements in the detail view anyway, this is still a neater approach.

There is nothing much new in either of these views, except where StatusView downloads the selected cat image. I tried using AsyncImage which worked really well except for one problem. When I selected a new status, the old image stayed in place until the new one arrived. I was unable to work out how to clear or reset an AsyncImage so it would show its placeholder again.

Update: Thanks to @ramzesenok who pointed out that this is another case where I could use an id to force a refresh. So now, the app uses AsyncImage which makes for a lot less code.

AsyncImage(url: httpStatus.imageUrl) { img in
  CatImageView(catImage: img, statusCode: httpStatus.code)
} placeholder: {
.id(httpStatus)   // this resets the AsyncImage whenever httpStatus changes

If anyone is still interested in the async/await version, check out this earlier commit on GitHub. It does appear to have better/faster caching, but a beta is not the right place to make speed assessments.

However I did switch to using async/await to download the image.

Updating this was also slightly complicated. I downloaded the first selected image using a task modifier and downloaded subsequent selections using an onChange modifier. Both of these were required to show the image every time.

Thanks to @davbeck, @malhal and @chriseidhof for pointing out that if I gave the task an id, it would be called whenever the id property changed.

The previous image is first set to nil, so that the progress indicator appears.

With all this in place, I had the basis of the app and the navigation was complete:


Detecting the Active Window

macOS apps can have multiple windows open at once, and in previous iterations of SwiftUI, it has been difficult to detect the active one. Last year, we got @FocusedBinding but it didn’t really work. This year it works, but we also have a new EnvironmentValue called controlActiveState.

As I did last time, I set up some menus by adding a commands modifier to my WindowGroup in the main _App.swift file. First, I added the pre-built SidebarCommands() which added a menu item and keyboard shortcut for toggling the sidebar. Next, I added a menu item for flipping the image:

CommandGroup(after: .textEditing) {
  Button("Flip Image") {
    NotificationCenter.default.post(name: .flipImage, object: nil)

This new item appears in the Edit menu, after the standard items. It has a shortcut of Command-F. The Command key is the default shortcut modifier, so if you only specify a letter, it automatically uses Command. All this menu item does is to broadcast a notification.

The image is shown in a subview called CatImageView which now includes the following properties:

@Environment(\.controlActiveState) private var controlActiveState

private let flipImageMenuItemSelected = NotificationCenter.default
  .publisher(for: .flipImage)
  .receive(on: RunLoop.main)

@State private var imageIsFlipped = false

The image has a rotation3Deffect modifier with the angle set to either 0 degrees, or 180 degrees, depending on the value of imageIsFlipped.

The view subscribes to the flipImage notification and receives it like this:

.onReceive(flipImageMenuItemSelected) { _ in
  if controlActiveState == .key || controlActiveState == .active {

When the notification arrives, the code checks the value of controlActiveState. In my tests, this was always either key or inactive, but I saw that active was an option and added it too, in case it becomes relevant later. If the CatImageView is in the active window, it flips the image and if not, this notification is ignored.

Target Active Window

As you can see from the text in the images, only the front window image is flipped.

Opening New Windows

In early versions of SwiftUI, opening a secondary window was a very complex process. Read part 2 of the original series to see how I struggled with this. Later, we got an easy way to open a Preferences window, using a Settings scene. Preferences are now called Settings, which makes this nomenclature more logical.

Last year, we got the ability to use a NavigationLink as a SwiftUI menu item and this will open the destination view in a new window.

This year, we have a new method that uses another new EnvironmentValue called openWindow. First, in the _App.swift file, I added another new scene to the body - this time a second WindowGroup. A WindowGroup can be passed an id, a data object of a specific type, or both. In this case, I didn’t want to pass any data, so I gave it an id:

WindowGroup(id: "ui_samples") {

I want to display a window with a view demonstrating some UI elements. The view is called SamplesView, so I set this as the content of the WindowGroup.

To use it, I added a property to DetailView:

@Environment(\.openWindow) private var openWindow

And inserted a Button to call it:

Button("Show UI Samples") {
  openWindow(id: "ui_samples")

This opens a new window with the appropriate id. This can open multiple copies of the same window. If I had passed a data object to the window, it would have brought the window containing that data object to the front instead of opening a new window. To test this behavior, I changed the WindowGroup to this:

WindowGroup(for: String.self) { _ in

And changed the Button to:

Button("Show UI Samples") {
  openWindow(value: "samples")

Now the WindowGroup expects a String. When you pass a String that has already been attached to a window, that window is brought to the front. If you pass a different String, you get a new window.

After that, I realized that there was another scene type I could use. If you create a Window scene instead of a WindowGroup, not only does this become a single presentation window, but you get a menu item for it in the Window menu without any extra work. You can add a keyboard shortcut to the Window scene too. Supposedly, you can add default sizing and positioning, but they don’t appear to work yet.

Window("Samples", id: "ui_samples") {
.defaultPosition(.topLeading)  // doesn't work yet
.defaultSize(width: 600, height: 600)  // doesn't work yet


One of the signature features of SwiftUI at WWDC 2022 was the new Charts API. I have struggled with charts in the past, so this was very interesting. I need to learn more, but I added a simple bar chart to the samples window:

Bar chart

This charts the number of entries in each category of HTTP status. I drew a line across at the 8 value because drawing a marker line is a feature I have often needed in charts.

Creating the chart was smooth:

Chart {
  ForEach(chartData.keys.sorted(), id: \.self) { key in
      x: .value("Category", key),
      y: .value("Count", chartData[key] ?? 0)
    .foregroundStyle(by: .value("Color", key))

  RuleMark(y: .value("Threshold", 8))

Having assembled a dictionary of category codes and counts, I looped through the keys, setting an x and y value for each in its own BarMark. The line used a RuleMark.

To get the different colors, I added this modifier to the Chart:

  "1xx": .green,
  "2xx": .purple,
  "3xx": .blue,
  "4xx": .yellow,
  "5xx": .red

which was used by foregroundStyle to assign a different color to each of the categories.

Next, I wanted to add the ability to switch between vertical and horizontal bars. This requires swapping the x and y data so that y has the category and x has the count. After testing this manually, I added a Boolean to specify the orientation, and a method for returning the appropriate BarMark:

func barMark(for key: String) -> BarMark {
  if drawHorizontal {
    return BarMark(
      x: .value("Count", chartData[key] ?? 0),
      y: .value("Category", key)
  } else {
    return BarMark(
      x: .value("Category", key),
      y: .value("Count", chartData[key] ?? 0)

A similar method provided the RuleMark as either a vertical or horizontal line.

A segmented picker switches between the two and the only thing now was to animate the change. There is an animation modifier added last year that allows you to connect an animation to a property, so that when the property changes, the animation is triggered.

.animation(.easeInOut, value: drawHorizontal)

Animated chart

I added Text views for the title of the chart and for the axes, inside a VStack and an HStack, rotating the text for vertical axis. Maybe there is a chart setting that I’m missing for adding these labels automatically using the Chart library.

Image Rendering

While investigating charts, I experimented with another new SwiftUI feature: ImageRenderer. When I have made charts, I’ve often wanted to export them as images for upload. ImageRenderer allows us to convert a SwiftUI view into an image: on macOS, either NSImage or CGImage.

The first step was to convert the chart view plus its labels, into a variable (modifiers and RuleMark omitted from this code snippet for brevity):

let chartView = Group {
  Text("Status codes by category")

  HStack {
    Text(drawHorizontal ? "Category" : "Count").bold()

    Chart {
      ForEach(chartData.keys.sorted(), id: \.self) { key in
        barMark(for: key)

  Text(drawHorizontal ? "Count" : "Category").bold()

Then I displayed the view using the variable:

VStack {

  // Picker & Button

This left the display unchanged, but allowed me to use this variable to create a view for rendering, omitting the controls that should not be part of the image:

Button("Save Chart as Image") {
  let view = chartView
    .frame(width: 1200, height: 800)

  let renderer = ImageRenderer(content: view)
  if let exportImage = renderer.nsImage {

I added padding and frame modifiers to the view variable as it came out very small without this. Then I created an ImageRenderer using this view and converted it into an NSImage. The saveImage method uses an NSSavePanel to get a URL and then convert the NSImage to JPG data before writing it out. I used the same technique in part 3 of the original series but that only exported the downloaded image. This creates an image from a complete SwiftUI view.

I would be interested to try the SwiftUI fileExporter, but that’s for another day.

I also tried to use the new ShareLink to share this image, but couldn’t get that to work. The ImageRenderer seems to work asynchronously so that didn’t work well with ShareLink. Again, that’s for another day.


SwiftUI has always had a Form object, but the new System Settings app (previously System Preferences) has taken this to a new level. So I added some UI elements to a second tab in the UI Samples window.


There are a few interesting things here. Firstly, I achieved something I was unable to do last time and that is to make the text edit field have focus when the view opens. This was a three part operation:

Firstly, I added this property to the view:

@FocusState private var emailFieldHasFocus: Bool

Then, I added this modifier to the edit field:

TextField("Enter your email address", text: $email)

And finally, I set the Boolean property in the onAppear modifier:

.onAppear {
  emailFieldHasFocus = true

With this in place, the email text entry field had the focus whenever this view appeared.

The date picker is slightly confused. It can’t seem to decide whether it’s a graphical picker or a numeric picker, but it works. I haven’t tried the new date range picker yet.

With the check marks, I was trying to emulate the toggles in System Settings, where they are very small switches. I set the toggleStyle to switch which gave the right shape but it was big, like on an iPhone or iPad. The outermost form is set to use the columns formStyle. This lines up the labels and controls very neatly. But when I put the Toggles and Picker into an inner form with a style of grouped, I got the exact System Settings look I was going for.

As an aside, I love the way you can now apply control-specific modifiers to a container view and every appropriate view inside the container will use that setting. For example, I added .toggleStyle(.switch) to the Form view and it was applied to every Toggle inside it.

The final item in the form is a color picker. It opens up the standard macOS color picker and uses the selected color to fill the capsule beside it. The interesting thing is that the color has a gradient modifier. So you can see the faint gradient that is automatically applied to the shape.

Writing a menu bar app has previously required using AppKit to create a NSStatusItem. Now, we can add a MenuBarExtra scene to the app body to create a menu bar app component.

MenuBarExtra("HTTP Status Code", systemImage: "number.circle", isInserted: $showMenuBar) {
  MenuBarView(httpSections: $httpSections)

Setting the title without a systemImage shows the text as the menu bar title. when you specify a systemImage, the text is not displayed and the menu bar only shows the image.

MenuBarExtra takes an isInserted parameter, so you can turn it off and on. I added this to the app’s settings and stored it using @AppStorage.

I set up a new SwiftUI view that looped through the HTTP Status data and created a submenu for each category and set this as the MenuBarExtra view. This works and my menu bar component was functional. Selecting a status uses NSWorkspace to open the relevant documentation page at MDN.



2022 is an exciting year to be a SwiftUI programmer. Apple has made it very clear that this is the way forward and as early adopters, we have the ability to influence how the framework develops, so keep filing those feedback reports! There have been some great new features this year: navigation is better than ever, the platforms are unifying and macOS is not getting left behind.

The project from this article is available on GitHub. And as usual, I’d be thrilled to hear any suggestions, corrections or improvements. Please contact me using one of the links below or through the Contact page. And if you found this article, I’d love you to buy me a coffee.

Writing Setup

Permalink - Posted on 2022-06-17 04:08

If you read my blog or tweets, you will have detected that I recently wrote a book called macOS by Tutorials, published by raywenderlich.com. in this post, I’m going to show you what hardware and software I used to write it.


I use an 24 inch M1 iMac - yellow. I’ve always loved the form factor of the iMacs. They offer a superb monitor attached to a very good computer and the price is reasonable. My previous iMac used to make a noise like a kettle boiling when Xcode really got going, but this one is totally silent no matter what I do.

I’m a recent convert to a dual-monitor rig. I’ve always been content to use Spaces which provides virtual screens, and I still do that. But having the luxury of a second screen is great when you’re writing and previewing. My second screen is a Samsung C24F390 - a curved 24 inch display. The resolution isn’t anything like as good as the iMac, but I tweaked its settings to give as good a result as possible and I can’t imagine going back to a single monitor now.

My keyboard is an Ergodox Moonlander which I love. This is my first mechanical keyboard and I wasn’t sure if I’d like it, since I appreciated the low travel on my standard Apple keyboard. But I chose the Kailh Silver key switches which have the lowest travel and are the least clicky. It’s still quite noisy, but the travel was not an issue. The configuration options are amazing. It took several iterations, but I now have a keyboard layout that works really well for me. And I keep my Apple keyboard tucked under my monitor stand so the Touch ID button is in easy reach.

For a pointing device, I have the Logitech MX Vertical Ergonomic Mouse which is very comfortable to use and charges via USB-C. Just don’t install the Logitech Options utility software which is buggy and causes system problems. Use BetterTouchTool instead if you want to customize the buttons.


App Development

For writing sample apps and code, I use Xcode set up in a completely standard way, using the default light scheme. This is so that my screenshots are consistent with what people will see if they are just getting started.

I wrote an article about Consistent Swift Style some years ago. The concepts are still valid but the way you integrate it with Xcode has changed. Add a build phase to your project, move it to before the Compile Scripts phase and set it to this:

export PATH="$PATH:/opt/homebrew/bin"
if which swiftlint > /dev/null; then
  echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"

This will use the default SwiftLint config which you can change in Terminal.

If you’ve saved a custom config file, use something like this:

if [ -f path/to/your-config-file.yml ]; then
  if which swiftlint >/dev/null; then
    swiftlint --no-cache --config path-to/your-config-file.yml

To make SwiftLint fix what it can automatically, duplicate the swiftlint line and add --fix as another parameter to the first copy. This will run SwiftLint twice: once to auto-fix what it can, and a second time to supply the warnings and errors about what it couldn’t fix.


The text of the book was written in Markdown which is great for producing formatted text in a totally open and transferable format. I’m always on the lookout for a new Markdown editor and there are a lot of them around. In Section 3 of the book, I talk you through creating a Markdown editor for yourself, but it isn’t quite ready for full-time use yet. I wrote this book using FoldingText which I was quite happy with. While the folding part was not something I used, I appreciated the outline view. Editing text inside links and image links was difficult and the spell checker sometimes got confused and marked an entire sentence or paragraph as incorrect. But the formatting was good and easy to use with plenty of keyboard shortcuts. Code formatting was also excellent, which is a must.

I have a bad habit of using the passive voice, which is not good when trying to teach. I use Hemingway Editor to help me detect this, so that the passive voice can be eradicated… (Passive voice joke there.) You can use it online, but I prefer to use the app.

Screen shots

If you’ve read the book, you’ll know that it includes a lot of screen shots. There are a lot of third-party utilities for doing this, but the built-in facility gives me everything I need. It’s important to memorise the keyboard shortcuts to make this easier:

  • Shift-Command-3: screen shot the entire screen.
  • Shift-Command-4: bring up crosshairs to allow selection of an area:
    • When in this mode:
      • Escape exits without action.
      • Press Space to enter window mode. The window under the pointer is selected and will be screen shotted.
      • Hold down Command to select a dialog box instead of the complete window.
      • Hold down Option to turn off the default shadow.
  • Shift-Command-5: bring up the interface where you set options, take screen recordings and set a delay.
    • I find this useful when I want to show the custom cursor during a drag operation. I turn on Show Mouse Pointer, set a 5 second delay and then start dragging before the timer runs out.

Once I have the image, I use Preview to crop and resize as needed.


Finally, there’s my support crew who watch every word I type and listen carefully as I explain my code.


WWDC 2022 Wishlist

Permalink - Posted on 2022-04-25 09:00

Apple has announced that their 2022 World Wide Developers Conference will again be an online event from June 7 to 11. The poster shows a very dark Swift logo in a coloured circle. While I have long since given up trying the read the tea leaves of Apple’s graphics to work out what they will announce, I always enjoy speculating. But this year, I thought that instead of trying to guess what Apple will have for us, I’d think about what I would like them to announce, with my main focus being the Mac.


The Apple hardware teams have been doing amazingly well over the last couple of years. The transition of the Mac lineup to Apple Silicon is almost complete and I would guess that they will complete it at WWDC with a new Mac Pro, but that is outside my budget and requirements.

While I was glad to see them offer a more reasonably priced monitor with the Studio Display, it’s still a bit pricey for me. The desk lamp iMac was one of my all time favourite Mac designs so it was great to see the option for the tilt & height adjustable stand, although the extra price for that option was rather eye-popping.

I have long thought that the desktop iMac was terrific value because it attaches a stunningly good monitor to a reasonable computer. I wish Apple would supply an iMac monitor using the exact same design, but without the computer. Imagine how great that would look as a second monitor - two coloured machines side by side.

But really, I’m not looking for any new hardware right now.


iCloud needs a lot of love, especially on the Mac side. I was trying to collaborate with a colleague so they shared a folder on iCloud. I was able to access their small set of files (24K total) after about 30 minutes, but my edits never uploaded. In the Finder sidebar, I have a perpetual progress indicator beside my iCloud folder and uploads never complete. The only solution is to reboot my computer, which does a complete sync once. We switched to sharing on our iPads and it all worked immediately, so the problem is not iCloud itself, but the macOS integration.

CloudKit has always looked like a great solution for use in apps. It allows public and private data, it syncs between devices, and it doesn’t have the potential for unexpected and huge data fees like some other options. But like many developers, I’ve tried and failed to get it to work reliably. It appears that the simpler mechanisms work well, but not the more complex options.

And while I’m talking about iCloud sync issues, some apps (Notes, Reminders etc) sync - albeit very slowly, but Messages operates as if it is only partially connected. If I delete a conversation on my iPhone or iPad, I get a warning telling me that this will remove the conversation from my other devices, which is what I would expect. This deletion flows through to my Mac and the conversation is gone everywhere. On my Mac, deleting a conversation only deletes it locally and I have to delete it again on my iPhone or iPad to get it to disappear completely. What is the logic of that?


There are two parts to Apple’s software: the operating systems and their own apps. iOS, iPadOS and watchOS seem quite solid in their latest versions. I don’t have any particular requests or complaints.

With macOS, apart from the iCloud problems that I mentioned above, my main complaint is with notifications. The user experience is terrible. Notifications popup at the top corner, and then disappear quickly. If they have action buttons, you have to mouse over the notification to see them, and this obscures the text. I have tried using System Preferences to change the way notifications are displayed, but this seems to have no effect. And trying to explain this system to a newcomer is impossible.

Apart from that, I like macOS 12 (Monterey). I would prefer Apple to go back to using numbers instead of names. Trying to work out what system people are using by the name is very confusing.

The other aspect of software is Apple’s in-house apps. Sadly, Apple has decided to use Catalyst to port a lot of apps from the iPad to macOS. For a small software house with very limited resources, I can see the attraction of Catalyst although, in my opinion, it results in a greatly inferior product that gives Mac users an inferior experience. However this is hardly a valid excuse for a company the size of Apple.

As a developer, one of my main tools is Xcode. This is an amazing app and over the past few years it has got a lot of new features that allow it to integrate better with source control and with the app distribution system. But I would love to see Apple open up the extension ecosystem again. For web development, I use Microsoft’s Visual Studio Code. Even though this is a cross-platform Electron-based web app, it is a great tool. It doesn’t look like a native Mac app but it performs well. But it’s major advantage is the huge number and variety of extensions so you can make VSC look and work the way you want. Apple has deliberately closed Xcode off from this sort of community involvement which is great shame.

Apple will tell you that they do allow Xcode extensions. But these are limited in scope, difficult to install and opaque to use. Xcode extensions used to be great - please bring them back again.

Developer Relations

This is where things get nasty. We all know that Tim Cook will bounce on to the WWDC stage saying how much they love their developers and how many billions they’ve paid out, but this is really just a smoke screen. Most of the money goes to a few large software houses who basically blackmail users into paying over and over again to make their apps (mostly games) usable. The race to the bottom has resulted in app stores where charging up front for an app is virtually impossible, although the Mac App Store is slightly better in this regard.

The big issue is Apple’s extremely erratic policing of the app stores. They allow behaviour in some apps and ban it is others. Big players get different treatment to small. Despite claiming that the app stores are the safe place to buy apps, Apple makes almost no effort to weed out scam apps, copyright infringements or fake reviews even when they are completely obvious to the most casual search.

I don’t mind paying Apple a cut of my app revenue. They do a lot of work that I would find tedious or difficult to set up for myself. I don’t even mind their restrictions. What I mind very deeply is the inconsistent way this is handled. I would love it if the App Stores lived up to Apple’s claim as being the safe place to buy apps, but in reality, app buyers are being fooled by purchased reviews, tricked into in-app purchases, and cannot assume that the rules designed to keep them safe have been applied to all apps.


So what would I really like to see at WWDC 2022?

  • iCloud syncing that works on all Apple platforms.
  • Real Xcode extensions.
  • New App Store rules to weed out copycat apps and fake reviews and that apply equally to all developers.
  • Better notifications for macOS - preferably the type we used to have.

macOS Book

Permalink - Posted on 2022-04-09 00:53

I can finally reveal the reason I have not been blogging. I have been busy writing a book. It’s finally out, so here it is: macOS by Tutorials, published by raywenderlich.com.

Book Cover

Anyone who reads my posts or tweets will know that I am a passionate advocate for building real native macOS apps. This book is aimed at iOS developers who know some Swift and SwiftUI but don’t yet know all the tips and tricks needed to convert that knowledge into a great Mac experience.

You don’t need to be a highly experienced developer, but some basic Swift will be useful.


The book consists of five sections. In each of the first four sections, I’ll walk you through developing a complete app. Each one is a different type of app using different techniques and different frameworks.

Section 1: Use SwiftUI to build a multi-paned window app. Learn how to manage windows, menus and toolbars.

Section 2: Build a menu-bar app using AppKit with a bit of SwiftUI.

Section 3: Back to SwiftUI to create a document-based app, with a bit of AppKit.

Section 4: Use your new skills to make an app that communicates with the macOS Terminal.

The final section deals with app distribution, covering both inside and outside the Mac App Store.

You can read more details of the book contents and why I wanted to write it in the Introduction which is a free section.

Thanks to…

I call this my book, but of course, it was only made possible by an awesome team. There were a lot of people involved, but I want to give special thanks to:

  • Ray Wenderlich who always has time for my Mac obsession and who let me write the book I wanted to write.

  • Manda Frederick was the RW book team lead when we started and was a huge source of encouragement.

  • Richard Critz, the wonderful editor who had the unenviable task of fixing my grammar. He was very supportive and helped me to convince everyone of the merits of this approach.

  • Audrey Tam and Ehab Amer were the amazing tech editors who had to make sure the instructions all worked and made sense. They took what I wrote and made it a lot better.

The whole team at Ray Wenderlich was great, so a huge thanks to them all. And I hope they enjoyed working on the book half as much as I did, because I had the best time!

Where can you read the book?

  • You can read it online at raywenderlich.com as part of a Ray Wenderlich subscription.
  • You can download an ebook (ePub or pdf) at the same page if you have a subscription or but one there if you don’t.
  • The paperback is available at Amazon.

All the code and extra materials for the book can be downloaded or cloned from GitHub.


I would love to hear from anyone who read the book, loved it, hated it, found an error or just anted to say hello.

You can contact me directly using any of the contact links at the bottom of this page or through the Contact page. There is also an official forum for the book where you can ask questions and tell us about any errors you find.

Site Search

Permalink - Posted on 2021-10-24 23:57

Not much action on the site lately as I work on other projects. But I have finally got around to adding a search option to the site.

I use Hugo as a static site generator, which is great but Hugo doesn’t come with any search facility.

Today, I read an article by Jesse Squires on Replacing Google Search with DuckDuckGo and while I had already switched to using DuckDuckGo for my own web searching, I had not considered it for my site search.

It isn’t as good as an in-built search page, which I have considered setting up using Algolia, but that requires a lot of setup and I never got round to it. This search takes you out of my site and into a DuckDuckGo page, but it limits the search options to the troz.net domain.

To access the search, go to either the Archives or the Tags page, and use the search field at the top of the page.

As a side note, if you are using DuckDuckGo as your regular search engine, read up about their !bangs. These are quick and easy ways to target your search. you can prefix your search with !so to search Stack Overflow, or !i to search for images. Search the !bangs page to find the ones that are useful to you.

The Apple DTK Gamble

Permalink - Posted on 2021-02-04 08:57

So I gambled…

I hoped Apple would do the right thing by developers who paid for access to the Developer Transition Kit (DTK) to get the first Apple Silicon Macs, but I was wrong and I lost.

UPDATE - 6 Feb 2020: Apple has responded to feedback from me and other disgruntled developers and so I didn’t lose as much as I thought. Apple is now giving US $500 credit, which is what developers in the US paid for the DTK, and they are extending the time limit to the end of the year. I am quite certain they will release a desktop M1 Mac before then, so I will get credit for most of the cost of the DTK (after exchange rate losses) and I will be able to use the credit towards a Mac that I want.

Thanks Apple for listening and reacting.

I paid Apple AU $779 for a year’s lease on a DTK which was effectively a Mac mini with an iPad CPU. I also had to buy a monitor to use with it.

That was in June 2020.

In November 2020, the M1 was released which made the A14Z based DTK totally irrelevant for testing or development, so the lease effectively only lasted for 5 months. At that I was luckier than many devs as a lot of these DTK machines started failing at around the 4 month mark.

  • I kept Apple’s secrets.
  • I tested their hardware and software.
  • I filed bug reports, a couple of which even got acknowledged.

And in return, I get asked to send back the DTK some months early for which I will get the princely reward of US $200 credit.

When Apple switched over to Intel CPUs, they gave the DTK buyers a free computer when they returned the DTK, but of course Apple wasn’t a trillion dollar company back then so they could afford to be generous. (How does one indicate heavy sarcasm in text?)

I don’t want a laptop, I want a desktop Mac, so there is nothing to spend my $200 credit on yet, but as a final sting in the tail, Apple has decreed that the credit expires at the end of May 2021. There is no guarantee that there will be desktop Mac to buy before then. Only Apple knows that and they have made me cynical enough to consider that they might decide not to release any new Macs until after these credits expire.

I realize that Apple made no commitment to do anything after the DTK program was over, but history indicated they would.

The smallness of the credit and the short time limit on it seem unnecessarily petty and punitive, especially when the people they are punishing are the ones that add so much value to the Apple platforms.

Assuming I have to get a laptop, I will want a high-powered one as it will have to be able to run Xcode. Apple’s flagship developer tool is famously demanding.

  • In the US, the one I want costs US $1,899

  • Here in Australia, it is AU $2,899 - 1.53 times the US price.

The US$200 credit will use the exchange rate at 23 December 2020, which for USD - AUD was 1.3218 which is significantly lower than the ratio in Apple’s pricing between the two countries.

This means that I will get AU $264.36 for my credit, which is 9% of the cost of the computer to replace it, even though that is not the computer I actually want.

Financially, I would have been much better off waiting until the M1s were released. But Apple needed the early machines tested, so they suckered us in and then slapped us in the face.

I wonder how Tim Cook and the others can stand up again and again and say that they value their developers. Does that not make them feel ashamed? Or maybe they struggle not to laugh while saying it?

Thanks Apple.

And good luck finding suckers to test your next round of new hardware.

SwifUI Mac Menus

Permalink - Posted on 2021-01-24 05:24

With the option to create apps using the SwiftUI App life cycle, we get a new way to set up menus in Mac apps. This post will explore some of the ways to do this as well as look at the default menu groups that Apple gives us.

When you create a new Mac app, the standard menu items are included for you. Using the commands modifier on the WindowGroup allows you to add new menus, add new menu items and to replace or remove existing menu items.

Adding a New Menu

To add a completely new menu, you can use CommandMenu, supplying it with a title and the contents to display.

After starting this process, the App.swift file looks like this:

struct MenuSamplesApp: App {
	var body: some Scene {
		WindowGroup {
		.commands {
			CommandMenu("Custom Menu") {
				// no contents yet

So what can be put inside the menu? We are used to only being allowed to use NSMenuItems but with SwiftUI there are no such things. It turns out that you can put quite a few SwiftUI views into a menu.

The most obvious is a Button with an action which appears like any standard menu item.

CommandMenu("Custom Menu") {
	Button(action: {
		print("Menu Button selected")
	}, label: {
		Text("Menu Button")

I have found that the easiest way to pass this selection on to other views is via a notification. Buttons can be disabled and enabled just as usual.

The contents of the button will usually be a Text view, but it can include an Image view if you want to use an SFSymbol or any other image in the menu.

Button(action: {}, label: {
	Image(systemName: "clock")
	Text("Date & Time")

Apart from Buttons, there are several other SwiftUI Views that work in a menu. A very common use case in a menu is to have a switchable boolean setting that is displayed with a leading check mark if it is on.

This can be done using a Toggle view.

Toggle(isOn: $toggleSetting, label: {

I created a variable to hold the setting using @State but @AppStorage would be better if this setting needed to persist between launches. To respond to changes, you can use an onChange modifier.

This demonstrates one of the huge strengths of SwiftUI’s declarative approach. You tell the compile you want a Toggle and it is automatically structured to fit the place and platform where it is being used.

A Picker is a good choice for allowing a single selection from multiple options. This makes a sub menu with check marks.

Picker("Appearance", selection: $pickerChoice) {

To make a sub-menu with standard menu items like buttons, use Menu.

Menu("Sub Menu") {
	Button(action: {}, label: {
		Text("Sub Item 1")
	Button(action: {}, label: {
		Text("Sub Item 2")
	Button(action: {}, label: {
		Text("Sub Item 3")

Menu items are often best split up with a separator and this is done in SwiftUI by adding a Divider().

If you try a UI element in a menu and it doesn’t work, it tends to show as disabled text and doesn’t break the menu, so experiment. I was surprised to find that Link does not work in a menu.

Editing Existing Menus

I have covered creating a new menu, but what about adding new items to an existing menu?

In this case, use CommandGroup instead of CommandMenu. The difference is that instead of setting a title for the menu, you give it a placement option with a reference to an existing standard menu item.

Still inside the commands contents, start typing CommandGroup to see three options:

  • CommandGroup(after:, addition:)
  • CommandGroup(before:, addition:)
  • CommandGroup(replacing:, addition:)

In each case, the first parameter is a CommandGroupPlacement that specifies one of a limited range of standard menu items.


The options for the menu items inside a CommandGroup are just the same as when creating your own menu.

Removing a Standard Menu Item

If you really want to get rid of one of the default menu items (or groups of items), you can use CommandGroupPlacement and replace the existing one with an EmptyView(). This is probably not a great idea as regards the Human Interface Guidelines but it is an option if you need it.

CommandGroup(replacing: CommandGroupPlacement.appVisibility) {

You can also replace an existing menu item with your own version if you want to be able to respond to it in a more custom way. I can imagine doing this for the Help menu item as I do not like using Apple’s Help system and prefer to direct users elsewhere.

Preset Menu Groups

If you watched my Back to the Mac talk called Build a Mac app inside 30 minutes using nothing but SwiftUI, you will have seen who I used a rather clunky function to dive into AppKit in order to stop the sidebar disappearing completely and permanently.

If you haven’t watched it yet, go and take a look - I’ll wait… If you made it this far, I assume you are a Mac app fan like me and I think you will enjoy the talk as it demonstrated a lot of SwiftUI Mac app techniques.

Since I recorded that video, I found out that Apple provides preset menu groups for dealing with certain things and one of them is for sidebars. My clunky solution is still useful if you want to have a toolbar button, but I think I would include the menu group as well.

There are five present Commands groups provided by Apple, four of which are useful and the fifth has a purpose that escapes me.

  • SidebarCommands()
  • ToolbarCommands()

Inserting both these into your commands will expand the default View menu, so that it goes from this:


To this:


You do not need to include both, but it was easier to show in one screen shot instead of two.

If your app allows any serious text editing, you are going to want to use:

  • TextEditingCommands()

Which changes the default Edit menu from this:


To this:


And if you need your users to be able to format text, including:

  • TextFormattingCommands()

adds in a Format menu.


And finally, there is EmptyCommands() which does nothing and has no obvious use.

These are used like this:

.commands {

Using a Separate File

If you are adding a lot of menus, you are probably starting to feel that your App.swift file is getting a bit crowded. You can separate out these menu commands into one or more separate files, so long as they are contained in a struct that conforms to the Commands protocol and which has a body that also conforms to Commands.

struct MenuCommands: Commands {
	@Binding var toggleSetting: Bool

	var body: some Commands {
		CommandMenu("Custom Menu") {
			Button(action: {
				print("Menu Button selected")
			}, label: {
				Text("Menu Button")


			Toggle(isOn: $toggleSetting, label: {

This struct cannot have its own data or you will get lots of warnings, but it can have bindings to data from its parent. Insert a call to this struct, and any others you have created, in the commands modifier, just like for the Apple presets.

@State private var toggleSetting = true

// ...

.commands {
	MenuCommands(toggleSetting: $toggleSetting)

Bonus: Credits

Every Mac app has an “About …” menu item which brings up a simple dialog box with basic app information: icon, app name and version number. These will always appear but there is an easy way to add more information underneath this info and it can include formatted text and links.

Create a new file called Credits.rtf - the New File dialog has a Rich Text File option. Anything in a file with this exact name will be shown below the standard information in the About box.

Xcode’s RTF editor is not great, but it is good enough for this. There are some basic formatting tools above the text editor, but you can also right-click on text to get more options, including Font and Color panels.

To insert a web link, go to the Editor menu and select Add Link…

Well that’s it. A quick round-up of the ways to use menus in your SwiftIU Mac apps. I hope you found it useful. If you have any suggestions, comments, corrections or improvements, please contact me using one of the links below or through the Contact page.

SwiftUI Data Flow

Permalink - Posted on 2021-01-24 05:17

SwiftUI gives us a completely new way to lay out out user interfaces, in a declarative and responsive way. Your data dictates what is displayed. But this leads to a new problem - how should the data models be constructed and how can they be passed around between the various views that make up your app?

In this post, I intend to discuss the possibilities with examples.

Update - January 2021: I think the information in this post is still all valid except for one change. When you are initializing an ObservableObject, you should use @StateObject instead of @ObservedObject. Your views can receive objects that are owned by other views as @ObservedObject or @EnvironmentObject but the owner of the data should always create the data object with @StateObject.

For a great diagram showing what data object type to use where, check out this image from Chris Edihof - thanks Chris!

Data flow

If you read this article before November 18th 2019, please check out ObservableObject & @ObservedObject - Part 2 again as it has gone through several iterations, which are all shown for comparison.

At WWDC 2019, some Apple engineers gave a great presentation on Data Flow Through SwiftUI and I strongly recommend watching the video. But you need to watch it twice. First watch it so that you can get started, and then, when you feel that this is all way too complicated, watch it again and it will start to click into place. The only real difference between then and now is that BindableObject has become ObservableObject.

I guess I could stop there, but I will be illustrating my ideas with code examples, which I hope will make things clearer. Some of the examples are rather contrived in order to make a point, but the sample code is also sprinkled with other SwiftUI examples which I hope will prove useful.

Download the sample project from GitHub and open it in Xcode. Go to ContentView.swift and make sure the Canvas is open. Click Resume to make the view appear. Then click the Live Preview button and wait for the view to become active. I recommend clicking the Pin button at the bottom left of the Canvas so that you can investigate the code samples, while still working in the main navigation.

Data Flow Options

There are 5 ways to specify data in SwiftUI:

  • Property
  • @State
  • @Binding
  • ObservableObject & @ObservedObject
  • @EnvironmentObject

Content View


struct Property: View {
    // Property
    let greeting = "Hello from SwiftUI!"

    var body: some View {
        // Using property directly

In this example, the greeting property is used in the view. greeting is static, so the view does not need to monitor it for changes. This may seem like a simplistic and obvious example, but separating it out allows for localization or re-usability.

The property could also have been supplied by a parent view and this is a really useful feature of properties. A parent view can have some dynamic data that it can use to set properties in a subview where the subview only needs to display the data statically. This data will change as the parent view changes but the subview will not be able to change the data in the parent view.

And it is important to remember that not everything needs to be set up with one of these new property wrappers.


This is where things start to get very interesting in the SwiftUI world. SwiftUI views are contained in structs, so are non-mutable. Also, the views are re-created every time the data changes, so any properties are re-created then too. By marking a property with the @State property wrapper, you are telling SwiftUI that you want it to keep this data in a separate portion of memory, allow it to be mutated, and preserve the current value during the view refresh.

struct UsingState: View {
    @State private var toggleValue = true

    var body: some View {
        // Using state with 2-way binding
         Toggle(isOn: $toggleValue) {
             Text("Toggle is \(self.toggleValue ? "ON" : "OFF")")

In this example, toggleValue is declared as a Bool with a property wrapper of @State. Inside the Toggle, the isOn value is bound to toggleValue by the leading $. This allows the variable to set the toggle and the toggle to set the variable - 2-way binding.


@State variables are always value types and are usually local to their view, so Apple recommends marking them as private.

And unlike properties, @State variables allow you to have data that is dynamic but it can still be passed to subviews as properties for display.


One problem with building SwiftUI views is that it is very easy to end up with a gigantic Pyramid of Doom as you embed views within views within views. The solution is to extract subviews, but then you need a way to pass the data to the subview.

This is where @Binding comes in as it allows you to tell a view that the data for a property is actually coming from a parent but that the subview is allowed to change that property and that change will flow back to the parent’s data.

struct Numbers: View {
    @State private var stepperValue = 0

    var body: some View {
        NumberChooser(stepperValue: $stepperValue)

struct NumberChooser: View {
    // Using state from parent with 2-way binding
    @Binding var stepperValue: Int

    var body: some View {
        ZStack {
            VStack {
                Stepper(value: $stepperValue, in: 0...20) {
                    Text("Value = \(stepperValue)")

                NumberBlock(stepperValue: stepperValue)

struct NumberBlock: View {
    // As this view never changes the value, there is no need to bind it
    var stepperValue: Int

    var body: some View {
        Image(systemName: "\(stepperValue).square")

In this example, I have declared a stepperValue property and marked it with @State.

The interface has been extracted into a subview called NumberChooser and a Binding to the stepperValue property has been passed to NumberChooser using the $ prefix, which will ensure that changes to the value can come back. Inside NumberChooser this property is wrapped in the @Binding property wrapper to indicate that it is coming from another source and that changes will be returned.

NumberChooser itself has a subview called NumberBlock but it is a display view only and never mutates the value itself, so stepperValue is passed to this subview as a property only, without the $ prefix. It will still be updated every time the data changes as it is contained by the view with the @State property.

Number Chooser

@State & @Binding - Part 2

So far, the examples have used primitive data types for the @State properties, but given that @State properties are value types, any struct can be used. In the next example, I use a struct to hold the properties of a pizza order and use a SwiftUI Form to allow selections.

struct PizzaView: View {
    // Using @State for a struct
    @State private var pizza = Pizza()

    var body: some View {
            VStack {
                Form {
                    // Using 2-way binding but each component
                    // only needs 1 property from the struct
                    PizzaNamePicker(selectedPizzaName: $pizza.name)
                    PizzaSizePicker(selectedPizzaSize: $pizza.size)
                    PizzaCrustPicker(selectedPizzaCrust: $pizza.crust)

                // Text representation to prove that the
                // subviews are modifying the parent struct
            .navigationBarTitle("Choose Your Pizza")

Each subview gets the property it needs using @Binding:

struct PizzaNamePicker: View {
    @Binding var selectedPizzaName: PizzaName

    var body: some View {
      // see the GitHub project for more details

The form consists of 3 subviews - one each for selecting the pizza, size and crust. The Pizza struct holds all three properties, but each subview only needs a Binding to the single property that it controls. The Text view after the Form is to prove that all the selections come back to the parent.

Pizza View

ObservableObject & @ObservedObject - Part 1

These are used if your data model is a class and you want to use reference-based data instead of the struct’s value-based system.

To set up a data model to be Observable, it must conform to the ObservableObject protocol and any property that needs to be observed should have the @Published property wrapper. This makes sure that any time this property changes, all the Views that are observing the instance of this data model will be notified to perform the UI updates.

For this example, I have a ColorSet class with six color components that are used to assemble two RGB colors.

class ColorSet: ObservableObject {
    // ObservableObject
    // The 6 color components are marked as @Published so any changes
    // get published to the views that are observing

    @Published var foregroundRed = 0.0
    @Published var foregroundGreen = 0.0
    @Published var foregroundBlue = 0.0

    @Published var backgroundRed = 1.0
    @Published var backgroundGreen = 1.0
    @Published var backgroundBlue = 1.0

In the primary view, I set up an instance of this class as an @ObservedObject.

struct ColorSetView: View {
    @ObservedObject private var colorSet = ColorSet()

The background of the view and the foreground of a system image are set using these colors. A button presents a sheet with sliders to allow editing these colors. The colorSet is passed to the sheet like this:

  .sheet(isPresented: $showChooser) {
      // notice that this does not use $ as the ColorChooser
      // will get a reference to the ColorSet object
      ColorChooser(colorSet: self.colorSet)
struct ColorChooser: View {
    @ObservedObject var colorSet: ColorSet

    var body: some View {
        // ...

A sheet is not the ideal way of presenting a view that uses sliders for editing, but I wanted to demonstrate that changing the sliders instantly changes the value of the @ObservedObject for the parent view as well as for the subview. Editing the background color components shows the new background color in the back at the top of the sheet.

The ColorChooser itself uses 2 subviews and they get a reference to the ColorSet in the same manner.

Color Chooser

ObservableObject & @ObservedObject - Part 2

This section was that one that caused me the most trouble when writing the example app. I wanted to display a list of data and have each entry link to an editable detail view with the edits flowing back to the parent list.

The initial display of data in a List was straight-forward and I was then able to have the list rows navigate to a detailed view for each entry. The problem was getting the edited data back to the parent List.

The basic data model was an ObservableObject that publishes an array of PersonViewModel objects.

class PersonListModel: ObservableObject {
    @Published var persons: [PersonViewModel] = []

    func fetchData() {
        // get data from web ...

        DispatchQueue.main.async {
            self.persons = newData

Since this data is going to trigger a UI update after a background network call, it is important that changes to the @Published property get switched to the main thread.

The PersonViewModel also needs to be Observable with the editable properties marked as @Published.

class PersonViewModel: Identifiable, ObservableObject {
    // Even though this is not observed directly,
    // it must be an ObservableObject for the data flow to work

    var id = UUID()
    @Published var first: String = ""
    @Published var last: String = ""
    @Published var phone: String = ""

The odd thing was the way that I had to pass the data to the detail view. This is what I tried initially:

  List {
      ForEach(personList.persons) { person in
              PersonDetailView(person: person)
          ) {
              Text("\(person.first) \(person.last)")

And in PersonDetailView:

    @ObservedObject var person: PersonViewModel

This almost worked. The correct data was passed to the detail view, and the data edits changed the data, but the parent list was never re-drawn. If I changed a record’s first name then went back to the list, the change was not displayed. But if I then returned to the detail view for the same record, my edits were there, so I could tell that the data was changing correctly. The problem was how to change it in such a way that the parent view was notified of the change.

Trying to bind person with PersonDetailView(person: $person) gave the error Use of unresolved identifier '$person', so the ForEach enumeration did not provide a direct connection to the personList object.

The solution I came up with was to switch to enumerating by index in the ForEach and passing a direct member of the parent list’s data to the detail view. And switching the PersonDetailView to use @Binding var person: PersonViewModel.

ForEach(0 ..< personList.persons.count, id: \.self) { index in
        PersonDetailView(person: self.$personList.persons[index])
    ) {
        Text("\(self.personList.persons[index].first)") +
          Text(" \(self.personList.persons[index].last)")

This works but as well as being hard to read, it has one major flaw. The rows in the table are identified by their row number, rather than by anything in the data like the person.id. This can really mess with how SwiftUI handles the List and how it knows which rows have changed and need to be re-rendered. It is important to identify rows by something unique to the data in each row so that SwiftUI knows that you have deleted the row with the ID “abcd-1234” and not row #7. Because if you delete row ID “abcd-1234” there is no longer a row ID “abcd-1234” but if you delete row #7, there is now a different row #7 and anything could happen.

Update 1: @StewartLynch contacted me to suggest a much neater way to pass the person data to the PersonDetailView by using a function to get a Binding<PersonViewModel> for each person being displayed. This worked perfectly and made for a much cleaner looking bit of code. Thanks Stewart.

ForEach(personList.persons) { person in
        PersonDetailView(person: self.selectedPerson(id: person.id))
    ) {
        Text("\(person.first) \(person.last)")

And outside the body declaration:

func selectedPerson(id: UUID) -> Binding<PersonViewModel> {
    guard let index = self.personList.persons.firstIndex(where: { $0.id == id }) else {
        fatalError("This person does not exist.")
    return self.$personList.persons[index]

If you want to have a look at Stewart’s solution, check out this commit on GitHub.

Update 2: @vadimshpakovski says that creating a binding for every person object is inefficient and that the function to create this binding will slow things down. He suggests using onReceive to react to changes to person and trigger an update of personList. In this case, PersonDetailView uses @ObservedObject var person: PersonViewModel. This also works perfectly.

  ForEach(personList.persons) { person in
          PersonDetailView(person: person)
              .onReceive(person.objectWillChange) { _ in
      ) {
          Text("\(person.first) \(person.last)")

If you want to have a look at Vadim’s’s solution, check out this commit on GitHub.

Update 3: More suggestions have come in from the community (thanks to everyone who contributed) and it has been pointed out to me that while Vadim’s solution does solve a lot of the issues, it means that the entire ForEach has to be recalculated to check for changes every time a single Person is edited. And it also inserts model management code into the view code, which is not great.

So my next attempt goes back to using @Binding var person: PersonViewModel in PersonDetailView but instead of PersonListModel having an array of PersonViewModels, it has an array of UUIDs and a dictionary of UUID: PersonListModel. The benefit of this is that the UUIDs can be used in the ForEach as they are unique to each row, and the dictionary can be used to provide a Binding to the person for each UUID.

This removes the problem of my original solution by identifying each row uniquely, it goes back to Stewart’s solution but eliminates the potential slow function to create a binding for the matching person, and eliminates the issue of complete redraws and model management inside views from Vadim’s suggestion.

But it was not entirely straight-forward as getting a value from a dictionary by key returns an optional. At first I thought I could use the new default syntax for dictionaries to get a non-optional value for binding but for some reason that couldn’t be used to create a Binding.

The answer was to write an extension on Dictionary with a subscript function that returns a non-optional value or gives a fatal error. Since I am in control of the data and set up every UUID with a matching PersonViewModel, this is not dangerous.

So here is what we have now:

class PersonListModel: ObservableObject {
    // Main list view model
    // ObservableObject so that updates are detected

    @Published var ids: [UUID] = []
    @Published var persons: [UUID : PersonViewModel] = [:]

    func fetchData() {
        // get data from web ...

        DispatchQueue.main.async {
          let personViewModels = dataArray.map { PersonViewModel(with: $0) }.sorted() {
              $0.last + $0.first < $1.last + $1.first
          self.ids = personViewModels.map { $0.id }
          self.persons = Dictionary(
              uniqueKeysWithValues: personViewModels.map { ($0.id, $0) }

The incoming data is mapped to a sorted array of PersonViewModels before extracting the UUIDs and creating the dictionary. This means that the UUIDs array is in the correct sort order for use in the ForEach.

Here is the Dictionary extension:

extension Dictionary where Key == UUID, Value == PersonViewModel {
    subscript(unchecked key: Key) -> Value {
        get {
            guard let result = self[key] else {
                fatalError("This person does not exist.")
            return result
        set {
            self[key] = newValue

And these go together to allow this:

ForEach(personList.ids, id: \.self) { id in
        destination: PersonDetailView(person: self.$personList.persons[unchecked: id])
    ) {
        Text("\(self.personList.persons[unchecked: id].first)") +
            Text(" \(self.personList.persons[unchecked: id].last)")

Person List View

This ended up a bit more complicated than my original idea, but I think it is now good SwiftUI, avoiding several problems from the earlier solutions.

Thanks to JSON Generator for the sample data. And if anyone has any other solutions to this problem, I would love to hear it. You can contact me using any of the buttons at the end of this article.


Think of the EnvironmentObject a piece of state that can be used by any view or any descendent of the view once it has been introduced. People who have used React or any of the similar web development technologies will be familiar with the concept of global state and this is similar to that, although not truely global.

You set up a class as an EnvironmentObject model exactly as you would set up an ObservableObject with the same protocol conformance and using the @Published property wrapper to mark properties whose changes will trigger UI updates. Here is a very simple example with just one property.

class UserSettings: ObservableObject {
    @Published var isLoggedIn: Bool = false

Nested Views

In this example, the yellow view is the parent view - the different views have different brightly colored backgrounds to make them easy to distinguish. The yellow view has access to the UserSettings like this:

struct NestingViews: View {
    @EnvironmentObject var userSettings: UserSettings

    var body: some View {
        ZStack {

            VStack {
                // UI omitted for space reasons

                // display first nested view

The ChildView contained in this parent - the green view - has no need to access this data and so gets no @EnvironmentObject property. But ChildView contains another subview - the blue one. And this GrandChildView does need access to the UserSettings so it has the exact same @EnvironmentObject var userSettings: UserSettings property as the parent view.

If this was using @ObservedObject the data would have to be passed through every view in an un-broken chain, even though ChildView did not need this data. By using @EnvironmentObject the chain can be broken, but any view that needs to, can access and mutate this data. In the example, both the yellow and the blue views display and edit the same data with updates happening in both when either button is pressed.

One key thing to remember about previewing @EnvironmentObject in the Canvas is that every view that uses it, or that contains a view that uses it, needs to be supplied with the ObservableObject in the preview using .environmentObject().

struct NestingViews_Previews: PreviewProvider {
    static var previews: some View {

In the app itself, only the first view to access the @EnvironmentObject needs it set. In this example, it is done in the NavigationLink that goes to the NestingViews example. The .environmentObject can be provided to the root view in the SceneDelegate if the root view needs it.

    NavigationLink(destination: NestingViews().environmentObject(UserSettings())) {
        ListContents(title: "@EnvironmentObject", imageNumber: 6)


Or What Should I Use When?

  • For value-based data models or data primitives, use @State.
  • For reference-based data use ObservableObject.
  • For data needed by a lot of views in your app, use @EnvironmentObject.
  • Use @Binding or @ObservedObject to pass data to a view that can mutate it.

And one final tip: while creating a view from scratch, use @State with sample, hard-coded data. Once you have the interface you want, then change it to use real data.

I am sure people will develop their own theories and their own ways of using SwiftUI, but those are the guidelines that I intend to follow for now. If you have different views and would like to discuss them, please contact me.


Permalink - Posted on 2020-11-22 22:59

I have just released Crossfix and Crossfix Lite for iPhone. They are both the same anagram assistant solver for crosswords, particularly cryptic crosswords. The Lite version is free but limits you to three solves per day. The full version is unlimited with no ads, no recurring subscriptions and works with family sharing.

Anagram solving

For more details, check out the app page at https://troz/net/crossfix/.

And if you are interested in the back story and the development process, have a look at Name This App. Thanks to everyone who suggested a name, and special thanks to Jerry who came up with the winning entry.

This is the first app that I have published that is 100% SwiftUI, although as I started it several months ago, it still uses the old App Delegate life cycle.


Permalink - Posted on 2020-11-22 06:23

Now available on the App Store for iPhones. Also works on Apple Silicon Macs.


Download on the App Store

Crossfix Lite

Download on the App Store

Programmers are basically puzzlers, and programming is the world’s best type of puzzle, but I like to start my day with a cryptic crossword. Like programming, cryptic crossword clues have their own syntax and what seems like gibberish on a first glance, can be parsed into logical parts to take you to the answer. But there are aspects of solving crosswords that were easier with pencil and paper, so I decided to write an app to help fill one of those gaps.

There are sites and apps that offer anagram solvers, but they are just looking through a dictionary and showing you all the possibilities. To me, this feels like cheating, but I don’t have a problem with using an app to emulate the techniques I used to use with pencil and paper.


Anagrams are a very popular clue type but they can be tricky to solve because our brains are too good at discerning patterns. We can recognize words using only the first and last letters if they have the correct number of letters inside. This means that asking our brains to scramble these letters into a completely different word is very difficult. In the olden days, when I used to do crosswords in the newspaper, the best method was to find a space in the margin and write the letters out in a circle which forced my brain to reconsider the options. But I do crosswords on my iPad now and while I could use a notes app and my Apple Pencil to draw the letters out, I don’t always have the Pencil with me and I want to keep looking at the crossword. So I decided that a companion iPhone app was the way that would work best for me.

Look at how I use Crossfix to help me solve this clue.

Users rip off revelation (8)

The word “off” is a hint that this is an anagram, “Users rip” has the right number of letters, so the overall clue must be “revelation”. This is not a very long anagram and I think having two words makes it easier, but even so.

Anagram solving

I knew that the third last letter was “I” so I locked that in place, then I was able to shuffle the other letters around to find the answer: SURPRISE.

A Different Type of Anagram

Now we come to a variation of the anagram clue that is very popular with some crossword creators. I don’t know if there is an official name, but I call them “subtraction anagrams”.

Here is an example:

Creationist has no taste for what’s sarcastic (6)

The idea here is to remove the letters in “taste” from the letters in “Creationist” and then unscramble the remaining letters to find a word that means “sarcastic”. This turned out to be “ironic”.

Subraction anagram solving

Using the app

Type the letters in your anagram word or words in the entry field at the top. Spell checking is turned off so you can add spaces or not, use abbreviations or anything you like. When you have all the letters in, press Return and the letters will be arranged in a circle.

Tap the arrows in the middle of the circle to shuffle the letters randomly. This can be very useful as sometimes a pattern appears.

Tap a letter square to select it and tap again to move it, either into an answer square or into the discard tray below. Tap a letter in an answer square or in the discard tray to put it back into the circle.

If you already know some of the cross letters, put them into the answer squares and tap the lock button to freeze them in place.

The up arrow button will move all the unlocked letters out of the answer squares and back into the circle. Reset starts the word again completely and Clear removes everything so you can start again with a new set of letters.

Tap the gear wheel to see some help and to configure the sound and animation settings. Swipe down to dismiss this display.


Which Version to Get

I have published two version of this app on the App Store: Crossfix and Crossfix Lite.

Crossfix Lite is free, but you are limited to solving three anagrams per day. Crossfix is a paid app that allows unlimited solves.

Try out Crossfix Lite and then pay for Crossfix if you need more solves or if you would like to support the development of this app.

You may be wondering why I chose to release two apps instead of using in-app purchases to unlock the full version and there is one big reason: family sharing. I share a family account and it has always really annoyed me that direct app purchases are shared, but in-app purchases are not. So if I used IAPs and more than one member of your family wanted to use the app, you would have to pay twice, which seems unfair. I have deliberately chosen to have two distinct apps so as to allow family members to share all the features of the full app with a single purchase.

Stats for WoW

Permalink - Posted on 2020-10-14 01:43

Do you play World of Warcraft?

Have you ever agonised over a new piece of gear - are those stats better or worse for my class and specialization?

Is your computer festooned with sticky notes reminding you that your prot pally needs haste over mastery but the enhancement shaman needs agility?

Get rid of the notes and use the Stats for WoW app instead.

Stats for WoW in the App Store

Data comes from Noxxic and Icy Veins and is updated automatically with each new patch.

And you can follow the direct links to the pages for your class and spec on Noxxic or Icy Veins for more info from within the app.

Stats for WoW

Click for a larger image…

Yes, my main is a Beast Master Hunter - Axelady on Khaz’goroth if anyone wants to say hello. And if you have to ask why a hunter is called Axelady, you haven’t been a hunter for as long as I have!


SwiftUI for Mac on Big Sur

Permalink - Posted on 2020-07-08 09:40

In December 2019, I wrote a series of articles about using SwiftUI to build a Mac app. At WWDC 2020, Apple announced macOS 11 Big Sur along with Xcode 12 and a heap of new features for SwiftUI, so I decided to try creating my test app again and seeing how much had changed.

You can read the earlier articles and if you are interested, download the previous project from GitHub. Usually, when revisiting an old app, I would update the existing project, but this time I want to use the new SwiftUI App so I am going to start from scratch with a new app project, copying in code as required. And I plan to follow the same basic thread as I did in the previous articles. Who knows haw many parts this one will have!

For reference, I am running the beta of macOS 11 Big Sur (20A4299v) and the beta of Xcode 12 (12A6159) on a rather aged MacBook with a dodgy battery. I do not have Xcode 12 installed on my Catalina Mac, so I have no way of telling whether some of the oddities are due to Xcode or Big Sur but I will try to keep this article updated as the new betas improve things.

Update: I have downloaded macOS Big Sur beta 2 (20A4300b) and Xcode 12 beta 2, oddly labelled in the About box as 11.5 (11E608c). I have only found one thing that needs to be changed. I had set the deployment target to 11.0 but the new Xcode does not allow this as an option and the app fails to build. Change the deployment target to 10.16 to make it work.

Xcode 12 beta 6 error

It looks like Apple is having some problems with consistency in the new version numbers in both macOS and Xcode.

The New Project

As before, the first step was to create a new project in Xcode. I chose the macOS App template although the Multiplatform option was intriguing. When setting the options for the new app, I chose SwiftUI for the Interface, SwiftUI App for the Life Cycle and Swift (of course) for the language.

Once I had selected a save location and the project was open, I checked out the file structure. The main difference here was that there is no AppDelegate.swift file. Instead there is a file called “SwiftUI_Mac_11App.swift” where “SwiftUI_Mac_11” is the name of my app. This file is vastly simpler than the old AppDelegate but it sets up the app, the scene and the window group, with the expected ContentView as the main content.

ContentView.swift had a change too. Instead of setting the maxWidth and maxHeight of the view to .infinity, this Content View only adds some padding to the standard Text view. Time to see what happens when I run…

The first run took longer than I expected (I told you it was an old MacBook) but then a very small window appeared, just big enough to show the “Hello world!” text with its padding. The app has all the expected menus although I have no idea where they are set up.

Closing the app and using the Canvas preview worked much as before, although the canvas now has additional controls including a button to add another preview and a menu to configure each preview. Oddly, running the preview and clicking “Bring Forward” displayed two app windows. I presume this is an Xcode 12 beta “feature”.

I used the attributes Inspector to edit the Text view, setting text, font style and weight and color. I had read that Xcode 12 had much better auto-formatting, but when adding modifiers this way, they all ended up on a single line which was not pretty. Manually adding line feeds before each dot did give a very neat structure, so typing in modifiers will be my preferred method.

Editing the Layout

Now on to my own layout. As I did last time, I used a static list to make a NavigationView for preliminary testing.

struct ContentView: View {
    var body: some View {
        NavigationView {
             List {
                 ForEach(1 ... 10, id: \.self) { index in
                     NavigationLink(destination: Text("\(index)")) {
                         Text("Link \(index)")

When I ran the app or looked at it in the Canvas it looked great, but when I clicked a link in the sidebar, the window shrunk to an unusably small size. So I added a frame modifier to the destination view. And I also set the ListStyle to SidebarListStyle() which gave the new macOS 11 full height sidebar look.

But here is where I encountered the first major difference. When I selected an item in the sidebar, the app correctly showed the detail view. But if I put the app into the background, this detail view disappeared. It literally disappeared because I was able to track that it was calling its onDisappear modifier.

After a lot of testing, several days of frustration and help from Jordan Singer with his mail-swiftui-sample project, I was finally able to work this out. The difference is that the initial view has to specify what comes next as well as what it is displaying. So in the initial NavigationView, I had a List, but I also needed some view to show that I was going to show another view in another column. This second column view has to reserve the space for the detail view to come.

I have no idea how Jordan worked this out, but I am very grateful. What I ended up with was this:

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                ForEach(1 ... 10, id: \.self) { index in
                                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    ) {
                        Text("Link \(index)")

            Text("Select a link...")
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        .frame(maxWidth: .infinity, maxHeight: .infinity)

The “Select a link…” text is shown when there is no destination view to display. And when I click one of the entries in the sidebar, its content replaces that Text view but keeps its frame.

Displaying Data

As with the previous app, I am displaying data from HTTP Cats. This part remains the same, so check back to the original article if you want to see how I did this. I did get warnings about the Decodable data structs I was using. My normal pattern when I want data to be Identifiable is to use something like this:

struct HttpSection: Identifiable, Decodable {
    let id = UUID()
    let headerCode: String
    let headerText: String
    let statuses: [HttpStatus]

But with Xcode 12, this gives an error. The error messages seem much more useful than before and they offered two suggestions. I tried what appeared to be the easier one of making the id mutable, but that stopped the decoding from working, so I added a CodingKeys enum to each struct to restrict the keys that would be included.

enum CodingKeys: String, CodingKey {
    case headerCode
    case headerText
    case statuses

When the app ran, I had a sidebar with collapsible sections. I wasn’t that happy with the default look of the section headers and the disclosure marker for the first header was positioned beside the text instead of at the right, but I do like the selected item lozenge look. I set a frame height for the section header view and that made the spacing better but the disclosure mark for the first header was still incorrectly positioned.

Initial collapsible sections

The Detail view to be displayed when a status is selected had no major changes, so I dropped in the file from the previous app, without the extra bits to do with notifications and preferences. However since SwiftUI now includes a ProgressView, I swapped out my “Loading…” text for a indeterminate progress twirly.

Three Column Layout

Since the collapsible sidebar wasn’t looking good, I decide to try for a three column layout with the categories in the first column, the codes for the selected category in the second column and the detail view in the third column.

The way I implemented this was to have the first list only show the section headers with NavigationLinks to a sub menu. To reserve the column layout, I had an empty submenu after the main list.

In the second column, I showed the sub-headers with NavigationLinks to the DetailView. This view reserved the space for the third column with a Text view that changed its text depending on whether that submenu was displaying anything or not.

I expanded the menu items to be big and chunky, which I feel fits the new style. The only remaining problem was that with the primary list set to use SidebarListStyle(), it only ever showed the first item. I had to change this to InsetListStyle() to see all the items! This lost the full height sidebar effect, but I assume this is a temporary bug.

Three column layout

Now I had the layout equivalent to what I ended up with after part 1 of my original series, so it was time to explore menus, which are very different. In the old style SwiftUI apps which were wrapped in AppKit, the menus were in a storyboard that you could edit. Now you add commands to the app’s WindowGroup to alter the menus.

The easiest way is to add a completely new menu, but it is also possible to insert new menu items after or before certain standard menu items.

Here is how to add a new Utilities menu with three items:

struct SwiftUI_Mac_11App: App {
    var body: some Scene {
        WindowGroup {
        .commands {
            CommandMenu("Utilities") {
                Button(action: {}) {
                    Text("Dark mode")

                Button(action: {}) {
                    Text("Light mode")

                Button(action: {}) {
                    Text("System mode")

A CommandMenu adds a new menu and it is always positioned between the standard View and Window menus. To add items to an existing menu, you need to use a CommandGroup and tell it where to appear. It can be after or before various standard menu items. Look up the docs for CommandGroupPlacement to see which items you can use as positional markers. I used after .windowArrangement.

Weirdly, the font, color and spacing of these menu items was different to the standard menu items. I can only assume this is a bug which will be fixed. I faked the proper look with modifiers, but it didn’t feel right. This screen shot shows the default look with the three mode items being my additions to the standard Window menu.

Menus with incorrect formatting

I tried using Labels to add an icon to the menu item. As I was switching between view modes, I wanted to have a checkmark before the selected menu item. This worked when first drawn, but the menus did not refresh when the data changed, so that was no use.

I also tested using Divider() to get a menu separator. It worked, but the look didn’t match the standard dividers. So menus need a lot of work still…

I kept the technique of having menu items publish notifications that other views could pick up. This seems to work well. I would have liked to have certain menus or menu items only appear conditionally or perhaps enable/disable conditionally, but I could not see how to do that. Since menus do not appear to update when data changes, this may not be possible right now.


There was one place where the new app architecture was amazingly good and that was to do with preferences. In my previous attempt at this app, I had a Preferences window and it was a major exercise to stop it opening more than once. This time, it was super easy. In the App.swift file, beside the WindowGroup, I added Settings which contained a view which had the UI for my app’s preferences.

This caused a few errors at first, but I added a @SceneBuilder property wrapper to the App’s body and that fixed the errors.

struct SwiftUI_Mac_11App: App {
    @SceneBuilder var body: some Scene {
        WindowGroup {

        Settings {

These three lines of code added a Preferences menu item and hooked it up to my SettingsView. This view opens in a new window when the Preferences menu item or keyboard shortcut is used and only one copy of this window ever appears.

Then on to the second brilliant thing about preferences: @AppStorage. In the previous version, I used a custom property wrapper to wrap settings that I wanted saved into UserDefaults. This is now built into SwiftUI and this was all I had to do:

    @AppStorage("showCopyright") var showCopyright: Bool = false

Now any time that variable was accessed, it was read from UserDefaults and every time it was changed, it was written back into UserDefaults. Instant preferences in a single line!

To pass this setting to a different view, all I had to do was give that view this same declaration. And it just worked!

Opening Another Window

Last time, I tried lots of different ways using hosting controllers, storyboards etc. to open secondary windows. This time I decided to stick to using sheet since it seems to be what works best for SwiftUI apps. So I added my User Interface Elements sample window as a sheet.

The view itself was reasonably similar except that last time, I used an NSViewRepresentable to embed an AppKit color well into the view. This time I was able to use the new SwiftUI ColorPicker which made it much easier to get the color back into the main view. I also added the new date and time pickers.

The color picker worked really well except that there is an option to specify whether the picker should support opacity or not. I found that no matter what I chose here, I never got the option to chose a color with opacity.

The date picker was good. It showed the date numerically using my local format - DD/MM/YYY. Clicking on any of the elements popped up a calendar view. The time picker was not so easy to use. Again, it showed the time in my format e.g. 7:53 pm. But there was no graphical entry, you click on an element (hour, minute or am/pm) and type. This would be OK except that every time you type, the focus jumps back to the hour. I found this confusing.

One big improvement is the ability to apply a keyboard shortcut to a button. When I set the keyboard shortcut for the Close button to .defaultAction, the button got the default appearance and was triggered by pressing the Return key.

    Button(action: {}) {

I was still unable to work out how to set the focus to a TextField. There are two new property wrappers to do with focus, but I understand they are not yet operational.


I have already used a sheet to display the UI elements and ActionSheets are not available on macOS, so that just leaves Alerts and file dialogs. File dialogs work identically in the app although they look quite different on Big Sur. Alerts look quite different but I think they are nice. Since the app icon is a prominent part of the dialog, I added one to make it look good. I understand that different numbers of buttons will get arranged in different ways.

Alert dialog

Other Improvements


Do a search for “self.” and get rid of them all. Your code will be much cleaner and easier to read and SwiftUI now understands what you mean. If you want to read more details about this change, check out swift-evolution proposal SE-0269.

iOS had the concept of setting a navigation title but it didn’t really work in macOS. Now you can set the navigationTitle of a view and this will be the window title.


This was an aspect of macOS apps that I referred to but didn’t explore last time mainly because I assumed it would be done through the storyboard, just as with an AppKit app. Now we can add a .toolbar modifier to a view and have it include ToolbarItems. For the first time, we can now use SF Symbols in a macOS app, so that made it easy to add good looking toolbar items.

Toolbar and navigation title

I would like to vary the toolbar according to what is being displayed, and the toolbar is also used to show the navigation title, but perhaps that is a topic for another day. There is certainly a lot to explore there.

Pyramid of Doom

With menus and toolbars, there is a heap of extra code added to certain views. I would love to be able to extract that into its own function or view modifier. I was able to extract the toolbar, but I am not sure how to do this with menus yet. I imagine it will need some specific sort of ViewBuilder but I think this is very necessary. Perhaps the topic for yet another article…

The project is available on GitHub. As always, if you have any comments, suggestions or ideas, I would love to hear from you. Please contact me using one of the links below or through my Contact page. Thanks for reading.

Thanks to Sungbin Jo (조성빈) for proof-reading and suggestions.

SwiftUI Snapshot Testing

Permalink - Posted on 2020-05-17 08:50

Snapshot testing is a technique that has been very popular in the web development world and it seems like a great way to test SwiftUI user interfaces. I read about snapshot tests in a recent blog post and was intrigued, but I had some difficulty getting it to work, so when I finally succeeded, I decided to share my experiences in the hope that others will find them useful.

What is Snapshot Testing

Unit testing checks that when you call various functions or methods with certain inputs, you get the output you expect. I use unit tests for testing my models and the methods that change them. But this only tests the logic behind the app, it does nothing to test whether the app is displaying what it should, or whether it is responding correctly to the user’s actions.

UI testing emulates user actions by faking taps, clicks, text entry and so on and checks that labels, buttons etc are showing the correct information after these fake interactions.

Snapshot testing is in between these two as it effectively takes a picture of the interface. The first time you run the test it will store an image and all subsequent test runs will check that the current interface matches this stored image. If there are any differences, the test will fail so you can decide whether to keep the new version or revert to what you had before.

How did I get started?

I first read about the idea of using snapshot testing for SwiftUI in a blog post by Vadim Bulavin. He made a very good argument for this, but I found his instructions assumed more knowledge of the topic than I had at the time and so I discarded the idea after an initial attempt.

But he was suggesting using a snapshotting library published by Point-Free and I later discovered a link to one of their videos where they discuss this exact thing: SwiftUI Snapshot Testing. This was enough to get me going with attempt #2.

Setting up an app for snapshot testing

Since the blog post and video were talking about iOS apps, I decided to start there, but you know me, I will get to macOS apps later…

First off, I created a single view iOS app using SwiftUI making sure to check “Include Unit Tests”, but not “Include UI Tests”. I created a simple view so I had something to test.

If you want to use this on an app that does not already have a unit tests target, go to the project settings, click the + button to add a new target and choose a Unit Testing Bundle.

Next step was to import the snapshot testing library using Swift Package Manager. Go to File > Swift Packages > Add Package Dependency. Paste in the URL below and click Next.


I accepted the default versioning suggestions on the next pane.

Adding the snapshot package

On the final pane, it is important to select the correct target for this package. Select the app’s test target, not the app itself and not the UI test target if you have one. I made this mistake on my first try as I assumed that snapshot testing would be part of UI testing but it is actually part of unit testing.

Setting the package target

Writing a Snapshot Test

Now I added a new Unit Test Case Class file to the tests target in my app. I had to import SwiftUI and SnapshotTesting into this test file as well as declaring the app as a testable import. The easiest way to do this is to copy the @testable import heading from the sample test file to make sure it is exactly right. The import needs to match the name of your app module.

Finally it’s time to write the first snapshot test:

import XCTest
import SnapshotTesting
import SwiftUI
@testable import Snapshots

class SnapshotsTests: XCTestCase {

    func testDefaultAppearance() {
        let contentView = ContentView()
        assertSnapshot(matching: contentView, as: .image)


This uses the snapshot library’s assertSnapshot method to save the content view as an image. But unfortunately, this doesn’t work. The problem is that the second parameter is a Snapshotting strategy that can convert various UI elements into some form of data or image. But the library doesn’t know what a SwiftUI View is, so it needs a way to convert the view into something that can be recognized by the snapshotter.

I added this extension to SwiftUI’s View that wraps the SwiftUI View in a UIHostingController. It returns this as a UIViewController which is a valid input for a snapshotter and can be converted to an image.

extension SwiftUI.View {
    func toVC() -> UIViewController {
        let vc = UIHostingController(rootView: self)
        vc.view.frame = UIScreen.main.bounds
        return vc

Now my first test became:

    func testDefaultAppearance() {
        let contentView = ContentView()
        assertSnapshot(matching: contentView.toVC(), as: .image)

And it worked. Or rather it failed as expected because there was no image to compare it with.

Test result

Checking the error message, I was able to see where it had created the snapshot image file which I could look at. And the second time I ran the test, it passed.

Test image in Finder

If you ever get an error message saying “No such module ‘SnapshotTesting’” use Shift-Command-U to re-build for testing. This usually only happens after you have cleaned your build folder.

Testing a Change

Now that I had a passing test, the next thing was to check what happens if the UI changes. This may be due to a deliberate change or because the cat just walked across your keyboard (a not infrequent occurrence around here).

Where I originally had a button with the label “Save”, I decided to change this to “OK” (rejecting the cat’s suggestion of “q2eegrnh”).

Running the test again produced this result:

Failed snapshot test

And I was then able to compare the 2 images, using the path to the failing image from the error message.

Test results: success and failure

Once I had confirmed that the new image was what I wanted and not a result of error, either feline or human, I set the test to record a new result so that the new version became the official test version.

    func testDefaultAppearance() {
        let contentView = ContentView()

        record = true
        assertSnapshot(matching: contentView.toVC(), as: .image)

This caused a failing test again as the new version was written to the Snapshots folder, but after removing the record = true line and re-running the test, it passed again, with my new button label now an accepted part of the test.

Using Snapshots with State

In SwiftUI, the UI displayed is a function of state, so changing state properties changes the UI. This is what makes snapshot testing really good for SwiftUI apps as you can change the state programmatically and confirm that this is reflected in the UI.

So having proved that the snapshot tests worked, I decided to move on and test it with my new anagram assistant app. This is quite a simple app that has a single AppState class that holds all the program data.

So I was able to write a suite of tests that changed the state in various ways and then snap-shotted the UI with that state. Here are a couple of examples:

    func testEmptyContentView() {
        let contentView = ContentView()
        assertSnapshot(matching: contentView.toVC(), as: .image)

    func testAfterLocking() {
        var contentView = ContentView()

        let appState = AppState.sampleState()
        appState.selectedLetterIndex = 1
        appState.placeSelectedLetter(at: 3)

        contentView.appState = appState
        assertSnapshot(matching: contentView.toVC(), as: .image)

This worked really well with only one slight problem. As the state arranges the availableLetters array randomly for display, I had to add a sort to make sure they always displayed in the same order and made the tests repeatable.

And as a bonus, I was able to test a screen in dark mode with this test which sets the colorScheme:

    func testDarkMode() {
        var contentView = ContentView()
        contentView.appState = sampleAppState()

            matching: contentView.colorScheme(.dark).toVC(),
            as: .image)

Accessibility Tests

iOS supports dynamic type and if your app uses standard font styles, it will adopt these dynamic sizes automatically. I can’t find the link right now, but I remember reading an article that said nearly half of all iPhone users change the default text size, setting it either smaller or larger.

With snapshot testing, it is quick and easy to get a view of how you app looks with different font sizes. Here is my test function for taking a snapshot of every possible font size variation.

    func testDynamicFonts() {
        var contentView = ContentView()
        contentView.appState = sampleAppState()

        for contentSize in ContentSizeCategory.allCases {
            assertSnapshot(matching: contentView.environment(\.sizeCategory, contentSize).toVC(),
                           as: .image,
                           named: "\(contentSize)")

For the settings screen, I decided that smaller fonts were not a problem, but I wanted to check the two largest options, so I used this test function:

    func testSettingsScreen() {
        let settingsView = SettingsView()
        assertSnapshot(matching: settingsView.toVC(), as: .image)

            matching: settingsView.environment(
                \.sizeCategory, ContentSizeCategory.accessibilityExtraExtraExtraLarge
            as: .image,
            named: "AccessibilityXXXL")

            matching: settingsView.environment(
                \.sizeCategory, ContentSizeCategory.extraExtraExtraLarge
            as: .image,
            named: "XXXL")

Dynamic font tests

This let me quickly see where the problems were and what I needed to adjust.

Snapshot Test for Mac Apps

You knew you weren’t going to get through this without me going on about Mac apps…

Snapshot tests for a Mac app work well, with one caveat.

First I had to change the Swift.View extension so that it returned an NSViewController instead of a UIViewController.

extension SwiftUI.View {
    func toVC() -> NSViewController {
        let vc = NSHostingController(rootView: self)
        vc.view.frame = CGRect(x: 0, y: 0, width: 1024, height: 768)
        return vc

I chose an arbitrary size for the snapshot, you just need to make sure your UI will fit into whatever size you select.

The real problem was with sand-boxing. The snapshot library was blocked from writing the image files to the project directory if the app was sand-boxed. This seems really peculiar, since Xcode is running the tests and Xcode writes to the project directory all the time!

I found two ways around this:

  1. Turn off sand-box mode temporarily while testing.
  2. Make a non-sand-boxed target and use it for testing against.

Neither of these are particularly great. Option 1 is tedious, although I think it can work if the snapshots remain the same, it only fails if there is a change that it needs to write to disk.

Option 2 is tedious to set up (contact me if you would like more details) but is more seamless after that.

The best solution would be for Xcode to allow you to turn off sand-boxing for a test target. Maybe Xcode 12…

Limitations of Snapshot Testing

Ignoring the Mac and concentrating only on iOS apps for the moment, there were a few issues:

  1. You have to run your tests against the same simulator every time, or at least against a simulator with the same screen dimensions. I decided to to use the iPhone SE (2nd generation) as it has a small screen and I find smaller screens to be more of a problem than large ones. You also need to make sure it is always using the same appearance: light or dark, unless you want to specify this for every test.

    I ended up with this setup function that ran before my snapshot test suite:

    static override func setUp() {
        let device = UIDevice.current.name
        if device != "iPhone SE (2nd generation)" {
            fatalError("Switch to using iPhone SE (2nd generation) for these tests.")

        UIApplication.shared.windows.first?.layer.speed = 100

        record = false

This uses a couple of tricks that are supposed to speed up tests and has a record setting that I could set for the entire suite if I wished, and it throws a fatalError if I select the wrong device or simulator.

It would be neater if Xcode allowed you to select a simulator in the test target build settings, but I think you can only do this if you run tests from the command line.

  1. Snapshot tests confirm that the UI matches the state, but they do not check to see if the state changes in response to user input. That is the missing link that UI testing provides, but even without that, I believe that snapshot testing is a very useful tool and much better than having no form of UI testing at all.

  2. You need to look at your snapshots. This may sound obvious but the snapshot library creates a set of images. These images are then set as the goal for future tests. If you don’t check that they are correct, then every test could be confirming that the UI is wrong but unchanged. If the tests report a difference, look at both copies and see which one is right. For the same reason, the snapshot images need to be included in your version control repository.


Will I use snapshot tests for my SwiftUI apps? Yes, definitely. I use unit tests for my model classes but mostly avoid UI tests as they are too clumsy to write and time-consuming to run. Snapshot tests are better for SwiftUI, and very fast.

Huge thanks to Vadim Bualvin for the original inspiration for this article. Go and read his blog post for a more detailed look. And thanks to Brandon Williams & Stephen Celis at Point-Free for getting me going after my initial discarding of the idea. Any mistakes or errors are mine and not theirs.

If you want to learn about UI testing for SwiftUI apps, I recommend watching azamsharp’s YouTube video: User Interface Testing for SwiftUI Applications.

As always, if you have any comments, suggestions or ideas, I would love to hear from you. Please contact me using one of the links below or through my Contact page.

Name This App

Permalink - Posted on 2020-05-09 01:26

My current work in progress is an iPhone app designed to make it easier to solve crossword anagrams by emulating and improving upon an ability that was there when we used to do crosswords on paper, but is missing for digital crosswords.

But I cannot think of a clever name for the app, so please read the story and contact me with your name suggestions or if you would like to test the pre-release version of this app.

Cryptic Crosswords

Programmers are basically puzzlers, and programming is the world’s best type of puzzle, but I like to start my day with a cryptic crossword. Like programming, cryptic crossword clues have their own syntax and what seems like gibberish on a first glance, can be parsed into logical parts to take you to the answer. But there are aspects of solving crosswords that were easier with pencil and paper, so I decided to write an app to help fill one of those gaps.

My crossword of choice is the Crosaire crossword from The Irish Times. A lot of newspapers have a cryptic crossword and most of them need a subscription, but the Irish Times has a crossword only subscription that I really like. Crosswords also tend to require some local knowledge, but for the Crosaire, if you remember that the Abbey and the Gate are both theatres and that Down is a county, you will have most of what you need. And as an added bonus, the crossword creator later blogs the solutions with explanations so you can learn how the clues were constructed if you are totally mystified.


Anagrams are a very popular clue type but they can be tricky to solve because our brains are too good at discerning patterns. We can recognize words using only the first and last letters if they have the correct number of letters inside. This means that asking our brains to scramble these letters into a completely different word is very difficult. In the olden days, when I used to do crosswords in the newspaper, the best method was to find a space in the margin and write the letters out in a circle which forced my brain to reconsider the options.

Here is an example from a recent Crosaire:

Users rip off revelation (8)

The word “off” is a hint that this is an anagram, “Users rip” has the right number of letters, so the overall clue must be “revelation”. This is not a very long anagram and I think having two words makes it easier, but lets take a look at how I would solve this the old-fashioned way. (And I knew the “I” was the third last letter.)

Anagram solving manually

If you watch this gif and then look at it when it stops repeating, hopefully you will be able to see that the answer is “SURPRISE”. Refresh the page if you want to start the gif looping again.

But I do crosswords on my iPad now and while I could use a notes app and my Apple Pencil to draw the letters out like I did in the GIF above, I don’t always have the Pencil with me and I want to keep looking at the crossword. So I decided that a companion iPhone app was the way that would work best for me.

There are sites and apps that offer anagram solvers, but they are just looking through a dictionary and showing you all the possibilities. To me, this feels like cheating, but I don’t have a problem with using an app to emulate the techniques I used to use with pencil and paper.

App Design

So I planned out the basic features of the app:

  • enter a word
  • display the letters in a circle
  • shuffle these letters if needed
  • place letters in a possible solution

Arranging the letters in a circle was made relatively easy by using SwiftUI. I placed the letters in a ZStack so they were all piled on the one spot. Then I calculated the X & Y offsets needed to move each letter to the edge of a circle. This involving digging out some long-forgotten trigonometry to convert from polar coordinates to rectangular coordinates. I could calculate the radius of the letter circle based on the screen size and the angle between each letter was 360 degrees divided by the number of letters. So some quick calculations converted these two numbers into X & Y coordinates for each letter, and then I had my circle.

    var radiansBetweenLetters: Double {
        let degrees = 360.0 / Double(anagramLetters.count)
        let radians = degrees * .pi / 180
        return radians

    var radiusForCircle: Double {
        let screenWidth = UIScreen.main.bounds.width
        return Double(screenWidth * 0.35)

    func XoffsetForLetterAt(index: Int) -> CGFloat {
        // x = R cos t
        let totalRadians = radiansBetweenLetters * Double(index)
        let x = radiusForCircle * sin(totalRadians)
        return CGFloat(x)

    func YoffsetForLetterAt(index: Int) -> CGFloat {
        // y = R sin t
        let totalRadians = radiansBetweenLetters * Double(index)
        let y = radiusForCircle * cos(totalRadians)
        return CGFloat(y)

The original word was converted into an array for display, so re-arranging the letters was a matter of calling shuffle() on the array which automatically triggered a SwiftUI redraw.

And here is version 1 of the interface running in the SwiftUI Canvas:

Anagram app version 1

Refresh the page to see the gif play, if it has stopped.

A Different Type of Anagram

Now we come to a variation of the anagram clue that is very popular with the author of the Crosaire crossword. I don’t know if there is an official name, but I call them “subtraction anagrams”.

Here is an example:

Creationist has no taste for what’s sarcastic (6)

The idea here is to remove the letters in “taste” from the letters in “Creationist” and then unscramble the remaining letters to find a word that means “sarcastic”. My first attempt at this used a Trash can button that removed the letter and shortened the space for the solution, but then I decided to have a discard tray at the bottom of the screen to show what had been removed and allow replacing any letters discarded by mistake.

Anagram discard tray

After this, I added a bit of style to make it look nicer and then moved on to the next feature. If I knew some of the cross letters already, I wanted to be able to place them in the solution squares and then lock them in place. This would allow me to shuffle in letters to test and remove all the unlocked ones with a button click. So here is what the app looked like after those changes:

Anagram with locked letters

Refresh the page to see the gif play, if it has stopped.

Drag & Drop

My next experiment was with drag & drop to place or discard letters. I waited until iOS 13.4 brought drag & drop to SwiftUI but I was not happy with the result. Firstly, there is a big lag on dragging. You have to hold your finger down on a letter for quite a while before it becomes draggable. This was so counter-intuitive that I thought it wasn’t working, but occasionally it did work and so I eventually deduced that it was a timing issue.

The second problem was solved thanks to a suggestion by Luis Ramos on Twitter. When I dragged a letter, the drag preview image was the shuffle button from the middle of the ZStack instead of the selected letter. This was solved by moving the onDrag modifier to BEFORE the offset modifier (not AFTER like I said in my original response to Luis). But I was still not happy with it, so I decided to discard this idea and stick to tapping.

There was one side-effect: I wasn’t able to get the drag preview to be round - it was a square with opaque corners. As a work-around, I changed the letters to be inside squares and then decided this was a better look anyway, since it was more like what you see in a crossword.

Further UI Enhancements

I installed a custom font so that it looked more like hand-writing. I wrote about installing custom fonts in a separate article, so if you are interested check that out for details on the multiple steps that you need to take to get them to work. I went through a few different fonts until I found one that I thought worked well and clearly for all the upper case letters but I settled on Oregano. And then I made the app work in dark mode too:

Custom font and dark mode

The clue for this one is “Consumables minus bacon and shellfish (6)”


SwiftUI has animation built in, so I was able to add an animation modifier to the various views to make the transitions look smooth. I particularly liked the way the letters re-arranged themselves around the circle when I removed or replaced a letter.

But to add something extra, I thought it would be fun if the letters all started in the middle and moved outwards to their places on the circle. The way I did this was by using a Boolean to store whether the letters had had their first draw. If not, the radius of the circle was zero, so they all piled in the middle. After a delay, this Boolean was toggled so the radius was changed to the full size and the animation modifier already applied, made the letters smoothly expand outwards.

For the letter shuffle, I did the reverse, moving the letters in, shuffling, then moving them out again.


Refresh the page to see the gif play, if it has stopped.

I also added sound effects and a slide-up sheet view with settings and help. I enjoyed using Apple’s SF Symbols to show icons for each paragraph of the help, although I may change the colour of these icons as they look at bit too much like buttons right now.

Help & Settings

Next Steps

Well, I am hoping that someone will come up with a good name. I thought of “Anagram Assistant” but that doesn’t fit underneath the home screen icon and it was shortened to “Anagram”. I don’t want people to see it and think it is just one of those dictionary lookup anagram finders, so I would like something more descriptive while still being short, or at least having a short variant.

In honour of P.G.Wodehouse’s favourite crossword clue, I thought of calling it “E blank U” but that isn’t an anagram, so it doesn’t really work. For people not familiar with that reference, Wodehouse’s less quick-witted characters always get stuck on “Large flightless Australian bird, 3 letters. E blank U”.

A clever name would be good - perhaps an anagram itself? If you think of anything, please let me know on Twitter, by using the email link below or through the Contact page. The namer will get full credit in the app. And use one of those methods to contact me if you would like to test the app before it is released.

Once I have a name, I can get to work on the usual secondary tasks which take so much time: App Store set up, screen shots, a support page and so on.

I haven’t tried an iPad version yet. I got stung once by testing an iPad version of an app, deciding it didn’t work well and then running into Apple’s ban on dropping a platform from a published app. This has discouraged me from iPad apps ever since, which I doubt was their intention.

And if you are curious about the solutions to the clues I used in the examples:

Users rip off revelation (8) = SURPRISE
Creationist has no taste for what’s sarcastic (6) = IRONIC
Consumables minus bacon and shellfish (6) = MUSSEL

SwiftUI Color

Permalink - Posted on 2020-05-09 01:26

As developers, we are used to thinking of color as a numeric way to specify a particular tint. But in SwiftUI, Color - like almost everything else - is actually a View in its own right. This leads us to two very interesting questions: how do we use a view to specify a color and how can we use the fact that Color is View?

Specifying a Color

To start my investigations of Color, I created a new iOS single view app in Xcode. Regular followers will know that I am a passionate advocate of macOS programming, but when experimenting with SwiftUI, I prefer to use an iPhone app as the preview canvas fits very neatly into the main Xcode window.

The default ContentView contains a single Text view. To change the color of the text in this view, I added a modifier:

  Text("Hello, World!")

The foregroundColor modifier expects a Color so there was no need to tell it that the parameter is a Color and I was able to use the short way of describing one of the standard colors.

Adding a background color is a bit different because a background can be any view, not just a color. So the modifier needs to specify that this is a Color view, as well as setting the actual color.

    Text("Hello, World!")

I added the padding to make the overall size bigger so that the background color was more obvious.

Command-click on .red or .yellow in the code and select “Jump to Definition”. This lists the available pre-defined colors. As well a set of basic colors and a clear option, there are two extra entries: primary & secondary. And if you scroll back up the page a bit, you will see another one: accentColor.

Choosing one of the preset options is the easiest way to select a color. But try this:

In your code, type let uiColor = UIColor. and have a look at the auto-complete suggestions that appear after you type the period. Scrolling past the various init methods, you will see that UIColor has a lot more options than Color. There are a bunch of colors, a section of system colors and a lot of semantic colors like placeholderText, secondarySystemBackground.

Why does UIColor get these other useful looking options and Color does not?

Well, I don’t have an answer to that except that I hope they will appear over time. But in the meantime, it is easy enough to create a SwiftUI Color from a UIColor.

    let backgroundColor = Color(UIColor.secondarySystemBackground)

    var body: some View {
      VStack {
        Text("Hello, World!")

If you know the RGB values of the color you want to use, it is possible to create a Color directly by various methods like this one for setting the color using the RGB values.

    let rgbColor = Color(red: 1.0, green: 0.5, blue: 0.5)

But when you get to this stage, I strongly suggest that you start using color assets instead.

Using Color Assets

Go to Assets.xcassets and click the plus button at the bottom of the list of assets. Select “New Color Set” and you will get a new asset called “Color”. You can double-click the name to edit it to something that makes sense to you.

Add Color Set

While naming it after the color may seem logical, I prefer to think about the use cases for this color and set the name to something like “cardBackground” or “alertText”.

By default, your new color set will contains a single color block. Click in the color block itself and then you will be able to edit the color in the Attributes Inspector. If you click the “Content” popup, you will get access to all the system colors, and you can also select any color space and create a custom color using that color space. Click “Color Panel” to access a standard color picker if you need it. And change the input method to whatever suits the color information you have.

Edit Color Set

Modern apps need to be able to handle light and dark modes, and this is where using a color set really shines. Set the color to what you want to use for light mode and then choose “Any, Dark” from the Appearances popup menu in the Attributes Inspector.

Now your color set has two blocks and you can change the Dark one to whatever color this should be in dark mode. This feature of Color Sets is a very strong argument for using them instead of defining colors using their RGB values.

Light & Dark Color Set

And now for the really neat part. To use any of these color sets in your code, add a modifier like foregroundColor just the same as usual, but when the placeholder for the color is selected, press Shift-Command-L to bring up the Library palette and choose the Color icon at the right. You will see all your color sets there and you can insert them easily and accurately.

Using a Color Set

Here is the code for my AlertView using two color sets.

Some people may object to using “magic strings” to specify the color sets but I feel that so long as the Library is used to insert the color names automatically, there is very little chance of error. But you could always make an enum or struct of color name constants and use these instead.

struct AlertView: View {
    var alertText = "Something went wrong!"

    var body: some View {
            .shadow(color: Color("alertShadow"), radius: 5, x: 1, y: 1)

struct AlertView_Previews: PreviewProvider {
    static var previews: some View {
        Group {

And here is a composite image showing the two versions of the alert with the colors specified by two color sets:

Alerts Using Color Set

Light & Dark Mode System Colors

Color’s preset colors adapt automatically to the environment so that they work with dark mode or light mode just like your own Color Sets can.

I wrote a test view to loop through all the preset colors (except clear) and display their descriptions in their own color.

struct ContentView: View {
    let standardColors: [Color] = [
        .black, .white, .gray, .red, .green, .blue, .orange,
        .yellow, .pink, .purple, .primary, .secondary, .accentColor

    var body: some View {
        VStack(alignment: .leading) {
            ForEach(standardColors, id: \.self) { color in

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {

The canvas shows two previews: one for light mode and one for dark mode.

If you have a color picker app (I use Colorpicker), you can detect the RGB values in the two previews. I made the font bold to make this easier. Red is rgb(232, 77, 61) in light mode but rgb(233, 85, 69) in dark mode. And the others have similar modifications to make them look their best in each environment.

Take particular note of the three at the bottom of the list: primary, secondary and accentColor. These are incredibly useful when making a layout that works in both light and dark modes.

Color previews

When choosing a UIColor or NSColor, it is best to use the system versions, so .systemBlue instead of .blue as this gives the dark/light variants that we just saw. And the other semantic colors like UIColor.secondarySystemBackground also have dark/light variants automatically.

Color as a View

Now let’s consider the effect of Color being a view and not just a description of a tint. Imagine you wanted to draw a colored box on the screen. Using UIKit, you would probably think of using a UIView. With AppKit, maybe an NSBox. Or perhaps you would have jumped straight to a Bezier path.

Create a new SwiftUI view and replace the default Text with a Color, like this:

struct BoxView: View {
    var body: some View {

Resume the canvas preview and you will see the color fill the preview iPhone screen, except for the safe areas top and bottom.

To make this into a box, add a frame modifier with the required height and width. And now you have a box, far more easily than you could in either UIKit or AppKit.

To be honest, in SwiftUI, you would probably use a Rectangle instead of a plain Color if you wanted a box of a set size but it is interesting to consider how Color could be made to work.

A more valuable use of Color is to set the background.

struct BackgroundView: View {
    var body: some View {
        ZStack {

            Text("Hello, green background")

This makes the entire background green and shows the text centered on it.

And to make the color extend into the safe areas:


I prefer to put the edgesIgnoringSafeArea modifier on the Color only and not on the entire ZStack. That way the other contents of the ZStack will all stay inside the safe area.

So in summary, use preset colors or color assets to set your colors. And use the Color view to set a background color for a view.

I hope you found this article useful, and if you have any suggestions, corrections or improvements, please contact me using one of the links below or through the Contact page.

Custom Fonts in iOS & macOS apps

Permalink - Posted on 2020-04-01 00:27

As a rule, I prefer to use fonts that come pre-installed with the system. That means that your interface is already familiar to users, you get dynamic font sizing and if Apple updates the fonts, you get the updates without doing anything.

But sometimes, you really need to use a different font in your apps, and as the process of getting a custom font to display in your app can be confusing and tedious, I thought I would go through the steps for both iOS and macOS apps.

I probably should have published this on a different day, but it is not a joke…. really.

Getting a Font File

The first thing is to find a suitable font and make sure that the license for that font matches your use. I wanted a font that looked like it was hand-written, so I went to fontspace and searched the hand-writing category there.


Since I wanted to use this in a paid app, I checked the “Commercial-use” button to limit the search. The one I chose was called “Painting With Chocolate” by “Make mooze”

Download font

I downloaded the font and un-zipped the file which gave me a single file called “Paintingwithchocolate-K5mo.ttf”. You can use either “.ttf” or “.otf” font files.

Using the Font in an iOS App

Now to use the font, first in an iOS app. Boot up Xcode and create a new SwiftUI project for iOS.

Once the project is open, drag the font file into the Project Navigator. At this stage there are 2 crucial settings:

  • Check “Copy files if needed”.
  • Check your app in the “Add to targets” section.

Add font to project

In one of my tests, the file stayed in the Downloads folder even after checking “Copy files”, so I deleted the reference, manually moved the font file to my project folder and added it again.

Now the font file is in the project but there is still more work to do.

Select the font file in the Project Navigator. Press Return as if you are going to edit the name. Select the complete file name, including the file extension and copy it.

Copy font file name

Now go to the Info.plist file. Right-click in the blank space below the existing entries and select “Add Row” from the popup menu. In the box that appears, start typing “Font” using an upper-case “F”. When you see “Fonts provided by application”, select that.

This entry is an array. Click the disclosure triangle to the left and you should see “Item 0” appear. Paste the name of your font file, including the file extension, into the value for “Item 0”.

Setting Info.plist entry

Your app now has a font file and knows to make it available. But you aren’t finished yet.

To use a custom font, you need to know its exact name. In SwiftUI, the code will be something like this:

  Text("Hello, World!")
      .font(.custom("Font-Name-Goes-Here", size: 14))

But the exact name is not always obvious and is rarely the file name. So the best thing to do is to ask the app what fonts it now has available. This will also act as confirmation that the font file is being included correctly in your project.

To get the app to list all its fonts, I used this:

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .onAppear { self.listInstalledFonts() }

    func listInstalledFonts() {
        let fontFamilies = UIFont.familyNames.sorted()
        for family in fontFamilies {
            for font in UIFont.fontNames(forFamilyName: family).sorted() {

You can run the app in the Simulator or use “Debug Preview” to make this show up in the console, but once you have the list, scroll through in until you find the font you just added. The headers are the names of font families and the indented entries are the font names themselves.

List of Fonts

This time I found that the name of the font was quite obvious: “PaintingWithChocolate” but this is not always the case. And if the font has any variants, you will need to use the complete name e.g. “Optima-ExtraBlack”

With the name of the font, you are finally able to use it in the app, like this:

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .font(.custom("PaintingWithChocolate", size: 40))

Font in use - iOS

Using the Font in a Mac App

The process for a Mac app is mostly the same.

Install the font file in your project as before, making sure to copy the file into the project and to add it to the app target.

For a Mac app, you do not need to specify the font file name in your Info.plist file. Instead, you have to tell the Info.plist where to look for custom fonts in your project directory.

Open your Info.plist, right-click in the blank space below the existing entries and select “Add Row” from the popup menu. Start typing “Application” using an upper-case “A”. When you see “Application fonts resource path”, select that and enter a period as the value. A period or full-stop tells Xcode that you mean the current directory but even if you have your fonts in a sub-directory, this seems to work.

Application Font Path

You do not need to set “Fonts provided by application” for a Mac app, although if I had a problem, I would set it as I feel that this is something that Apple may add at some stage.

While I was using the same font for both apps and so already had the exact name, you may still need to check the list of installed fonts in a Mac app. The function for doing that is quite different:

  func listInstalledFonts() {
      let fontFamilies = NSFontManager.shared.availableFontFamilies.sorted()
      for family in fontFamilies {
          let familyFonts = NSFontManager.shared.availableMembers(ofFontFamily: family)
          if let fonts = familyFonts {
              for font in fonts {

The format of the print-out is different too, but you can see where I have selected the exact name to use.

List of Fonts - Mac

Then the SwiftUI code for using the font was just the same:

struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
            .font(.custom("PaintingWithChocolate", size: 60))
            .frame(maxWidth: .infinity, maxHeight: .infinity)

Font in use in Mac app

Storyboard apps

The examples above were both SwiftUI projects, but these techniques work much the same in a storyboard project.

Follow the same steps to install the font and configure the Info.plist file and use the same functions to list the installed files.

To use the fonts, if you are using a storyboard in an iOS project, select “Custom” in the font picker and then you will be able to see your custom font listed if it is installed correctly. I could not work out how to get the custom font appearing in this menu for a macOS app.

To apply the font programmatically, you can use something like this:

    // iOS
    fontLabel.font = UIFont(name: "PaintingWithChocolate", size: 36)

    // macOS
    fontLabel.font = NSFont(name: "PaintingWithChocolate", size: 24)


If you have gone through these steps and the font still isn’t working, here are a few things to check:

  1. Is the font file’s target membership set to the app? File target Set

  2. Is the font file being included in the “Copy Bundle Resources” build phase? If not, drag it in manually from the Project Navigator. Copy Bundle Resources

  3. iOS Info.plist - is there a typo in the “Fonts provided by application” setting? Copy the file name and paste it in directly rather than trying to re-type it.

  4. macOS Info.plist- have you put a single period “.” in the “Application fonts resource path” setting?

  5. Run the font name listing utility - does the font show up there?

  6. Have you used the font name EXACTLY as shown in the font listing? Copy & paste it from the font list.

Having struggled with various of these steps myself recently, I thought it was worth documenting it. I am sure that future me will be grateful, but hopefully others will find it useful also.

If you have any suggestions, corrections or improvements, please contact me using one of the links below or though the Contact page.

SwiftUI for Mac Extras

Permalink - Posted on 2020-01-27 01:32

Last year, I wrote a 3 part series of articles on using SwiftUI to build a Mac app. I would like to thank everyone who contacted me about this series. It was received very well and revealed that there is still a large amount of interest in programming for the Mac.

Some of the responses I got were pointing out different or better ways to do things, so I am going to list them here, adding to this post as I get new information. The relevant sections in the original posts will have links to the fixes suggested here, but I decided it was easier to list the changes in a separate post, rather than asking people to re-read the whole series looking for modifications.

Dismissing sheets

I just read your series on writing Mac apps with SwiftUI. Great stuff! Just wanted to add that in part 2 when dismissing sheets there are two ways to do that, one of them is the one that you figured out and the other is to have the view dismiss itself by grabbing its PresentationMode from the environment. This way you don’t need to pass presentation bindings to your sheet views.

Paul Hudson of Hacking with Swift explains how to use both methods very clearly in his article on How to make a view dismiss itself.

My original technique passed the Boolean that triggered the sheet to appear, as a Binding to the sheet view. The sheet view could then toggle this to make the parent view dismiss it.

  .sheet(isPresented: $sheetIsShowing) {
      SheetView(isVisible: self.$sheetIsShowing)
struct SheetView: View {
    @Binding var isVisible: Bool

    var body: some View {
        VStack {
            Text("This is a sheet.")
            Button("OK") {
                self.isVisible = false
        .frame(width: 300, height: 150)

The presentation mode method leaves it up to the sheet to dismiss itself. The parent view shows the sheet but does not pass any binding.

  .sheet(isPresented: $sheetIsShowing) {

The sheet view gets an environment property that it can use to change its presentation mode, dismissing itself that way.

struct SheetView: View {
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        VStack {
            Text("This is a sheet.")
            Button("OK") {
        .frame(width: 300, height: 150)

I guess the presentation mode method is slightly easier to understand and it leaves the caller of the sheet view less cluttered which is a good thing. But the two methods are functionally identical, so use whichever you prefer. The sample project now contains both methods, with one commented out, so you can swap the comments to test.

Subscribing on the Main Thread

In part 2 of this series, I created a menu item caused the downloaded image to be flipped. Selecting the menu item posted a notification:

    @IBAction func flipImage(_ sender: Any) {
        NotificationCenter.default.post(name: .flipImage, object: nil)

which the view showing the image was listening for.

    private let flipImageMenuItemSelected = NotificationCenter.default
        .publisher(for: .flipImage)

The outermost component of the view’s body used an onReceive modifier to get this notification and react accordingly.

  var body: some View {
      VStack {
        // layout omitted for brevity
      .onReceive(flipImageMenuItemSelected) { _ in
          DispatchQueue.main.async {

Since the notification was triggering a change to the UI, I made sure that this happened on the main thread.

But it was pointed out to me that it would be easier to make sure that the publisher was set up to use the main thread all the time, instead of having to specify the main queue when processing the notification.

So now the publisher is defined like this:

  private let flipImageMenuItemSelected = NotificationCenter.default
      .publisher(for: .flipImage)
      .receive(on: RunLoop.main)

And the onReceive modifier can toggle the imageIsFlipped flag directly, without having to worry about the thread.

This seems to me a much better solution as it sets the correct thread once when the publisher is created and makes using it much cleaner and easier.

Passing data back from AppKit

The previous two changes have been more a matter of style, but this one is a real error that would stop an app working as it should.

In the User Interface Elements section of the series, I used NSViewRepresentable to embed a standard NSColorWell in a SwiftUI view. I thought this was working properly, but then I got this email:

I noticed that the selectedColor in the EmbeddedColorWell is not being mutated and is not being used in a two-way manner. The selectedColor is initialized to NSColor.blue and used to set the color in the NSColorWell view. When the NSColorWell color is changed, it does change the color of the EmbeddedColorWell view. However, the actual @State var selectedColor value is never mutated in this process beyond the initialized value of NSColor.blue.

This is in the Form tab of the UI Samples window. As suggested to me, I added a background modifier to set the background of a portion of the view to the selected color. And although the NSColorWell showed newly selected colors, the background remained stubbornly blue.

The solution was to add a Coordinator to the NSViewRepresentable and have it subscribe to any changes in the color and update the embedded view’s selected color as needed. I would not have come up with this by myself, so many thanks to the person who sent it to me.

Here is the full code for the EmbeddedColorWell struct:

struct EmbeddedColorWell: NSViewRepresentable {
    @Binding var selectedColor: NSColor
    class Coordinator: NSObject {
        var embedded: EmbeddedColorWell
        var subscription: AnyCancellable?

        init(_ embedded: EmbeddedColorWell) {
            self.embedded = embedded
        // Observe KVO compliant color property on NSColorWell object.
        // Update the selectedColor property on EmbeddedColorWell as needed.
        func changeColor(colorWell: NSColorWell) {
            subscription = colorWell
                .publisher(for: \.color, options: .new)
                .sink { color in
                    DispatchQueue.main.async {
                        self.embedded.selectedColor = color
    func makeCoordinator() -> EmbeddedColorWell.Coordinator {
    func makeNSView(context: Context) -> NSColorWell {
        let colorWell = NSColorWell(frame: .zero)
        context.coordinator.changeColor(colorWell: colorWell)
        return colorWell
    func updateNSView(_ nsView: NSColorWell, context: Context) {
        nsView.color = selectedColor

In the previous section, I changed the publisher to use the main RunLoop so as to avoid having the use DispatchQueue.main.async. In this instance, that did not work so well. It only updated the selected color after the mouse had been released. But using DispatchQueue.main.async made the update live.

As I explained at the start of these articles, I was documenting my explorations in using SwiftUI for a Mac app and while I hoped there would be some useful examples, this was not intended to be a definitive guide. So I am very grateful to everyone who has contributed to these updates.

If you have anything more that you would like to be included, please contact me using one of the contact buttons below or through the Contact page on this site.

The edited project is available on GitHub.

SwiftUI for Mac - Part 3

Permalink - Posted on 2019-12-15 07:28

In part 1 of this series, I created a Mac app using SwiftUI. The app uses a Master-Detail design to list entries in an outline on the left and show details about the selected entry in the detail view on the right. In part 2 I explored using menus, adding all the expected user interface elements and opening secondary windows.

In this third and final part, I want to look at the various ways to present dialogs to the user.

There are four different types of dialog that I want to explore:

  • Alert
  • Action
  • Sheet
  • File dialogs (open & save)

So the first thing to do is add a footer to the DetailView to trigger each of these. I am going to separate this out into a new subview for neatness.


To make an Alert, I need an @State Bool which sets whether the alert is visible or not. All the button has to do is toggle that Bool. Stripping out the extra code and views, this is what I have.

struct DialogsView: View {
    @State private var alertIsShowing = false
    @State private var dialogResult = "Click the buttons above to test the dialogs."

    var body: some View {
        Button("Alert") { self.alertIsShowing.toggle() }

To configure the alert itself, I added an alert modifier to the outmost view in this view. The dialogResult string is a diagnostic that I can use to confirm that the results of the various dialogs get passed back to the parent view.

  Alert(title: Text("Alert"),
        message: Text("This is an alert!"),
        dismissButton: .default(Text("OK")) {
          self.dialogResult = "OK clicked in Alert"

There were a few things that tripped me up in this relatively short chunk of code. Firstly, both title and message must be Text views, not strings. If you get an error message that says “Cannot convert value of type ‘String’ to expected argument type ‘Text’”, then you have forgotten to use a Text view.

Then there is the button which auto-suggest tells me is of type Alert.Button. I couldn’t find any documentation for this, but delving into the definition for Alert, I see that there are three pre-defined button types: default, cancel or destructive. Cancel actually has two variants and will use a label appropriate to the user’s locale if no label is supplied.

Again, these buttons need a Text view as the label (if supplied) and can take an action closure, which I used to update my dialogResult string.

This version showed a single dismissButton but I saw that there was a variation of Alert with primary and secondary buttons. It was not obvious that these would also dismiss the alert dialog, but I tried anyway.

  Alert(title: Text("Alert"),
        message: Text("This is an alert!"),
        primaryButton: .default(Text("OK"), action: {
          self.dialogResult = "OK clicked in Alert"
        }), secondaryButton: .cancel({
          self.dialogResult = "Cancel clicked in Alert"

This worked very nicely and the Esc and Return keys triggered the two buttons as you would expect with both of them closing the dialog.


I tried using the destructive button type, but there was no difference to either the appearance or behavior of the button.

So Alert is a great choice for a text-based dialog, either for informational use or to allow two choices of action.


Very short section here - ‘ActionSheet’ is unavailable in macOS! I probably should have researched that before I started this section. So use Alerts, I guess or a custom sheet.


While Alerts have a very fixed structure, sheets allow us to put any SwiftUI view into a sheet dialog.

So I added another Bool for the Sheet button to toggle, and added this sheet modifier. SheetView right now is simply a TextView.

  .sheet(isPresented: $sheetIsShowing) {

This didn’t work so well. It showed the sheet, but the sheet was tiny - only the size of the Text view it contained. And I had no way of dismissing it…

The size problem was solved by setting a frame on the Text view in SheetView.

The trick to dismissing the sheet is to pass it a Binding to the Bool that triggered it to open in the first place. If a button in the sheet sets this Bool back to false, the parent view will hide the sheet. That sounds confusing, but it works.

  .sheet(isPresented: $sheetIsShowing) {
      SheetView(isVisible: self.$sheetIsShowing)
struct SheetView: View {
    @Binding var isVisible: Bool

    var body: some View {
        VStack {
            Text("This is a sheet.")
            Button("OK") {
                self.isVisible = false
        .frame(width: 300, height: 150)

Here is a very bad diagram that tries to explain what is happening:


The parent view has an @State Boolean variable called sheetIsShowing. This is bound to the alert’s isPresented so it dictates whenever the sheet is visible. When the Sheet button is clicked, this variable is set to true and the sheet opens. But at the same time, a Binding to this variable is passed to the sheet. I deliberately gave this a different name, so as to make it clear which View was changing what variable.

When the sheet wants to close, it does not close itself. Instead it sets this variable to false. Because it is a Binding, this sets the original sheetIsShowing variable on the parent view to false and the parent view then closes the sheet.

UPDATE: Look at Dismissing sheets in my post of extras & changes to this series for an alternative way to dismiss a sheet.

Sheets & Data

With this in place, I had the sheet opening and closing perfectly, but I was not yet passing data back & forth between the sheet and its parent view. I decide to put a TextField in the SheetView and bind its contents to the dialogResult property in the DetailView so that any edits appeared immediately in the DetailView. And while I am there, I might as well add some more decorations to the SheetView since it is a full View and not a restricted Alert.

Calling the SheetView changed to this:

  .sheet(isPresented: $sheetIsShowing) {
      SheetView(isVisible: self.$sheetIsShowing, enteredText: self.$dialogResult)

And the SheetView itself (not all the interface is listed here for brevity):

struct SheetView: View {
    @Binding var isVisible: Bool
    @Binding var enteredText: String

    var body: some View {
        VStack {
            Text("Enter some text below…")

            TextField("Enter the result of the dialog here…", text: $enteredText)

            HStack {
                Button("Cancel") {
                    self.isVisible = false
                    self.enteredText = "Cancel clicked in Sheet"
                Button("OK") {
                    self.isVisible = false
                    self.enteredText = "OK: \(self.enteredText)"
        .frame(width: 300, height: 200)

Sheet with data

I only had two issues with this now. I was not able to get the focus into the TextField automatically when the sheet opened and I was not able to assign keyboard shortcuts to the Cancel and OK buttons so that they could be operated without a mouse. And as I mentioned in the previous part, I was not able to make the OK button take on the default styling.

One useful technique that I developed: the SheetView is in the DialogsView.swift file instead of in its own SwiftUI file. It would probably be a good idea to separate it out but I didn’t which meant that it had no Canvas preview to look at while I was laying it out.

So I edited the PreviewProvider like this, so that I could change the comments to switch it between showing the DialogsView and showing the SheetView.

struct DialogsView_Previews: PreviewProvider {
    static var previews: some View {
        // DialogsView()
        SheetView(isVisible: .constant(true), enteredText: .constant(""))


AppKit provides NSOpenPanel for selecting a file and NSSavePanel for saving. I will try to implement NSSavePanel to allow saving the current cat image.

Since this is an AppKit control rather than a SwiftUI control, I assumed that I would need to use NSViewRepresentable like I did for the NSColorWell in part 2. But while NSColorWell is a descendent of NSView, NSSavePanel is not. So I need a new idea.

Rather naively, I thought maybe I could just create an NSSavePanel in a function inside DialogsView and see what happened.

  func saveImage() {
      let panel = NSSavePanel()
      panel.nameFieldLabel = "Save cat image as:"
      panel.nameFieldStringValue = "cat.jpg"
      panel.canCreateDirectories = true
      panel.begin { response in
          if response == NSApplication.ModalResponse.OK, let fileUrl = panel.url {

Crash & burn… so what if I made the NSSavePanel an @State property of the View? No, that crashed even faster. Maybe SwiftUI Views don’t like this sort of thing, but how about if I get the Application Delegate to handle it? What if I moved the saveImage method to the App Delegate and changed the calling function to access it there?

Still crashed. At this stage I am beginning to wonder if I know how to use an NSSavePanel. Time to create a simple test app without SwiftUI and see what happens. Well it appears that I no longer know how to use an NSSavePanel. Code from an older project that works fine, will not work in my new sample project!

Guess what - it was another macOS Catalina security issue which I would have realised faster I had opened the Console. Back to the Signing & Capabilities section of the target settings and this time I set File Access for User Selected File to Read/Write.

Now the NSSavePanel opens when called from DialogsView and prints the selected file URL if one is chosen.

But this is all happening in DialogsView, which is a subview of DetailView. And DetailView is the view that holds the image, not DialogsView. So how can I save the image? Do I pass the URL to DetailView or pass the image to DialogsView? Or do something clever with Notifications and Subscriptions?

I really don’t know what is best, but I have decided to post a Notification with the URL as its object. DetailView can receive this Notification and save the image whenever it is received.

So I replaced the print line in the saveImage() method with:

  NotificationCenter.default.post(name: .saveImage, object: fileUrl)

And in DetailView, I set up the publisher:

    private let saveImageUrlSelected = NotificationCenter.default
         .publisher(for: .saveImage)

    var body: some View {
        VStack {
          // view code removed for brevity
        .onReceive(saveImageUrlSelected) { publisher in
            if let saveUrl = publisher.object as? URL,
                let imageData = self.catImage?.tiffRepresentation {
                if let imageRep = NSBitmapImageRep(data: imageData) {
                    if let saveData = imageRep.representation(using: .jpeg,
                                                              properties: [:]) {
                        try? saveData.write(to: saveUrl)

And there we have it. Three types of dialogs demonstrated in a SwiftUI for Mac app:

  1. Alerts: good for simply text-only dialogs
  2. Sheets: good for more complex dialogs
  3. Panels: AppKit dialogs that can be called from a SwiftUI View.

I think this time I really am finished. This article has already expanded out into a 3-part monster, so I think it is way past time that I stopped typing. I hope you have enjoyed this series. Please use any of the buttons below to contact me or use the Contact page on this site. I would love to hear from anyone who found this series useful or who had any suggestions or corrections to make.

The final project is available on GitHub if you would like to download it and take a look.

SwiftUI for Mac - Part 2

Permalink - Posted on 2019-12-15 07:28

In part 1 of this series, I created a Mac app using SwiftUI. The app uses a Master-Detail design to list entries in an outline on the left and show details about the selected entry in the detail view on the right.

Now it is time to explore some more of the features of a Mac app with SwiftUI.

I had already discovered that the menu bar is configured in the Main.storyboard file. As an experiment, I will add new menu items that allows the user to select between dark mode, light mode or the system mode.


Looking at the possibilities along the top that I could send the menu command to, the App Delegate looks like the best option, especially since these menus will change the entire app.

I opened AppDelegate.swift in the Assistant Editor and Control-dragged from each of the new menu items to create the 3 IBActions and added the code to set the mode.

    @IBAction func darkModeSelected(_ sender: Any) {
        NSApp.appearance = NSAppearance(named: .darkAqua)

    @IBAction func lightModeSelected(_ sender: Any) {
        NSApp.appearance = NSAppearance(named: .aqua)

    @IBAction func systemModeSelected(_ sender: Any) {
        NSApp.appearance = nil

And since I realized that I would want to check or un-check these based on the current settings, I added IBOutlets for each of these menu items too. As a side note, I love how Xcode is now clever enough to decide whether to add an IBOutlet or an IBAction depending on where in the file you Control-drag to.

Using a Property Wrapper

Changing mode worked perfectly in the Xcode Preview and in the built app, but the app was not storing this or displaying the current selection with a check mark in the menu.

For storing the selection, I decided to try another new thing and use a UserDefaults property wrapper, based on this post by Antoine van der Lee.

I configured a UserDefault wrapped variable for the mode, set it whenever the menu items changed it and added a function to read it in and apply it on startup.

    @UserDefault("system_mode", defaultValue: "system")
    var systemMode: String

It would be neater to use an enum here instead of strings, but that would have required fiddling with rawValues to save the data, so for this first test, I stuck to strings.

The code to toggle the checkmarks in the menu items is standard stuff and nothing particularly SwiftUI related, so I won’t detail it here, but it is in the GitHub project if you are interested.

Dark mode

Passing menu data to a View

This worked fine and the app worked equally as well in dark or light modes, but I wanted to test how to communicate data back from the menus to the SwiftUI views.

As a totally pointless but possibly amusing feature, I decided to add a menu item to flip the cat image and then work out how I could send that to the ContentView.

I added the new menu item to the Format menu and as a first attempt, I tried to Control-drag from there into the ContentView. It didn’t take, so I guess I need to send the message to the AppDelegate as before and then pass it on to the ContentView. I feel like this might be a good place to use a Publisher although so far I have only used the built-in ObservableObject type publishers.

In this case, it would make more sense to have the DetailView respond to the menu, since it contains the image. But trying to add an @IBAction to a SwiftUI View struct gives this error: Only instance methods can be declared @IBAction so I am using the App Delegate instead. I feel like this is a problem I need to solve, or the AppDelegate is going to end up filled with @IBActions, but for now, let’s keep going.

In AppDelegate.swift, I added the IBAction for the Flip Image menu item and had it issue a Notification, after setting up an extension on Notification.Name to de-stringify the name of the notification.

    @IBAction func flipImage(_ sender: Any) {
        NotificationCenter.default.post(name: .flipImage, object: nil)

In DetailView.swift, I set up a Boolean @State property to store whether the image was flipped or not and added an onReceive handler to toggle it. Since this is updating the UI, I made sure that it happened on the main thread, but I am not sure whether this is necessary, or whether onReceive uses the main thread automatically.

UPDATE: Check out Subscribing on the Main Thread in my post of extras & changes to this series for an alternative way to make sure the updates happen on the correct thread.

    @State private var imageIsFlipped = false

    // ...

  .onReceive(flipImageMenuItemSelected) { _ in
    DispatchQueue.main.async {

Once I had that Boolean property, I added two more modifiers to the image. Don’t hate me for the force un-wrapping. I tried using if-let but it wouldn’t compile so I check for catImage != nil before using this force-unwrap.

  Image(nsImage: catImage!)
      .aspectRatio(contentMode: .fit)
      .rotation3DEffect(Angle(degrees: imageIsFlipped ? 180 : 0),
                        axis: (x: 0, y: 1, z: 0))

Now the image can be flipped from the menu item or even by using the keyboard shortcut. And with a smooth animation (smoother in the app than in this gif).

Flipping the image

Opening another window

For my next challenge, I want to open a second window that I can use to show samples of various UI elements. As I want to open it from a menu command, my first thought was to add a Window Controller to the Main storyboard and open it that way. I replaced the default View Controller with a Hosting Controller so that I could insert my SwiftUI View into it.

I had great trouble finding any documentation or examples of how to implement this, but after a lot of trial and error, here is what I got to work:

  1. Drag a Hosting View Controller into the storyboard and connect it to the menu item with a segue.
  2. Set the Presentation property for the window controller to Single so that multiple copies of the window are not created.
  3. Create a new Swift file and subclass NSHostingController. Don’t bother using a Cocoa class file - the template doesn’t work. Use the code below, replacing SamplesView with the name of the SwiftUI view you want to display.
import SwiftUI

class SamplesHostingController: NSHostingController<PrefsView> {
      @objc required dynamic init?(coder: NSCoder) {
          super.init(coder: coder, rootView: SamplesView())
  1. Back in the storyboard, set the class of the HostingController to this sub-class: SamplesHostingController in my case.
  2. Set a minimum size for the new Window Controller, otherwise it shrinks to a very small stripe on the screen.
  3. Add the .frame(maxWidth: .infinity, maxHeight: .infinity) modifier to the root view in the view you are displaying - my SamplesView.

With all these in place, I was able to open and close a Samples window that was displaying my SwiftUI content.

User Interface Elements

Not all the expected user interface elements are available in SwiftUI and some of the ones that are implemented are using different names. Again this is a point at which iOS development has got all the attention, so there are conversion tables out there listing UIKit elements and their SwiftUI equivalents, but I was not able to find a similar listing for AppKit. If you find one, please let me know.

Anyway, I experimented and got most of what I wanted as you can see below. The sample app on GitHub shows the SwiftUI code for these samples, but the main advice I would give is firstly to use the Object Browser to look for what is available and then to check out the styles that can be applied to the element you have chosen.

UI elements

Mostly, I managed to achieve what I wanted but there were a few exceptions.

Buttons were a bit odd as there are multiple button styles listed, but I found that they either all looked the same or they disappeared completely. I was not able to style a button with an image and text which is now easy to do in iOS. And I was not able to set a button as the default button and I could not work out how to set a keyboard equivalent for a button. (Setting the keyboard equivalent to Return or Enter might set it to the default style automatically.)

Of the other UI elements that I wanted to use, a color picker was the main one missing. So I decided to embed an NSColorWell from AppKit into my SwiftUI view.

The process for embedding a UIKit view is quite well documented elsewhere and the AppKit equivalent was not significantly different. Replace every “UI” with “NS” and you are nearly there.

First I made a struct that conformed to NSViewRepresentable and had the required two functions: makeNSView(context:) and updateNSView(_:context:). I supplied an @Binding variable to hold the selected color as an NSColor since that is what the NSColorWell uses.

struct EmbeddedColorWell: NSViewRepresentable {
    @Binding var selectedColor: NSColor

    func makeNSView(context: Context) -> NSColorWell {
        NSColorWell(frame: .zero)

    func updateNSView(_ nsView: NSColorWell, context: Context) {
        nsView.color = selectedColor

Back in my SwiftUI view, I was then able to use EmbeddedColorWell just like any other SwiftUI view, passing it a binding to an @State variable to set and get the selected color.

  EmbeddedColorWell(selectedColor: $selectedColor)

UPDATE: Be sure to read Passing data back from AppKit in my post of extras & changes to this series. This is an important fix that is needed to make this embedded control pass data back properly.

The other stumbling block that I encountered was that I had no way to close the window programmatically, in response to a button click or some other interaction. Maybe this was not the best way to open a fully SwifUI window, but it was still an interesting experiment.

One thing I learned while working on this project was that SwiftUI can be a bit too clever about working out what needs to be redrawn in the previews. If you edit something in an separate file to the View, you may need to force a re-build to get the updates to show.

Communicating Between Windows

The last feature that I need to explore is transferring data between two windows. I tested using a .sheet modifier to open a dialog and that worked exactly as it would in an iOS app - I was able to pass an @Binding variable to the sheet window and any changes made to that in the sheet window flowed back to the calling view.

But I want to set up a Preferences window which will be opened from the menu bar and not directly from the ContentView or any of its sub-views.

I started out by using the same technique as before with a Hosting View Controller. And here is where I came mightily unstuck as I could not make a data connection. I had hoped an EnvironmentObject would work, but I could not get an EnvironmentObject through to the HostingController as it was not in the same view hierarchy.

So instead of trying to use the storyboard, I decide to see if I could use something similar to the initial window creation and call that new window from my ContentView so that it was part of the view and therefore the data hierarchy.

As usual, there was a lot of trial and error involved here, but I came up with a workable solution.

struct PrefsView: View {
    var body: some View {
        Text("Hello, Prefs!")
            .frame(maxWidth: .infinity, maxHeight: .infinity)

    var window: NSWindow!
    init() {
        window = NSWindow.createStandardWindow(withTitle: "Preferences",
                                               width: 300,
                                               height: 100)
        window.contentView = NSHostingView(rootView: self)

For convenience and reusability, I made an extension on NSWindow that created a window with the basic properties configured, much like they are in AppDelegate. I temporarily added a Button to ContentView like this:

  Button("Prefs") {
      let _ = PrefsView()

This opened the window perfectly, but it had a problem: repeatedly clicking the button kept opening a new window instead of bringing the existing one to the front.

After a lot more trial and error, this is what I ended up with for my PrefsView struct:

struct PrefsView: View {
    @State var prefsWindowDelegate = PrefsWindowDelegate()

    var body: some View {
        Text("Hello, Prefs!")
          .frame(maxWidth: .infinity, maxHeight: .infinity)

    var window: NSWindow!
    init() {
        window = NSWindow.createStandardWindow(withTitle: "Preferences",
                                               width: 300,
                                               height: 100)
        window.contentView = NSHostingView(rootView: self)
        window.delegate = prefsWindowDelegate
        prefsWindowDelegate.windowIsOpen = true

    class PrefsWindowDelegate: NSObject, NSWindowDelegate {
        var windowIsOpen = false

        func windowWillClose(_ notification: Notification) {
            windowIsOpen = false

So my PrefsView opens its own window and sets a window delegate that records when the window is closed.

I removed my temporary button and back in AppDelegate.swift, I added an IBAction called by the Preferences menu item:

    var prefsView: PrefsView?

    @IBAction func openPrefsWindow(_ sender: Any) {
        if let prefsView = prefsView, prefsView.prefsWindowDelegate.windowIsOpen {
        } else {
            prefsView = PrefsView()

And this gave me what I was after - a view that opened from a menu item but that knew itself whether it still had a window so could decide whether to open a new one or bring the existing one to the front. This looks a bit convoluted, but it doesn’t appear to cause any memory leaks and the responsibility for the window rests on the view that uses it, which feels right to me.

After I had this working, getting the data passing around was quite simple. I created a Prefs class to store the preference data. I wanted this data stored in UserDefaults, but since I also wanted to use an ObservableObject with the @Published property wrapper, I was not able to use the @UserDefaults property wrapper that I had used for the app mode.

So instead I used @Published with a didSet that saved the changed data to UserDefaults. Thanks to @azamsharp for this technique.

class Prefs: ObservableObject {
    var showCopyright: Bool = UserDefaults.standard.bool(forKey: "showCopyright") {
        didSet {
            UserDefaults.standard.set(self.showCopyright, forKey: "showCopyright")

This preference will dictate whether a copyright notice is shown on every cat image, so it needs to be available to DetailView and to PrefsView. Since I did not want to pass it through every view on the way to DetailView, I decided to use an EnvironmentObject. But I was not able to work out how to set the environmentObject for the PrefsView as I created it, so I ended up sending an @ObservedObject to PrefsView but using an @EnvironmentObject for DetailView. (Actually for CatImageView as I had extracted the image from DetailView as a subview.)

In AppDelegate.swift:

    let prefs = Prefs()

    // and in the openPrefsWindow IBAction:
    prefsView = PrefsView(prefs: prefs)

In PrefsView.swift:

    @ObservedObject var prefs: Prefs

In CatImageView (a subview of DetailView):

struct CatImageView: View {
    @EnvironmentObject var prefs: Prefs

    let catImage: NSImage
    let imageIsFlipped: Bool

    var body: some View {
        Image(nsImage: catImage)
          // modifiers as before

             Text(prefs.showCopyright ? "Copyright © https://http.cat" : "")
                 .shadow(radius: 5)
             ,alignment: .bottomTrailing)

And that is that! I have shown how it is possible to create an entire Mac app using SwiftUI.

I am sure that there are numerous ways that this could be improved, so if you have any ideas or suggestions, please use one of the buttons below to contact me.

If you want to check out the project at this stage, here is a link to the relevant GitHub commit. Or if you would prefer, here is a link to the final version of the project.

Moving on to an unplanned part 3 of this series, I am going to experiment with various forms of dialog.

SwiftUI for Mac - Part 1

Permalink - Posted on 2019-12-15 07:28

So far, nearly all the articles I have seen about SwiftUI show it being used for iOS, more particularly for iPhone. But SwiftUI works on all Apple’s platforms, and as I am primarily a Mac developer, I decided to try out a Mac app and see what happened.


I opened up Xcode and created a new project selecting the macOS App template. The project opened at the usual ContentView.swift but there were a few differences in the project structure as well as one in the ContentView struct.

New Mac project

The first thing to notice is that the default “Hello, World!” Text view has a frame set:

  .frame(maxWidth: .infinity, maxHeight: .infinity)

If I removed this frame modifier, the preview display in the Canvas changed so that the view was only the size of the text instead of being a standard window size. I guess an iOS device always knows what size it is, but a Mac window can be any size, so you have to be more explicit to stop SwiftUI shrinking the container view to the minimum size possible.

The next thing is to look at the files that are included in the project. There is no SceneDelegate.swift as you would see in an iOS project. And to my surprise, there was still a Main.storyboard file! And going to the General settings for the app target, I could see that this storyboard was selected as the Main Interface.

Opening it up reveals that this is where the application menu is configured. I had wondered where the menus were configured in Mac SwiftUI apps.

Main storyboard

The AppDelegate was the next thing I looked at and here I found some of the code that I would have expected to find in a SceneDelegate. The applicationDidFinishLaunching(_:) method creates an instance of ContentView, creates an NSWindow and uses an NSHostingView to display the ContentView inside the window. At this stage, running the app gives me what I would expect: a fully-fledged Mac app with a window and a menu, both with all the functions you would expect in any standard Mac app.

The Canvas

I was not expecting the Canvas to be much use when it came to previewing a Mac app. It works so well with an iPhone app because the iPhone is tall and thin and fits neatly into one side of the code window. But a Mac view is likely to be much bigger, so it would have to be scaled down a lot to avoid talking up too much precious space in my Xcode window.

But it works as expected, and even scaled down, you get a good idea of the layout while still getting the live reloading that is part of what makes developing in SwiftUI so much fun.


But here is where I got my first real surprise, with a feature that I had not seen yet in any SwiftUI tutorial or article. Click the Live Preview button and see what happens…

Live Preview

Of course I clicked “Bring Forward” and there was my app running in a window called “Xcode Preview”. There was an app in my Dock and when I chose “Show in Finder”, I found that the app is buried deep in DerivedData. Positioning my windows so I could type in Xcode while watching this preview window, I saw that it instantly updated my view as I typed, just like an iPhone in the Canvas.

If I changed the structure of the view, the app closed and re-opened immediately with the new content. This is amazing and shows that the Xcode & SwiftUI teams really thought about how to use these new features in Mac apps as well as iOS.

In Xcode 11.3, I found that I was having trouble with the previews. They would not display and above the Canvas, I got the super helpful message “Cannot preview in this file — SwiftUI-Mac.app may have crashed.”. It turned out that this was a signing issue. If you go to the app target and look in the Signing and Capabilities section, check that Signing Certificate is not set to “Sign to Run Locally”. If it is, switch to “Development” and the previews will start working again.

Code signing

Laying out the View

Now that I have the project and I know how to preview it, it’s time to work out what to display in the app. The next real app I want to work on will use a master-detail layout, so that is what I decided to try here.

Before worrying about the data, I decided to try populating the master view with a static list and using that to navigate to a detail view that was simply a Text view.

struct ContentView: View {
    var body: some View {
        NavigationView {
             List {
                 ForEach(1 ... 10, id: \.self) { index in
                     NavigationLink(destination: Text("\(index)")) {
                         Text("Link \(index)")

This worked, except that the left column was only about 20 pixels wide. But I was able to use the mouse to drag it wider and there were my List entries. Clicking on one did indeed show the detail I wanted, but it shrunk the window to one line high!

The first thing I did was to apply a listStyle modifier to make it show the semi-transparent Mac sidebar. This fixed the width of the sidebar. But the whole window still shrunk when I selected an item.


I tried applying the frame modifier to the NavigationView and that made the window stay the same size, but the content still shrunk into a tiny section in the middle. It looks like I need to apply that frame modifier to the detail view as well.

  .frame(maxWidth: .infinity, maxHeight: .infinity)

And as you can see from this gif, I then had a full functional master-detail view with a collapsible and expandable semi-transparent sidebar.

Master detail view

Adding Data

After some scouting around for a free API that I could hook into, I came across HTTP Cats which is a site that serves up a cat image to match almost every HTTP status code.

This sounded ideal: I can list the codes in the master view on the left and display the image in the detail view on the right.

First I created a JSON file to list all the HTTP status codes so that I could put them into a List view. This was a very simple array with each entry having a code and a title:

    "code": "100",
    "title": "Continue"
    "code": "101",
    "title": "Switching Protocols"

I created an HttpStatus struct with these 2 properties and I borrowed Paul Hudson’s excellent Helper Bundle extension to decode the JSON file. For a first attempt, I used the numeric codes to build the list and showed the title of the selected one in the detail view. But one of the best things about SwiftUI is that it makes it so easy to configure table rows, so it is time to create a new View to do this.

After some experimentation, I had a TableRowView that I liked the look of, but the default sidebar width was too narrow and truncated the status code titles, so I added a frame modifier to the List to set a minimum and maximum width for the sidebar.

Master view

Outline List

At this point I decided that it would be more useful to have a outline list with the status codes grouped by their category.

So I re-did the JSON file to show this, added an HttpSection struct and a SectionHeaderView and modified the data loading method and @State variable.

    "headerCode": "1xx",
    "headerText": "Informational",
    "statuses": [
        "code": "100",
        "title": "Continue"
        "code": "101",
        "title": "Switching Protocols"
    "headerCode": "2xx",
    "headerText": "Success",
    "statuses": [
        "code": "200",
        "title": "OK"

This worked really well and I was thrilled to find that the sections automatically had Show/Hide toggles!

Outline view

Detail View

Up until now, I had been using a standard Text view as the destination for my navigation. This is a really useful technique as you can build the interface gradually but have it work from the beginning. But now it was time to create a new view for the details.

I set up the view and added a method that would download the correct cat image when the view appeared but there was no image. After some digging, I realised that sand-boxed Mac apps do not allow network access by default. I went to the Signing & Capabilities section of the target settings and turned on “Outgoing Connections (Client)”. And then I had my cat pictures.

Detail view

It really should have a loading image to display while the cat image is being downloaded, but to my disappointment, I found that the SF Symbols are not available to a Mac app! But I added a Text view to say “Loading…”.

Now that I have a functioning Mac app with a Master-Detail view, the next thing is to explore some more of the challenges that will need to be solved before I can write a Mac app completely using SwiftUI.

If you want to check out the project at this stage, here is a link to the relevant GitHub commit. Or if you would prefer, here is a link to the final version of the project.

In part 2 of this series, I will look into:

  • how to interact with the menus
  • how to open a secondary window
  • more user interface controls
  • how to pass data around between windows

SwiftUI First Thoughts

Permalink - Posted on 2019-08-18 05:00

At WWDC 2019, Apple surprised us all by announcing a completely new declarative UI framework called SwiftUI. Quoting snippets from the Apple announcements, “SwiftUI is an innovative, exceptionally simple way to build user interfaces across all Apple platforms with the power of Swift” and “SwiftUI uses a declarative syntax so you can simply state what your user interface should do.” But what does this mean and should we all adopt it now?



Before discussing whether to adopt SwiftUI, we need to consider Swift itself, since you cannot use SwiftUI without Swift.

The announcement of Swift at WWDC 2014 was a complete bombshell. Here in Australia, I watch the keynote every year while half asleep since it starts at 3 am. That announcement had me wide awake and bouncing out of my seat with excitement. I was an early adopter and have never regretted that decision.

Many well-respected developers have decided to ignore Swift and they have their various reasons, so let’s go through the ones I have heard:

1. I’m very comfortable and productive in Objective-C

This is not a bad reason and for many people, their employer may insist on the language anyway, but this argument doesn’t work for me. Firstly, I think that there is never going to be the One Perfect Language (with apologies to Chris Lattner) so I am always open to new ideas. And personally, I love learning new languages even if I am never going to use them in production. I feel that this makes me a better programmer overall. And there are vast benefits to Swift - it is a much safer language to write it, it is easier to read and more concise to write, it is just a much more modern language.

2. Swift is too new and changes too much between versions

Swift was new. It is now 5 years old and we are into version 5.2. Undeniably, there have been a lot of changes since 1.0 and many of them have been breaking changes. Swift 3 was especially bad in this respect. But this came with advantages too. As early adopters, we were able to influence the direction of the language. And Xcode was always pretty good about providing a converter to the next version. But either way, since Swift 4, there are supposed to be no more breaking changes, so this is an argument whose time has passed.

3. No ABI stability

ABI stability was a crutch that many people clung to as an excuse to avoid Swift. But unless you were building frameworks for distribution, I don’t see that it was ever a complete deal-breaker. The Swift ABI Stability Manifesto has a good review of what ABI stability is and what it will allow. As app developers, the main advantage is that the Swift libraries will no longer need to be bundled with each app. This will decrease app sizes dramatically. But either way, we now have ABI stability, so again, this argument is finished.

4. Apple may not be serious about Swift and it may not last

I think there was a certain amount of wishful thinking here. The main data behind this theory seemed to be that very few of the Apple apps included any Swift. And in the beginning this was true. I expect Apple’s apps have a rather longer development time-frame than apps produced by independents. However over the last few years, more and more of Apple’s own apps have started to use Swift, either completely or partially. And any doubt about Apple’s commitment to Swift should have been permanently laid to rest by the announcement of SwiftUI.

5. It’s too complicated

OK, this one has some validity, but then again, if Swift is to rule the world, it needs to be able to do a lot of things. I love Swift, I love writing in it and I am very productive when using it. But then I see a chunk of code sprinkled with generics and unsafe pointers and I can’t make head nor tail of it. However, I think that if you are writing any standard, non-arcade-game app, you can write very good Swift using just the basics.

Why did Apple make SwiftUI?

Having demolished the arguments against using Swift, it’s time to move on to SwiftUI. Let’s start with the reasons why something like this had to happen.

Apple now has 5 or possibly 6 user platforms: macOS, iOS, iPadOS, tvOS, watchOS and maybe CarPlay. (I’ve never considered any CarPlay development so I have no idea how it works.) The screen sizes range from 38mm for the smallest watch to over 75" to large screen TVs (apologies for mixing my units there, but it seems that TVs have not gone metric yet). As far as user interface frameworks go, we have had AppKit, UIKit and WatchKit. AppKit is the venerable old member of this team, descended from NextStep (which is why every element name has the NS prefix) and is used to make macOS apps. UIKit was built from scratch for the iPhone and so is a lot newer and neater than AppKit, but at the same time it is more limited. It has never had to deal with the vast variability and complexity of a Mac app’s interface. WatchKit is an even more slimmed down framework with a relatively small number of interface elements.

Now imagine that you are trying to write a multi-platform app. You have to learn at least 3 different ways of doing everything. And there are differences that always catch me out. For example, in AppKit, to set the text in a text field, you set the field’s stringValue but in iOS, you can set the field’s text property. And in WatchKit, you call the setText() method.

Want to change the background color of a view? UIView - no problem, set backgroundColor. NSView - nope - do something weird with layers. I forget what, I have to look it up every time.

These inconsistencies are annoying, time-consuming and a huge barrier to cross-platform development. It really annoys me when I read articles or tweets that assume Swift programming = iOS programming when it is so much more. But before SwiftUI, it was not easy to jump between the platforms.

Catalyst, previously code-named Marzipan, was supposed to be the answer. And it is a partial answer. It allows iPad apps to be ported to the Mac and that’s great for iPad developers who want to expand their reach. But it isn’t the answer for everybody.

Interface Builder

Before I go further into what I think is so great about SwiftUI, I would like to take a moment to discuss Interface Builder. Xcode is a brilliant tool that gets better with every release, but its weak point has always been Interface Builder. I am old enough to remember when Interface Builder was a separate app (not that we called them “apps” in those days) and although it has been folded into Xcode for many years now, the connection between interface and code has always been clunky and un-intuitive. Control-dragging from interface to code and then remembering to switch between Action and Outlet so that you don’t end up naming your button “doneButtonWasTapped”. And if you get the modifier key wrong, who knows what weird stuff will happen.

And then came Auto Layout… It was vastly more flexible than the old school springs & struts and with the ever increasing number of iPhone & iPad models something had to be done, but if you have never ended up swearing at Auto Layout and reverting to a previous commit or mashing Undo repeatedly, then you can’t have used Auto Layout very much!

WatchKit had an entirely different approach to layout and it was easy, intuitive and very refreshing. You drag in objects, they go one under another. You can group them horizontally or vertically, you can make them into table cells. WatchKit has a much more limited set of interface elements and a much more limited set of device sizes to deal with, but I think we can clearly see the origins of SwiftUI in the way it worked. Even if you still had to use Interface Builder to do it.

Interface Builder’s quirks lead to a category of programmers who felt the need to write all their interface in code. To my way of thinking, this is a huge waste of time and you still had to wrestle with Auto Layout, but without the visual clues! But if it makes them happy…


What Is SwiftUI?

A “declarative UI framework” - what does that mean? Basically, declarative programming is a way of specifying what a program should do, rather than specifying how to do it. A common example is making a sandwich. If you want a sandwich, you say to the sandwich maker, “Please can I have a ham, cheese and tomato sandwich”. You don’t say “Get two pieces of bread, butter both of them, cut 3 slices of ham and 2 slices of cheese…”. They know how to make a sandwich so you only have to ask for what you want.

Back in the Apple UI world, what if you want a button? Is it for an iPhone app? Then you need an UIButton with a certain type. Set its title, size, location, layout constraints. What are the default sizes for an iPhone button? What is the default font? What color should the text be? Now make a button for a tvOS app? That has to be huge! And what other settings does it have? But the thing is, iOS, macOS, tvOS etc. already KNOW what their buttons should look like. So why not just tell the system “I want a button”? Let the system work out the details and you can get on with the cool app ideas.

I’m not going to turn this post into a SwiftUI tutorial, but I would like to thank and recommend the people that have really helped me get to grips with it, especially Paul Hudson of Hacking with Swift with his Learn SwiftUI tutorials, Mohammad Azam’s great YouTube series, and Meng To’s SwiftUI course at Design+Code.

The other great benefit of SwiftUI is that when used with the Combine framework, it gives you a reactive interface. There have been various third-party libraries for doing this: RxSwift, ReactiveSwift, ReactiveCocoa, Bond etc, but with Combine, Apple is baking this into the ecosystem, which makes it a lot easier to set up and means that it will stay up-to-date with the operating systems. A reactive interface is one where you can bind a UI element to a piece of data and then when the data changes, the user interface updates automatically. You can even bind both ways so that the user interface updates the data without you having to do a thing. Imagine how much boiler-plate code that can eliminate?

The Good, The Bad and The Ugly

1. The Good

You get a lot of interface for very little code. Making tables is a joy without the masses of boilerplate code needed to set up data sources and delegates. The instant preview in the canvas makes iteration much easier. Being able to create something like a Picker and having SwiftUI render it in one of multiple different styles depending on the platform is magical.

2. The Bad

It’s early days yet and SwiftUI has some quirks and bugs. Sometimes the canvas just stops responding, switching into live mode in the canvas can take a while and of course it is still in beta, so there will be breaking changes to come.

3. The Ugly

It is very easy to build up the Pyramid of Doom where you have multiple levels of nesting leading to the end of your code being a seemingly endless stream of closing curly braces. In SwiftUI, one tends to build from the inside out: make a Text view, embed it in a VStack so you can add another one, embed that stack in an HStack so you can add an Image and so on… But there is an answer: Command-click on one of your outer layers and select “Extract Subview”.

Coding the Layout

Earlier in the article, I spoke about programmers ignoring Interface Builder and laying out the interface in code. I don’t think this is a good approach, so how is SwiftUI different? Firstly, you get immediate feedback of the UI you are coding, so you are not losing that visual benefit of using Interface Builder. Secondly, SwiftUI does much of the layout for you, so you are not hand-coding auto layouts or every last detail of every UI element. So as far as SwiftUI is concerned, I am a convert to programmatic layouts. But if not using SwiftUI, I would still stick to Interface Builder.

Another point to consider here is that developers have long argued that if Apple wants the iPad to be seen as a “Pro” device, there should be a version of Xcode for iPad. One of the problems with this was Interface Builder - it is difficult to see how it could be made to work with a touch interface. But with SwiftUI and iPadOS, is it possible that Apple can make an iPad version of Xcode?

Should you use SwiftUI?

I hope that from my previous paragraphs, you have come away with a good feeling for why Apple made SwiftUI and why it is good for us as developers. Personally, I find it a joy to use even in these early beta stages, but some of the arguments against using Swift, can now be applied again to SwiftUI.

That SwiftUI is very new cannot be debated. It is extremely new and even in the handful of betas released since WWDC, we have seen some breaking changes. It feels quite buggy still but as I am running it in a beta operating system with a beta version of Xcode, it would be unfair to blame all the instability on SwiftUI.

SwiftUI is not yet a complete replacement for UIKit/AppKit/WatchKit etc. There are SwiftUI equivalents for many of the interface elements and I recommend the Gosh Darn SwiftUI site which maintains a list of UIKit equivalents as well as really useful snippets of SwiftUI code. But even when SwiftUI does not have the UI element you want, there are two easy options: use UIKit/AppKit or build your own. Apple has made sure that there is no problem about mixing and matching UIKIt/AppKit code with SwiftUI. And maybe the SwiftUI tools would allow you to build your own version of the missing element. I needed a progress bar and I built one myself with not much code and ended up with what I think is a better look than the standard one.

Progress Bar

Click the image for a link to the GitHub repository.

For years, Apple has been telling us to use standard interface elements in our apps and if we did this, when system updates changed the look and feel, we mostly got that change for free. Now they are giving us even more for free by saying effectively, tell us what UI element you want and we will do all the work of configuring it for the platform and for the user’s settings.

But with this, Apple has given us a lot of modifiers we can apply to elements as well as a great animation suite, so I expect to see a lot of more interesting design choices being made in apps, while they are still adhering to all the standard human interface guidelines for the various platforms.

Apple does not promote SwiftUI as “write once, run everywhere” but as “learn once, apply everywhere” and that is an important distinction. It seems at first glance that we can write once but only on a basic level. You are still going to need to design the appropriate UI for a platform, but it will be able to re-use components from the other versions of the same app.

Do I intend to use SwiftUI in my next app - YES. If I was writing code for NASA, I wouldn’t, but my apps are rarely mission-critical, so I can indulge myself and learn as I go. It will be frustrating when there are breaking changes, but at the same time, my bug reports are going to make it better.

One caveat is that SwiftUI apps will require the latest operating systems, iOS 13 and macOS 10.15 so if your app has to support older versions of the systems, you will have to wait until next year. But there is nothing to stop you building some test components and starting the learning process.


Permalink - Posted on 2019-02-04 04:48

Mark Time is now available now from the iTunes App Store for iPhone and iPad as an assistant for celestial navigators.

Mark Time is an application for Celestial Navigation that solves the problem of how to take an accurate time reading to go with each sextant sighting.

By simply tapping the screen you can record the exact time UTC as you take your sight, so you have no chance of making an error with the conversion, and this time is stored in one of five registers.

Mark Time

Very useful when you have an assistant, and ideal for taking readings when you are on your own.

As you record a time you hear a confirmation sound and feel a vibration, so there is no need even to look at the screen. In addition the actual latitude and longitude at each time can be accessed later to verify your calculations. These options are all configurable in Settings to suit your own preferences.

Mark Time

Location permissions: On startup, the app will request permission to access your location. This is how the latitude and longitude data is gathered to provide this data if you wish.

Support: If you have any questions about this app, please use the Contact link above to get in touch.

Learning Swift - Tuples

Permalink - Posted on 2019-02-03 09:48

I sometimes like to focus on aspects of the Swift language that get less publicity, but that I think are really useful without adding a lot of complexity. This time I am looking at tuples.

There are many different ways of collecting data together in Swift, but for small amounts of transitory data, I find tuples to be an extremely convenient data structure.

What is a Tuple?

A tuple is basically an array with a pre-determined length and unlike normal Swift arrays, it can hold a mix of data types.

Here are some examples:

let pair = ("Jessie", "Woody")
let coords = (0, 4, -6)
let pet = (type: "cat", trained: false, age: 5)

To define a tuple, you enclose the data elements in parentheses - normal brackets, not curly or square. Optionally, the elements can have a label attached as shown in the pet example.

Tuples can have any number of components, but if they get too long, a struct might be a better option. SwiftLint will complain if you use tuples with more than 3 elements and usually I go along with that.

There are various ways to access the parts of a tuple. The first way is using index numbers which works but isn’t very intuitive and could be hard to decipher when you come back to a project after some time.


The next way is if the tuple has used labels for the elements as in the pet example above:


But the way I prefer to use them is by deconstructing the parts into separate variables in a single statement:

let (x, y, z) = coords
print(x, y, z)

The elements of a tuple can be of different types but once a tuple has been defined, that type of each element is fixed, so you still get all the benefits of Swift’s type safety.

Option-clicking on the variable name shows the inferred type of the tuple:

The type of a tuple.

Trying to re-assign the tuple or any elements of the tuple will only work if the new assignments match the initial types for each element:

Errors when mutating a tuple.

Where could you use a tuple and why?

Let’s imagine you have a function that checks a database or web service and comes back with the title of a movie and its rating.

func getMovieInfo() {
  var movieTitle: String
  var rating: Int

  // get the data from somewhere
  // now return both movieTitle and rating

Having got the data, this function needs to return two pieces of data: movieTitle and rating - one String and one Int. How could this be done?

  1. Array: since there are 2 different data types, the array would have to be of type [Any] or the Int could be converted to a String before returning. Neither of these are good options. Using Any removes the protection of Swift’s type safety and converting the Int to and from a String may fail, so then you have to deal with optionals.

  2. Dictionary: the same arguments hold true. The dictionary would have to be of type [String: Any] or the rating would have to be converted to a String.

  3. Struct or Class: either of these would be fine but unless this is a data structure that is going to be re-used, it seems like overkill.

  4. Tuple: this would get my vote, so let’s see how that would work.

func getMovieInfo() -> (String, Int) {
  var movieTitle: String
  var rating: Int

  // get the data from somewhere

  return (movieTitle, rating)

Two main things to notice here:

  1. The return type of the function lists the data types of both the elements being returned, enclosed in parentheses.

  2. The returning tuple is created by wrapping the elements inside parentheses, just like in the examples above.

And then in the calling function, you can access the parts of the returned data like this:

let (returnedMovieTitle, returnedRating) = getMovieInfo()

The tuple is being returned and immediately deconstructed to give 2 new variables so accessing the parts of the tuple is easy and type-safe.

A function returning a tuple can also be configured to use named elements by specifying the names in the return type declaration.

func getMovieInfo() -> (name: String, score: Int) {
    var movieTitle: String
    var rating: Int

    // get the data from somewhere

    return (movieTitle, rating)

let result = getMovieInfo()
let returnedMovieTitle = result.name
let returnedRating = result.score

My feeling is that once a tuple is complex enough to need names, you should really consider using a class or a struct, but for returning 2 or 3 chunks of data from a function, this is a very useful technique, espeicialy if the data types are different.

Looping through tuples

If you have an array of tuples, looping through the tuples is made very convenient if you use the deconstruction method of accessing the parts.

As an example, suppose you are dealing with some 3D coordinate system and you want to perform an operation on each location.

let coords_array = [
    (0, 0, 0),
    (0, 1, -3),
    (1, 4, 2),
    (-2, 0, 5),
    (5, 2, 4)

for (x, y, z) in coords_array {
    let distanceFromOrigin = abs(x) + abs(y) + abs(z)

You can deconstruct the tuple each time through the loop, assigning temporary variables so you can act on them.

Wrapping Up

So those are the basics of tuples: how to create them, how to use them and where they might be useful. My main use is as a light-weight alternative to a struct for returning multi-part data from a function. But hopefully after reading this article, they have become another tool in your Swift tool belt that you can consider using in certain circumstances.

That leaves only one important question: how do you pronounce ’tuple'?

I have heard two variations: ’toople’ using a long U as in universe or ’tupple’ using a short U as in cup. There does not appear to be any strict geographical differentiation, so take your pick. I prefer ’toople’ myself, but if somebody says ’tupple’, I know what they mean.


Permalink - Posted on 2019-01-16 00:59

The End of Pic-a-POD

Permalink - Posted on 2018-10-05 23:38

I think I wrote the first version of Pic-a-POD in 2003 and have been updating and maintaining it ever since, but the time has come to shut it down.

I haven’t been able to find a picture of the original version, but here is one from 2005:

Pic-a-POD 2005

And here it is today:

Pic-a-POD 2018

It was written originally as a convenient way to download the daily picture-of-the-day from National Geographic and use it to set the Mac’s Desktop Picture automatically. From there is just grew with more sites added (9 at the moment although I think there have been up to 12 at certain times).

The main issue was keeping up with the site changes of the various sources. Early versions had each copy of the app interrogate the sites directly which meant that any change to the site broke the app until an update could be released. And without the App Store making updates easy to distribute, this was a problem. Later I switched to having PHP scripts on my server do the data retrieval and store the results in a database. The app then just had to request the data from my server. That way if there was a change, I could react quickly and a fix to the server-side scripts allowed all users to get the new data.

As my first Objective-C app and my first app on the Mac App Store, Pic-a-POD has always held a place in my affections, and until last week, it was the one app that was always running on my Mac. So what changed? macOS Mojave’s dynamic desktops! I turned off Pic-a-POD, and set the Desktop picture to change dynamically through the day and I loved it.

On the server, I have kept Pic-a-POD updated regularly, adding and removing sites, fixing the scripts to accommodate changes and so on. But the desktop app has languished and has needed an update for many years now. It’s networking is primitive and I know so much more about programming for the Mac now that looking at the code is positiviely embarrassing! But it has never been a big seller so a re-write is definitely not economically viable, it would only be for my satisfaction. And if even I am not using it any more, what is the point?

So I have made the sad decision to shut it down. But what does this mean for users of Pic-a-POD right now?

Firstly, it is not going away immediately. I will remove it from the App Store, but existing copies are still going to work. If any of the source sites change their data structure, I will not be monitoring this and I will not update the server-side scripts - just turn off that source and carry on with whatever still works. And finally, when the picapod.com domain name expires in 2021, I will not renew it and the app will cease to operate.

What can you use instead? The default dynamic desktops in Mojave are great although there are only two of them, but I have bought myself an app called 24 Hour Wallpaper which includes a great range of dynamic desktop pictures.

So thank you to everyone who has used Pic-a-POD over the years and especially those of you who took the time and trouble to contact me. It has been a fun journey, but there are other apps in my future now.

Moving to the Dark Side - Part 2

Permalink - Posted on 2018-10-05 22:29

Now that most of my Mac apps have been updated to support macOS Mojave’s dark mode, it was time to turn my attention to this web site.

I build this site using Hugo and up until recently I used a theme called Even which I had been able to modify to suit my requirements. The story of how I switched to Hugo, what I wanted in a theme and how I went about, is in a post from last year.

But Evan is a theme with a white background and dark text, which looked great in light mode, but rather glaring in dark mode. So it was time to head for the Hugo Themes page to look for an alternative.

But which way to go? In my opinion, dark themes look better in Mojave’s light mode than light themes look in dark mode, so I decided to go with a dark theme. But to my delight, I found a theme that allowed users to switch between light and dark modes: Hello Friend by panr. Click the light bulb icon in the top right and the web site instantly toggles between modes.

Dark and light versions of homepage

With the spread of dark mode, I would expect more web sites and themes to implement this sort of switching in the future. Thanks to panr for being an early adopter.

As I said in my previous post, I have already updated several of my macOS apps to support dark mode. But after reading some comments on Twitter, I have updated Icon Builder and Dice Pass to allow the user to decide which mode to use. Make your choice in the Window menu as to whether these apps use whatever mode is set for the system, or select your preferred mode.

Select mode in Window menu

Moving to the Dark Side

Permalink - Posted on 2018-09-26 06:49

With the release of macOS Mojave on 24th September 2018, I have started updating my Mac apps, mainly to enable support for dark mode if appropriate.

And now I have updated this site too. Click the light bulb icon at the top right of the page to toggle between light and dark modes for this site.

And with my apps, so far (1 st October 2018), I have updated Icon Builder, World Time in Words, Dice Pass and A Knight’s Move.

Icon Builder 5.1

World Time in Words 3.2

Dice Pass 3.2

Knights Move 1.6

For A Knight’s Move, I wanted to make sure the wood-look background didn’t change, so I actually disabled dark mode. For any developers looking for the way to do that, I added the following chunk to the applicationDidFinishLaunching(_:) method:

    if #available(OSX 10.14, *) {
        NSApp.appearance = NSAppearance(named: .aqua)

Similar code could presumably be used to change the appearance of a running app. I may add the ability to switch to my apps later.

Swift Strings Helper

Permalink - Posted on 2018-06-21 04:45

Hands up everyone who can remember how to work with Swift strings, especially when it comes to substrings and ranges? ….


Me neither. So I decided that I would work it out once and create myself a library to make it easy for myself in the future. And then I thought that other people might like it too. So I have created my first open sourced project.

Strings in Swift

Swift’s string handling is amazing. It is truly Unicode-compliant, so a Swift String doesn’t care whether your string is made up of basic alphanumerics, accented characters, or emojis that might be composed of several different emojis joined together.

But this power comes at a price, and every version of Swift has changed the way we interact with strings, seemingly making it more and more confusing for the poor programmers trying to stay current. I have got to the stage where each year I read up on the new String features and then promptly forget them. For every use, I have to go back and search how to do what should be simple.

The Problems

To my mind, there are two main problems: indexes and substrings.

In most languages, you can get the n-th character of a string, but not in Swift. In Swift, you have to ask the string for its startIndex (or endIndex), then use an offset to adjust that index by a certain number to give you a String.Index. Do much the same to get a second index and then you can grab the string between those two indices.

To get a sub-string from the 7th up to the 11th character of a string, this is what you have to do:

let str = "Hello, playground"

let subStart = str.index(str.startIndex, offsetBy: 7)
let subEnd = str.index(str.startIndex, offsetBy: 11)

let subStr = str[subStart ..< subEnd]       // "play"

Splitting the lines up like that at least helps to show what is happening, but then you see abominations like this:

let sub = str[str.index(str.startIndex, offsetBy: 7)..<str.index(str.startIndex, offsetBy: 11)]

And how anyone is supposed to read that, I really do not know.

And now here is the kicker: the results (subStr and sub in the examples above) are not of type String! They are of type Substring so when you go to use them, they don’t work as expected.

I guess there are cases for using Substring but I always just end up casting to String to solve this, but only after the compiler has choked on what I thought was a String all along.

The Solution

To make my life easier, I worked out all the ways that I wanted to be able to split up strings. Basically just two ways: by character number or by substring. Swift already has a substring method but it uses String.Index as shown above. To avoid confusion, I named my functions all sub.

But now I can do the following to split strings by character number:

let subStr = startingString.sub(from: 9)
let subStr = startingString.sub(from: -3)

let subStr = startingString.sub(upTo: 4)
let subStr = startingString.sub(upTo: -3)

let subStr = startingString.sub(from: 3, upTo: 7)
let subStr = startingString.sub(from: 3, upTo: -5)

Negative numbers count back from the end of the string. And they all return String objects!

Or to split strings by their own sub-strings, I can do this:

let subStr = startingString.sub(from: "abc")

let subStr = startingString.sub(upTo: "xyz")

let subStr = startingString.sub(from: "abc", upTo: "xyz")


Once I had created a string helper library, I started thinking about all the other string utilities that would be useful. So I started adding all sorts of facilities:

  • Computed properties:
    • length (why should the length of a string be called count - that makes no sense)
    • words
    • lines
    • word count
    • line count
    • title case
  • Encoding:
    • URL encoding & decoding for queries or forms
    • base64 encoding & decoding
  • Trim:
    • trim
    • trim left
    • trim right
    • trim using extra characters
  • Pad:
    • pad left
    • pad right
    • with default space or specified other character

That’s as far as I have got so far, but I am hoping for some community involvement that will expand or edit this library to make it more broadly applicable.

Open Source

I have never created an open source project before and I have rarely contributed to open source. But I have now published this library on GitHub under an MIT license. Please check it out at https://github.com/trozware/swift-strings-helper. The GitHub repo contains an Xcode project with all the source files, plus the targets to build frameworks for macOS or iOS, and a playground as documentation and to test it all out.

I would love to get as many stars as possible and it would be fantastic if anyone wanted to log an issue or contribute directly. As someone who finds the whole open source world rather intimidating, I would like to assure everyone that there will be no flaming and no shooting down of ANY ideas. I look forward to hearing from you.

I am sure there are other Swift libraries out there dedicated to solving the same problems, but I hope that mine can prove useful to some. And if you just want to use it without contributing, feel free. The usage instructions are all in the ReadMe on the GitHub page.

Functional Programming in Swift

Permalink - Posted on 2018-06-14 04:18

What is Functional Programming and how can we use it in Swift?

Search online for any definition of functional programming and you will find many different definitions, few of which are practically helpful. I have no claim to be an expert, but as a Swift enthusiast, this is what I have distilled out of the morass.

What is Functional Programming?

Without providing a concrete definition, here are what I see as the 3 main goals of functional programming:

  • use pure functions where possible
  • avoid mutability where possible
  • use functions as the basic building blocks

So let’s go through those one by one and see how they fit into the Swift language.

Functional Programming in Swift

You can download a playground containing all these examples from GitHub.

Pure functions

A function is considered pure if it will always produce the same result for the same input, regardless of where it is and what calls it.

Imagine you are writing a role-playing game and for a given fight, you need to be able to calculate the damage per second caused by a character.

class DamageDealer {

    var damageDone: Int = 0
    var timeTaken: TimeInterval = 0

    func damagePerSecond() -> Double {
        if timeTaken == 0 {
            return 0
        let dps = Double(damageDone) / timeTaken
        if dps < 0 {
            return 0
        return dps


let mage = DamageDealer()
mage.damageDone = 32
mage.timeTaken = 10


The damagePerSecond function takes no parameters but uses the properties of its containing object. This works in this class, but there are 3 big problems:

  1. The function is not transportable - you cannot copy it into another class as it is totally dependent on the structure of the properties in the containing class.
  2. When calling the function, it is not clear what data it is going to use.
  3. This function is difficult to test as calling the function with the same parameters (none) will produce different results depending on the setup.

So for a version that uses a pure function, we could replace damagePerSecond() with this:

func damagePerSecondPure(damage: Int, time: TimeInterval) -> Double {
    if time == 0 {
        return 0
    let dps = Double(damage) / time
    if dps < 0 {
        return 0
    return dps

mage.damagePerSecondPure(damage: mage.damageDone, time: mage.timeTaken)

Calling the function is now more verbose, but reading the call gives you much more information about what is going to happen. Testing is easy, and the function is completely self-contained so can be copied into any class or struct.

Avoid mutability

This one has become the poster child of Swift Functional Programming as Swift provides some very convenient ways to avoid mutability.

The first is let versus var. My rule is always to start defining any variable/constant with let and only changing to var if the compiler raises an error. In the current versions of Xcode, it will give a warning if you use var unnecessarily which is great, but I still stick to using let first.

The most powerful way Swift lets us avoid mutability with Functional Programming is with map, filter and reduce.


Consider this function that checks possible player names:

func checkPlayerNames(names: [String]) -> [String] {
    var validNames: [String] = []

    for name in names {
        if name.count > 3 && !name.contains(" ") {

    return validNames

let allNames = [ "Woody", "Rex", "Slinky", "Buzz Lightyear", "Hamm" ]
let checkedNames = checkPlayerNames(names: allNames)

Only names with more than 3 characters and no spaces are considered valid. So this function creates an empty array and then loops through each member of the supplied array and appends any valid names to the new array before returning it.

This function is a pure function and it works as expected. But the validNames array is mutable and there is no need for it to be.

Converting this to avoid mutability, we get:

func checkPlayerNamesUsingFilter(names: [String]) -> [String] {
    let validNames = names.filter { name in
        name.count > 3 && !name.contains(" ")
    return validNames

Inside the filter closure delimited by the curly braces after the word filter, (more about closures below), the element in the array being evaluated is stored in the name constant. The checks are done and this implicitly returns a Bool - true if the checks pass, false if they do not. If the closure returns true, the name is valid and will be part of the validNames array.

And if you really want to be concise:

func checkPlayerNamesUsingFilterShort(names: [String]) -> [String] {
    return names.filter { $0.count > 3 && !$0.contains(" ") }

I recommend the first method even if it is a bit more verbose. Storing the result in a constant before returning it makes debugging much easier. Using $0 instead of using a named parameter is convenient, but I prefer not to do this unless the closure is very simple.


filter takes an array of objects and returns a sub-array containing every element which returned true for the checks inside the filter body.

map changes the elements in an array and can return an array of the same type or an array of different types.

Here is a function to square every integer in an array in the old style, using a mutable array to accumulate the result:

func squareNumbers(_ numbers: [Int]) -> [Int] {
    var squares: [Int] = []

    for number in numbers {
        squares.append(number * number)

    return squares

let numbers = [ 1, 2, 3, 4, 5, 6 ]

And doing the same thing using map:

func squareNumbersUsingMap(_ numbers: [Int]) -> [Int] {
    let squares = numbers.map { $0 * $0 }
    return squares

In this case, the type of the data did not change: integers went in, integers came out. But map can change the type as well.

func squareRoots(_ numbers: [Int]) -> [Double] {
    let roots = numbers.map { number in
    return roots


And there is a final twist to map that used to be called flatMap but is now called compactMap and that allows us to get rid of optionals as we map through an array.

func convertStringsToInts(_ strings: [String]) -> [Int] {
    let ints = strings.compactMap { return Int($0) }
    return ints

let strings = [ "1", "two", "", "0.34", "65", "-93", "4e8" ]

The conversion of String to Int may fail and so returns an optional. If this function had used map instead of compactMap, the result would have been an array of optional Ints: [Int?]. By using compactMap, every nil value was dropped and only valid integers are included.


The final tool in the immutability toolbox is reduce and this is one that took me a while to wrap my head around.

Imagine that you wanted to add up all the integers in an array. Here is a way to do it using a mutable variable and a loop:

func sumNumbers(_ numbers: [Int]) -> Int {
    var total = 0

    for num in numbers {
        total += num

    return total

let numbers = [ 1, 2, 3, 4, 5, 6 ]

I can’t use filter or map here because I want to end up with a single value after applying some logic to every item in the array. So here is where I use reduce.

func sumNumbersUsingReduce(_ numbers: [Int]) -> Int {

    let total = numbers.reduce(0) { (cumulativeTotal, nextValue) in
        return cumulativeTotal + nextValue
    return total


The reduce function takes 2 parameters. The first is the starting value - in this case it is zero. The second paramter is a function (I am using a closure) this in turn takes 2 parameters and here is where it gets complicated. Inside the closure function, the 2 parameters are the current result and the next value from the loop. And what you return from this closure is going to be the new cumulative value which will either be fed back into the loop, or returned as the final result. The first time through the loop, the first parameter will be the initial value as set in the reduce function call.

To see how this happens, here is a version sprinkled with print statements showing what happens each time through the loop:

func sumNumbersReduceDebug(_ numbers: [Int]) -> Int {
    let total = numbers.reduce(0) { (cumulativeTotal, nextValue) in
        print("cumulativeTotal = \(cumulativeTotal)")
        print("nextValue = \(nextValue)")
        print("about to return \(cumulativeTotal) + \(nextValue) = \(cumulativeTotal + nextValue) which will become the next culmulative or the final value")

        return cumulativeTotal + nextValue
    print("final result = \(total)")
    return total

let shortNumbers = [ 5, 3, 8 ]


This produces a log showing:

cumulativeTotal = 0
nextValue = 5
about to return 0 + 5 = 5 which will become the next culmulative or the final value
cumulativeTotal = 5
nextValue = 3
about to return 5 + 3 = 8 which will become the next culmulative or the final value
cumulativeTotal = 8
nextValue = 8
about to return 8 + 8 = 16 which will become the next culmulative or the final value
final result = 16

Using functions as building blocks

This one is more a matter of style than of any particular programming technique. Basically, keep each function small and break your code into small chunks with obvious naming. This makes your code easier to read, test and debug and it beomes vastly more reusable.

Consider this totally made-up function:

func configureDisplay(for userId: String?) {
    guard let userId = userId else {

    displayUserData(for: userId)
    let userType = getPermissions(for: userId)

    populateMenus(for: userType)
    loadInitialData(for: userId)


configureDisplay(for: "abc123")
configureDisplay(for: nil)

Is it easy to read? Can you work out what it does? Now imagine all that functionality in a single huge function - would that be as good to use?

As a way of encouraging shorter functions, which leads inevitably to this sort of structured code, I strongly recommend using SwiftLint to check your code. I wrote a post about this a while ago which you might find useful.


The other key thing to mention and it is a point that Apple makes very strongly, is to name your functions and their parameters so as to make them as readable as possible from the calling site. You write a function once, but you most likely call it multiple times, so it is the calling site that needs to be really easy to read.

Returning to the game example, here is a dummy function to show damage caused to a target:

func displayDamage(damage: Int, target: String) {}

displayDamage(damage: 31, target: "Ogre")

There is nothing really wrong with the function, but calling it is a bit clunky and doesn’t read well with the repeated use of the word ‘damage’.

What about this version?

func display(damage: Int, doneTo target: String) {}

display(damage: 42, doneTo: "Wolf")

There are no repeated words in the caller and by using two labels for the second parameter, the calling site can read almost like a sentence, but inside the function, target is still a more logical name.

A third alternative is to use an un-named parameter if the naming logic is implicit in the function name itself:

func displayDamage(_ damage: Int, doneTo target: String) {}

displayDamage(12, doneTo: "Orc")


As promised above, a very quick explanation of closures, which really deserve their own post…

In Swift, as in many languages, functions can be passed as parameters to other functions. As an example, I have set up 2 functions to perform a simple calculation on a given integer:

func cube(_ number: Int) -> Int {
    return number * number * number

func square(_ number: Int) -> Int {
    return number * number

Now imagine that you wanted to create a more general function that could call either one of these functions with any number:

func doCalculation(_ number: Int, calculation: (Int) -> Int) -> Int {
    return calculation(number)

doCalculation takes 2 parameters. The first one is easy - it is just an integer. The second one is weird! For every parameter of a function, you have to supply the type of that parameter. Usually this is quite straight-forward: Int, String, MyCustomClass etc. But what is the type of a function? Option-clicking on the word cube in my function definition, I see this:

Function type

And ignoring the parameter labels, this basically provides the function type: Int inside parentheses for the input, then the arrow, then Int again for the return type. So the type definition for the cube function is (Int) -> Int. And when I define the type for the calculation parameter in the doCalculation function, this is exactly what I put. The last part of the function definition is specifiying the overall return type as an Int.

Using the cube and square functions inside doCalculation works like this:

doCalculation(7, calculation: square)
doCalculation(4, calculation: cube)

But what if I didn’t want to define all the functions I might call in advance? Then I can send the function body to the doCalculation function instead of using a pre-built function. This way of using a function inside another function is referred to as a closure.

doCalculation(6, calculation: { number in
    return number * 12

The doCalculation function in unchanged, but instead of passing it a reference to a function, I am directly passing it the instructions it should use to get the result. As with any function, the instructions are contained within a set of curly braces. The input to this function is listed after the opening curly brace followed by the keyword in. Then the function body does whatever it needs to and returns the result.

You may have heard the term trailing closure. This refers to a function where the last parameter is a function. If that function is called using a closure, there is a short-hand way of writing this, omitting the closure’s parameter name and moving the closing parenthesis to before the opening curly brace.

doCalculation(16) { number in
    return number % 3

With the filter, map and reduce functions I showed above, this is the way their logic was supplied but here is how the filter example would look without using a closure:

func checkName(_ name: String) -> Bool {
    return name.count > 3 && !name.contains(" ")

func checkPlayerNamesUsingFunction(names: [String]) -> [String] {
    let validNames = names.filter(checkName)
    return validNames

let allNames = [ "Woody", "Rex", "Slinky", "Buzz Lightyear", "Hamm" ]
let checkedNames = checkPlayerNamesUsingFunction(names: allNames)

Which methods you use are up to you - they all work. If you have a function that will be called in many different places, maybe it makes more sense to define it once and pass around a reference to that function. If not, a closure has the advantage that it keeps everything together. There is more to closures, particularly to do with variable scope, but I think this post has gone on long enough already…. maybe next time.

World Time in Words iOS Update

Permalink - Posted on 2018-06-14 00:41

Its been a long time since the last update to Time In Words for iOS but after prompting by Apple (update or we will remove it from the App Store), I finally did it. I was never really happy with the last design of Time in Words for iOS, particularly for the iPad, so this was a good opportunity to do a complete re-design, bringing the app more into alignment with its Mac counterpart. And it got a new name to match its new direction and is now called World Time in Words.

World Time in Words v 5.0 is available from the App Store.

In 2015, I released Time In Words v 4.0 for iOS. This was a big change as I had dropped the original QlockTwo concept and switched the emphasis to world time conversions that would be easy to read and understand. This bit worked out well, but the paging interface was not a great success - it made it too tedious to find the zone you were interested in.

The Mac version is a menu bar app that shows the selected time zones as separate menu items. iOS apps don’t have menus, but the closest thing to this is a table, so that is what I went with.

Basic display

As before, you can add, remove or re-order the time zones and the top three zones can be shown in your Today widgets.

Edit zones

Today widget

But the feature that I use most in the Mac app is “What time will it be when…”. In the iOS app, for reasons of space, the button is labelled “What time will it be?” but the functionality is the same: drag the slider to adjust the hour in your local time zone and see what that hour will be in your selected world zones. This is incredibly useful when you have family, friends and colleagues all over the world and really don’t want to call them at the wrong time of day.

What time will it be

The iPad version of the app is identical at this stage, but I am thinking of adjusting the interface so as to take advantage of the increased real estate. If other work doesn’t get in the way, this may happen…

Privacy Policy

Permalink - Posted on 2018-05-25 23:51

TL;DR: I don’t track you either on my web site or through my apps. If you want to contact me, please do so but I will not initiate any contacts.

As anyone who gets email would realise by now, the EU has introduced a General Data Protection Regulation designed to enhance online privacy. You will have been getting lots of emails announcing new privacy policies or asking you to opt-in to existing arrangements.

So here is my version of those emails (which you will not get by email because I do not store any user data):

  • None of my apps store data off your device.
  • I do not have any user data except for data specifically sent to me via web forms, direct email or in-app email.
  • If you have signed up to beta test one of my apps, you did give me your email address. No tests are currently on-going, but please contact me if you would rather I removed you from any future beta tests.
  • My web sites are now totally free of trackers and analytics software.

Most of my apps have a “Contact the Developer” button that creates an email that I will answer. If you do not want me to have your name and email address, do not use these buttons.

My web site has a contact page - if you use it, I will see your name and email address and I will respond. Again, if you do not want me to have this data, do not use this page.

Since I no longer have any analytics, I would really appreciate hearing if you find any of my posts useful or interesting.

App Updates

Permalink - Posted on 2018-05-25 23:22

Just a quick post to let you know about some recent app updates…

Man Reader

Man Reader v 1.10 was released on 11 May 2018.

I had to update Man Reader in November 2017 because of a really strange “feature” that arrived with macOS High Sierra. Man Reader displays the man pages as HTML which allows the tabs and internal links to work using anchor tags. These had worked for years, but under High Sierra, they just stopped working.

I eventually discovered that it was because I was loading the text directly into the WebView using:

[self.web.mainFrame loadHTMLString:manText baseURL:nil];

With no baseURL, the anchor links were all defaulting to about:blank and going nowhere. The solution was to save the text to a temporary file and then load using:

NSURLRequest *request = [NSURLRequest requestWithURL: tempFile];
[self.web.mainFrame loadRequest: request];

Needless to say, this took me ages to work out, including a lengthy excursion into using WKWebView to see if the more modern web view would solve the problem.

The second update (May 2018) was in response to a crash report from a user. I had great difficulty tracking this one down and even now, I cannot see how it can have happened, but it was in relation to the utility apps that are displayed in the toolbar.

For each app, Man Reader checks to see if the app bundle exists, then it checks for a bundle identifier. It appears that this can come back as nil which I had not realised. And trying to insert an item with a identifier of nil into the toolbar caused a crash.

As you can see from the code, ManReader is written in Objective-C. Going back to Objective-C from Swift is painful! And I know that this crash could not have happened if the app had been written in Swift as the identifier would have been an optional and I would have been forced to check that it was not nil before using.

On the plus side, Objective-C apps are tiny in comparison to Swift apps. And the Mac App Store review process set a new record for me. I submitted the app at 10:58 am and it was on sale at 12:03 pm the same day - 66 minutes from start to finish.

Sequenza VII

The other app that I updated recently is Sequenza VII. Version 1.2 was released on 23 April 2018.

This is an app with a very limited audience - specifically oboe players who want to learn to play Berio’s weird music. However Apple sent me a notice saying that as it hadn’t been updated for ages, it would be removed from the store within 30 days unless I did something.

Updating it to use the iPhone X display was surprisingly difficult. I set the minimum system version to 11.0 and changed the storyboards to use the latest Xcode but the horns on either side of the notch were still being left blank. In the end, the trick I found was to create a new Launch storyboard - that seemed to fool the system into re-considering all the layouts.

Man Reader

Permalink - Posted on 2018-05-11 00:00

Man Reader is a utility app for reading macOS’s man pages. Man Reader allows quick, convenient and easy access to the man pages on your system, useful for programmers, system administrators and tweakers.


Man pages are available for the Unix commands used mostly in Terminal or when shell scripting. These man pages are normally displayed in Terminal using the “man” command e.g. “man man” gives you the man page for the man command.

However there are problems with this: the man page is displayed to you in your Terminal window page by page and when you have got to the bottom, you have to know to press ‘q’ to get out of the man page display, at which point it disappears completely. Hope you have a good memory!

There are various tricks to get around this: opening it in a separate window, piping it to Preview as a PDF, listing it as a single page etc, but none of these are really convenient, which is why I wrote Man Reader. Basically, I reckon that if I want a utility, then there must be other people who would want the same thing.

Man Reader assembles a list of the commands with available man pages on your system - this will vary according to what developer tools you have installed. These commands are listed for you and you can click on any one to display the man page for that command.

Man Reader Features:

  • List of all available man pages on your system.
  • Show only a section of the pages.
  • Search for a man page by name.
  • Display man page in text or HTML (different pages look best in different formats).
  • Step back & forward through recently viewed man pages.
  • Live links to ‘See Also’ entries.
  • ‘Sticky notes’ at the side to jump to sub-sections in a page.
  • Choose a font and size for the display.
  • Convenient buttons in the toolbar allow quick access to commonly used utilities.
  • Sand-boxed for OS X Lion & later.

Man Reader version 1.13 changes (26 May 2021):

  • Add missing links for non-standard man pages.

Man Reader version 1.12 changes (17 May 2021):

  • Fixes issues with crashing on first run and with dark mode over-riding the user preferences.

Man Reader version 1.11 changes (16 May 2021):

  • I am working on a major update to Man Reader, but this is taking longer than expected due to other commitments, so this is an interim release to fix some of the UI problems with the current version.

Man Reader version 1.10 changes (11 May 2018):

  • Fix for possible crash if toolbar apps are not available.

Man Reader version 1.9 changes (27 Nov 2017):

  • Fix for High Sierra problem where page navigation had stopped working.

Man Reader version 1.8 changes (23 Oct 2016):

  • More complete search for man pages, including in third-party IDEs.
  • Fix for glitch when displaying previously selected page on launch.

Man Reader version 1.7 changes (10 Oct 2016):

  • Updated for macOS Sierra.
  • List of pages now uses alternating colors even if not using the defaults.
  • Minimum supported system version raised to 10.11.
  • Minor display glitches fixed.

Man Reader version 1.6 changes (13 Jul 2016):

  • Much improved searching for available man pages, including permissions fix for some pages.
  • Fixed error with new search term being over-written.
  • Sand-boxed version now works just as well as the non-sand-boxed so please switch back to this version.

Man Reader version 1.5 changes:

  • Much improved searching for available man pages.
  • Sand-boxed version now works just as well as the non-sand-boxed.

Man Reader version 1.4 changes:

  • Fix for plain text view not wrapping correctly for odd-sized fonts.
  • Fix for HTML text view over-riding font colors that may be invisible.
  • Search for missing entry (e.g. g++) no longer requires Enter or Return.
  • Better automatic selection of matching entries while searching.
  • Fix for animation warning message appearing in Console.
  • Status display shows when man page list is being updated.
  • Searching inside a page now allows a minimum of 2 characters (was 3), so flags e.g. ‘-b’ do not need to be escaped.
  • Fixed path for Network Utility in tool bar (moved in OS X 10.9).
  • More information available about the effects of sand-boxing for this app.

Man Reader version 1.3 changes:

  • Better formatting of plain text to allow for HTML entities.
  • Fix for font in some HTML pages getting bigger & bigger.
  • Failed search for page will search for a matching man page anyway.
  • Editable apps in toolbar (see Preferences & View menu).
  • Fixed bug when setting custom colors for marker tabs.
  • Changed shortcuts for Find (see Edit menu).

Man Reader version 1.2 changes:

  • Customizable colors for text, background, links, found text.
  • Searching for text within pages marks all matches.
  • Pages will adjust line width to suit window size, even in plain text mode.
  • If a search only results in a single page, press Return to display it.
  • More man pages should be located on your system.
  • Fix for bug where app did not always remember full screen setting.
  • Fix for bug where some pages were being added to the history list twice.

Man Reader version 1.1 changes:

  • Search for text within a man page.
  • Bookmark frequently visited pages.
  • Search man page list using “Starts with” or “Contains”.
  • Preferences for the marker tabs: choose a pre-made color set or design your own.
  • Full screen mode now supported.
  • Custom toolbar configurations now saved & restored correctly.

If you have any problems with Man Reader, any suggestions for future versions or encounter any bugs, please contact me.

Berio's Sequenza VII

Permalink - Posted on 2018-04-23 00:00

Luciano Berio wrote a series of Sequenzas for various instruments with Sequenza VII being the one for oboe.

Preparing this work creates some unique problems for the oboist as Berio did not adhere to any time signature that could be indicated by a metronome. Instead, each line consists of 13 bars (measures) with each bar’s length specified in exact seconds.

When my son (an oboist currently studying in Melbourne, Australia) started trying to learn this piece, it occurred to him that having an iOS app developer in the family could be of some assistance. So with instructions from him and with suggestions from other oboists, I have developed the Berio Sequenza VII app for iPhone or iPod Touch.

With the default settings it will count the bar lengths, using metronome-like sounds to mark the starts of bars and lines. The player who needs to practice a specific bar can easily set the app to start at that bar and even to repeat that bar length continuously.

Tapping the “i” button at the bottom right of the screen takes you to the more advanced options.

The “Settings” section deals primarily with the B4 drone that is supposed to accompany the performance of this piece. While in an actual performance, the dynamics of this drone would vary, for this practice app it remains at a constant volume as specified by you. The volume can be set to a percentage of the iPhone’s current volume setting. If it is still too quiet, plug your iPhone into a speaker or use some sort of physical amplification. If you prefer to play with an A other than 440 Hz, that can be adjusted. And finally, the wave form used to generate this drone sound can be switched between a sine wave or a triangle wave. Disclaimer: excessive use of this drone may cause loss of friends!

The Settings page also includes an option to slow down the times for practice. At 100% speed, bar 1 on each line will last for 3 seconds. The speed can be reduced to allow each bar to last longer, for use during the learning process.

The “Bars & Sounds” section allows you to customise the various options marking the start of each new bar. You can specify the number of seconds & the sound used to count you in after tapping the Start button. You can also select which of the metronome sounds to use to mark the start of each bar, making the first bar of each line use a different sound if you prefer. Finally, in case you are playing so loudly that you are unable to hear the iPhone, you can set the screen to flash a different color at the start of each new bar.

Jacqueline Leclair wrote a supplementary edition of this work in 2000 using traditional time signatures in a way that almost exactly duplicates the original timings. This app is designed for use with the original score using Berio’s real time bar lengths.

Consistent Swift Style

Permalink - Posted on 2018-03-30 23:35

  • Why is important to style your code?
  • How do you decide on a style?
  • Is there a way to enforce this style automatically?

What is style in Swift?

Style applies to writing in any programming language and refers to the way you structure your code.

For example, how to you arrange braces?

if theValue < 10 {
    // do one thing
} else {
    // do the other thing


if theValue < 10
    // do one thing
    // do the other thing

or anything in between?

Do you use camelCase or snake_case?

Do you always start class names with an uppercase letter?

And of course there is the Great Debate: tabs or spaces? And how many?

Why is important to style your code?

You only write code once, but you & others will read it many times.

As I tell students, in six months time some poor sucker is going to have to read this code, and worse still, that poor sucker might be you, so make it readable.

There is a cognitive load involved in reading code but you can lighten that load by using consistent patterns that your brain can recognise quickly without having to re-analyse them each time.

How do you decide on a style?

Do a search online for Swift style guide and you will get numerous results, although you do have to dodge the sites dedicated to Taylor Swift’s dress sense! I like the Ray Wenderlich guide although its emphasis is on styles that read well in print and in web pages. The LinkedIn guide is also good. GitHub also has a style guide but it hasn’t been updated recently. However it contains some good general advice.

But in the end, you have to decide your own style. The important thing then is to be consistent. I don’t care whether you use camelCase or snake_case, tabs or spaces, but if you use a mixture your code will be harder to read, so pick a style and stick to it.

Is there a way to enforce this style automatically?

This is where SwiftLint comes into the picture. SwiftLint is a tool that can check your code and look for style violations. While it comes with a default set of rules, you can configure these rules to suit your own style.

Installing and Running SwiftLint

To install SwiftLint, I recommend using HomeBrew. Once you have HomeBrew installed, open Terminal and type brew install swiftlint. You can update it any time using brew upgrade swiftlint.

You can run SwiftLint directly from the Terminal. cd to the folder containing your Xcode project and type swiftlint. For a brand new iOS project, you will probably get a result similar to this:

Linting Swift files in current working directory
Linting 'ViewController.swift' (1/2)
Linting 'AppDelegate.swift' (2/2)
ViewController.swift:23: warning: Vertical Whitespace Violation: Limit vertical whitespace to a single empty line. Currently 2. (vertical_whitespace)
ViewController.swift:25: warning: Trailing Newline Violation: Files should have a single trailing newline. (trailing_newline)
AppDelegate.swift:16: warning: Vertical Whitespace Violation: Limit vertical whitespace to a single empty line. Currently 2. (vertical_whitespace)
AppDelegate.swift:44: warning: Vertical Whitespace Violation: Limit vertical whitespace to a single empty line. Currently 2. (vertical_whitespace)
AppDelegate.swift:46: warning: Trailing Newline Violation: Files should have a single trailing newline. (trailing_newline)
AppDelegate.swift:17: warning: Line Length Violation: Line should be 120 characters or less: currently 144 characters (line_length)
AppDelegate.swift:23: error: Line Length Violation: Line should be 120 characters or less: currently 285 characters (line_length)
AppDelegate.swift:24: warning: Line Length Violation: Line should be 120 characters or less: currently 159 characters (line_length)
AppDelegate.swift:28: error: Line Length Violation: Line should be 120 characters or less: currently 218 characters (line_length)
AppDelegate.swift:29: warning: Line Length Violation: Line should be 120 characters or less: currently 141 characters (line_length)
AppDelegate.swift:33: warning: Line Length Violation: Line should be 120 characters or less: currently 155 characters (line_length)
AppDelegate.swift:37: warning: Line Length Violation: Line should be 120 characters or less: currently 194 characters (line_length)
AppDelegate.swift:41: warning: Line Length Violation: Line should be 120 characters or less: currently 128 characters (line_length)
Done linting! Found 13 violations, 2 serious in 2 files.

I have removed the full path that will be listed for each file just to make this fit better.

These reports show the file and line number, whether this is an error or a warning, a description of the error and the name of the SwiftLint rule that caused the warning or error.

You could now go through and fix each of these but there are 2 solutions to make things easier: Try entering this in the Terminal window: swiftlint autocorrect.

Correcting Swift files in current working directory
Correcting 'ViewController.swift' (1/2)
Correcting 'AppDelegate.swift' (2/2)
ViewController.swift:22:1 Corrected Vertical Whitespace
ViewController.swift:23 Corrected Trailing Newline
AppDelegate.swift:15:1 Corrected Vertical Whitespace
AppDelegate.swift:43:1 Corrected Vertical Whitespace
AppDelegate.swift:43 Corrected Trailing Newline
Done correcting 2 files!

And now if you run swiftlint again you will only get Done linting! Found 8 violations, 2 serious in 2 files. and all the remaining issues are for Line Length Violation This shows that autocorrect cannot fix everything and while it is good on spacing, it has trouble with more complex issues. But it is still worth doing as it can do a lot of the tedious fixes that creep into Xcode projects.

Incorporating SwiftLint into Xcode

The next thing to do to make your life easier is to add SwiftLint to your Xcode project so that it can run automatically whenever you do a build.

Open your project in Xcode and select the project itself at the top of the Navigator on the left. Select the target for the main app and click the Build Phases tab along the top. Click the + button at the top left of the existing build phases and choose ‘New Run Script Phase’. Expand the newly added phase and paste in the following script:

if which swiftlint >/dev/null; then
  swiftlint autocorrect
  echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"

Your Xcode window should look something like this:

SwiftLint Run Script phase

If you think this looks like it is running SwiftLint twice, you are correct. The first time through it corrects what it can and the second pass reports all remaining issues. This is still faster than manually correcting the easy stuff. So now you will see any violations in the Xcode issue navigator when you do a build and you can click the entry to go directly to the code.

SwiftLint errors & warnings in Xcode issues navigator

Configuring SwiftLint

Now you are all set to SwiftLint all your code, but how do you decide what styles SwiftLint should enforce? Go back to Terminal, make the Terminal window as wide as possible and run swiftlint rules which will return a table like this (click to see full-sized image):

SwiftLint Rules

For details on what each rule does, check out the entries in Rules.md

As an example, look at the rules for line_length:

| identifier                               | opt-in | correctable | enabled in your config | kind        | configuration       |
| line_length                              | no     | no          | yes                    | metrics     | warning: 120, er... |

And by making my Terminal window full width, I can see the configuration column contains warning: 120, error: 200, ignores urls: false, ignores function declarations: false, ignores comments: false.

  • The rule name (identifier) is line_length - this is what appears in the issue navigator or Terminal.
  • It is not an opt-in rule, meaning that it is enabled by default.
  • It is not correctable by autocorrect.
  • It is enabled in this configuration.
  • And then comes the configuration:
    • a line of more than 120 characters will generate a warning
    • a line with more than 200 characters will generate an error and stop the build
    • this rule will not ignore URLs, function declarations or comments

To set your own configurations, you need to create a .swiftlint.yml file in the same folder as your Xcode project. The leading period makes the file invisible, so you will need to create and edit it using Terminal.

In the Terminal, cd to the folder containing your Xcode project file and run touch .swiftlint.yml to create the invisible file. You can edit the file in Terminal using nano, vim or whatever you prefer, but you can also open it in any text editor. I prefer to use Atom so I open the file by running this command: atom .swiftlint.yml.

The SwiftLint ReadMe has a section about configuration which shows the format and the various general headings you can use, as well as how to configure an individual rule.

Here is my .swiftlint.yml file:

disabled_rules: # rule identifiers to exclude from running
included: # paths to include during linting. `--path` is ignored if present. takes precendence over `excluded`.
excluded: # paths to ignore during linting. overridden by `included`.
  - Carthage
  - Pods
  - closure_end_indentation
  - closure_spacing
  - contains_over_first_not_nil
  - empty_count
  - explicit_init
  - fatal_error_message
  - force_unwrapping
  - literal_expression_end_indentation
  - multiline_arguments
  - multiline_parameters
  - operator_usage_whitespace
  - overridden_super_call
  - private_outlet
  - prohibited_super_call
  - trailing_closure
  - unneeded_parentheses_in_closure_argument
  - 60 # warning
  - 100 # error
  - 150 # warning
  - 200 # error
  ignores_case_statements: true
  • No rules are disabled by default.
  • included is blank which means it checks every folder…
  • … except for the ones listed in the excluded section.
  • opt-in-rules: I went through the list of rules with opt-in equal to yes and enabled all I thought useful.
  • function_body_length - the default warning length is 40 but I allow myself 60 as that fits on my screen so I can always see the entire function without scrolling.
  • line_length - with a bigger screen, I lengthen both the warning and error lengths.
  • cyclomatic_complexity checks for functions that are getting so complex that the compiler might run into trouble. I have this on with the default warning & error limits, but I set it to ignore case statements as they can often trigger this without really being too complex.

Now that my .swiftlint.yml file is edited, doing a build uses those settings and for a new iOS project, I am now down to 2 errors and 3 warnings, all due to long lines in AppDelegate.swift.

The other main way to configure SwiftLint is by disabling specific rules in my code.

As an example, I have an enum for direction:

enum Direction {
  case up, down, left, right

When I build this, SwiftLint gives a warning: Identifier Name Violation: Enum element name should be between 3 and 40 characters long: 'up' (identifier_name)

This tells me that up is too short a word to use as an identifier according to the identifier_name rule. In this case, up is the obvious identifier to use, so I want SwiftLint to let it pass. But I don’t want to check my configuration file, because I want it to catch other short identifier names.

The solution is to add this comment to my code, before the case line:

// swiftlint:disable next identifier_name

This tells SwiftLint to ignore the next identifier_name warning or error it sees and now my code builds without error.

Rules can also be disabled or enabled by file. Check out the Disable rules in code section of the SwiftLint ReadMe for more details.

What are the benefits?

For me, SwiftLint enforces a number of good habits:

  • Files are kept relatively short.
  • Functions are always small enough to fit on a single screen.
  • Variable names & function names cannot be too short and non-descriptive.
  • Braces, indentation and white-space are always consistent.

And sometimes the warnings make me think of a better way to do things.

Icon Builder 5

Permalink - Posted on 2018-02-18 00:19

Icon Builder 5.0 is now available from the Mac App Store. This is a complete re-write for better compatibility with Apple’s latest icon requirements. Read on to see what I have fixed and how…


When I came to create a new iOS app recently, I found out that Icon Builder had fallen behind Apple’s requirements in three ways:

  1. The 1024 x 1024 marketing icon is now supposed to be inside the app’s icon set.
  2. Icon files must have their color profile set to sRGB (P3 is also valid for iOS apps).
  3. iOS icon files must have no transparent pixels and the alpha channel must be removed from the files.

When I set to work fixing these problems I soon ran into issues with the existing version of Icon Builder which was created 6 years ago.

  • It was written in Objective-C which I am increasingly finding difficult and un-safe to write.
  • The app was written when I was very much a beginner in Mac apps and this is obvious from the code…
  • There was a lot of legacy code left over from previous changes and extensions.

So I decided that the most interesting thing to do would be to start almost from scratch and re-write the app in Swift using better techniques.

The Re-write

Now instead of the Massive View Controller, I have a larger set of small files, each with their own responsibility. Enums and structs dictate the various requirements for the different devices or app types. Other structs deal with creating the images, the folder management and writing out the files. An NSImage extension handles the resizing and reformatting of the images. This is now an app that I would not be ashamed to show anyone, except perhaps for the need to add more unit tests.

Adding a color profile

But then we get to the new features needed. Adding the 1024x1024 icon to the app icon set was easy, especially after the re-factoring. But what about the color profile?

This was not as easy as I expected - there is no built in command to apply a profile but here is the solution that I finally found:

extension NSImage {

  func convertImageTo_sRGB() throws -> Data {
      guard let colorSpace = CGColorSpace(name: CGColorSpace.sRGB),
          let cgi = self.cgImage(forProposedRect: nil,
                                 context: nil,
                                 hints: nil) else {
                                  throw ImageError.cantMakeCgImage

      let ci = CIImage(cgImage: cgi)

      guard let pngData = CIContext().pngRepresentation(of: ci,
                                                        format: kCIFormatRGBA8,
                                                        colorSpace: colorSpace) else {
          throw ImageError.cantConvertToPng
      return pngData

  • This takes the NSImage and converts it to a CGImage, first checking that the appropriate color space exists.
  • Then it uses the Core Graphics CGImage to create a Core Image CIImage.
  • There is a new API in macOS 10.13 to extract the png data from a CIImage while assigning a color profile.
  • This Data can then be written directly to a file and there you have a PNG with an attached color profile.


Now problems 1 & 2 have been solved. Problem 3 was the most difficult. It turned out to be a two-part problem because an image file can have no transparent pixels but still have an alpha channel in the file data.

At first, I thought maybe I could just circumvent the whole problem by converting the images to JPEGs which have no transparency or alpha channel. Using the code above, I just changed it to getting the jpegRepresentation instead and saving with a .jpg file extension.

While this solved the alpha channel problem, the transparent parts of the icon just went black which was a not a good look.

Transparent image converted to JPEG

For anyone horrified at my use of force-unwrapping, I never do this in a production app but in a playground, it makes the code shorter and it doesn’t really matter if I get a crash there.

Converting transparent pixels to white

So the first step must be to set the transparent parts of the image to another color. Searching for solutions online, most of the ones I came up with were very slow (processing each pixel) or so complicated that I didn’t understand them, and I hate just copy-pasting code that I don’t understand at all.

But eventually I found something that I morphed into this:

extension NSImage {

    func makeAlphaWhite() -> NSImage {
        guard let imageData = self.tiffRepresentation,
            let imageRep = NSBitmapImageRep(data: imageData),
            let jpegData = imageRep.representation(using: .jpeg, properties: [
                NSBitmapImageRep.PropertyKey.compressionFactor: NSNumber(value: 1.0)
            let jpegImage = NSImage(data: jpegData) else {
                return image
        return jpegImage


It used basically the same trick of converting the image into a JPEG but doing it this way via NSBitmapImageRep turned the transparent pixels white instead of black. And as you can see, this gave a much better looking image:

Transparent portions converted to white

Now I was able to continue with my plans to have JPEGs rule the world! This worked really well in my early tests but then I came to try a Stickers app and the icons didn’t work. I couldn’t even drag them in manually! Back to the Apple docs and I see that icons must be PNGs.

When I changed the transparent pixels to white, added the color space and then saved the PNG data, I got an image that looked correct but the file still contained an alpha channel. So I had to come up with a method that re-wrote the PNG data in such a way that it never contained any alpha data at all.

Removing the alpha channel

Graphics experts are probably groaning aloud by now, but I did eventually arrive at a solution, however hacky:

extension NSImage {

    func convertImageTo_sRGB_noAlpha() throws -> Data {
        guard let colorSpace = CGColorSpace(name: CGColorSpace.sRGB),
            let cgi = self.cgImage(forProposedRect: nil,
                                   context: nil,
                                   hints: nil) else {
                                    throw ImageError.cantMakeCgImage

        let ci = CIImage(cgImage: cgi)
        guard let jpgData = CIContext().jpegRepresentation(of: ci,
                                                           colorSpace: colorSpace) else {
            throw ImageError.cantConvertToJpg
        guard let jpegImage = NSImage(data: jpgData) else {
            throw ImageError.cantConvertToJpgImage
        let pngData = try jpegImage.convertImageTo_sRGB()
        return pngData

  • Take the image after changing the transparent pixels to white.
  • Convert it to JPEG data with the required color space.
  • Convert the JPEG data back to an image - this will contain NO alpha data.
  • Use the original routine to convert this JPEG into PNG data with the correct color space.

Running this in the playground looks like this: Creating non-transparent PNG in playground

And as you can see from the file info, it results in a file with the correctly assigned color profile and no alpha channel:

Final result file info

The double shuffle sounds time-consuming and in-efficient but it really doesn’t take long. In my tests, by far the longest part of creating an icon set is opening the file dialog.

Future plans

  • Add more unit tests.
  • Work out how to replace the transparent pixels with a selected color.
  • Offer better cropping and image positioning options.


For resizing and cropping images, I use Matt Gemmell’s NSImage+MGCropExtensions and for further reading, I recommend Apple’s Human Interface Guidelines concerning app icons for iOS and macOS.

Note: here is Australia we use the spelling colour but for consistency with the code samples, I have used color throughout the text.

NCSS 2018

Permalink - Posted on 2018-01-05 01:33

I gave a Masterclass on Swift at the NCSS Summer School 2018 in the University of Sydney on 9th January 2018. This post contains useful links for use in relation to the material covered during my class.

Online Sandboxes


Contact Details


Permalink - Posted on 2017-12-22 07:05

Mark Time

Permalink - Posted on 2017-12-11 23:14

Mark Time is an application for Celestial Navigation that solves the problem of how to take an accurate time reading to go with each sextant sighting. Here is how it was developed…

A day in the life of a software developer - “it would be great if there was an app that did…”

One of the family is learning celestial navigation and was struggling with the problem that you either need a partner or more than 2 hands. The key factor is that you need to record the exact time at the moment when you take your sighting. And this time has to be in UTC to make your subsequent calculations work.

Since this is a very simple app, I decided it would be fun to describe the development process from first specifications to release in the App Store.

The Basic Specs

  • tap anywhere on the screen to record the time
  • convert the time to Universal Time (UT)
  • display that time in a specific format: DD:HH:MM:SS
  • store the last 5 tap times

A UITapGestureRecognizer over the entire view solved the first requirement. The native Date object handles time zone conversions perfectly, and then it was a matter of configuring a DateFormatter with a custom format string to provide the required date display.

The last 5 times are stored in UserDefaults and displayed in reverse order so the most recent is always at the top.

UI considerations

  • colour scheme must work in bright sunlight
  • text should use dynamic sizing so it works if people adjust the text size on their iPhones
  • the UI elements must be out of the way of the new iPhone X system gestures.
  • while it will most likely be used on iPhones, allow for iPads as well

I had done extensive tests of colour schemes when developing my golf scoring app 19th Hole, so I already had the answer to the colours question: dark grey background with white text.

Allowing for dynamic type should have been easy - choose a font style e.g. body, headline, title 1 and set it to adjust automatically. But with a display that is mainly numeric, the display looked terrible because the numbers in the default San Francisco are non-proportional. So I switched to Helvetica Neue and watched for dynamic font size changes manually.

The iPhone X should be fine since I used the new safe area layout guides.

For iPad, I didn’t make a lot of UI changes since I don’t expect it to be used much, but the display is bigger and probably easier to read.

Mark Time


As always, once the first few iterations have been through the testing process, there were a few things that needed changing and then feature creep set in…

  • change the date format to be more readable
  • change the basic tap gesture so that it triggers on tap down, not tap up
  • add a button to clear all the stored data
  • display the current time in UTC and in the same format
  • cheat mode - record latitude and longitude for each time so the calculations can be checked
  • change the format for showing the latitude and longitude
  • sound & haptics to provide feedback
  • settings

The date format was DD:HH:MM:SS so for 12th December at 1:01:46 pm, this would show 12:13:01:46 which we decided was a bit confusing. One tended to assume the first section was actually the hours. Under the new scheme, that same date displays as 12d 13h 01m 46.654s. The extra precision on the seconds was to show that the time really was changing if you tapped multiple times quickly.

To make the time record immediately, I removed the UITapGestureRecognizer and placed UIButtons covering all the relevant active areas. They respond on Touch Down for a much faster reaction.

Usually, I make a separate View Controller for preferences. This time, because the app needed access to the standard Settings app for Location services, I decided to add the app’s preferences to the app’s page in the Settings app. This worked really well, and made the app itself smaller and simpler.

Mark Time

In cheat mode, the location is recorded at every tap and then the info button beside each time shows the details. This needed to handle the permissions required for accessing the user’s location. The latitude and longitude are shown in decimal format and at first, I also showed them in DMS (degrees, minutes, seconds) format. I found out that for navigation calculations, they prefer to see degrees and decimal minutes, no seconds. And rather oddly, this is displayed something like this: 153° 22’.84 E

Sounds and haptics were added, configurable through Settings. The sound was a nice loud double-beep designed to be clearly audible to tell you when you had recorded a time.

Mark Time


After numerous rounds of TestFlight, I was ready to release. The app was submitted to iTunes Connect and ready for review on Dec 9, 2017 at 7:36 PM. It moved into review on Dec 11, 2017 at 8:07 AM and was ready for sale on Dec 11, 2017 at 10:19 AM. So less than 39 hours from start to finish of the review process for a new app - things have certainly changed!

The app is free - you can get it from the iTunes App Store.

Moving to Hugo

Permalink - Posted on 2017-11-29 07:42

Yesterday, I came to update my blog: I had a new post in draft form and I wanted to update the Swift code to version 4. However installing High Sierra had removed Jekyll which is the site generator that I had been using. I re-installed Jekyll but found that it had been updated from version 2 to version 3.

Jekyll Problems

Then my problems started: missing dependencies due to the basic Jekyll install no longer including certain features, and then syntax errors due to changes in the way things are done, particularly to do with pagination.

I tried to fix this myself, then thought that maybe the theme I was using had already solved these issues so I tried re-installing that. It wanted to add about 25 more gems and then failed to install - sigh - spend some time rolling that back…

At this point I decided that if Jekyll was going to cause me a lot of trouble, it might be worth looking at an alternative.

My main criteria were the ability to import my Jekyll site and the ability to host on GitHub Pages. After checking out the options, I decided to have a look at Hugo.

Moving to Hugo

One of the most lauded features of Hugo is speed. I had found with Jekyll that when I saved an edited page, it took about 5 seconds before the edits could be reloaded into the browser. Hugo is supposedly fast and does auto reloads.

Following the Quick Start guide, I installed Hugo. Importing my Jekyll site worked easily and so fast I wasn’t sure anything had happened, transferring my posts to contents/posts and my other files (status pages, images etc.) to static.

Then the main exercise appeared to be choosing a theme which would provide not only the visuals but the capabilities of the site.

So I drew up a list of demands for any theme I chose:

Must Have Features

  • Responsive
  • Blog style:
    • front page with recent posts
    • tags
    • archive page
  • Written using Markdown
  • Static pages for apps listing, about, contact etc.
  • Syntax highlighting
  • Social links
  • Google Analytics

Would Be Nice Features

  • Disqus commenting
  • Twitter cards
  • JSON Feed
  • Searching within the site

The Hugo themes page https://themes.gohugo.io has themes listed by capabilities, but no way that I could see to combine a selection of capabilities.

Some of the features like Google Analytics or Disqus comments, I could probably add myself using templates from theme that did include them, if the template I chose did not.

Conveniently, nearly all these seem to come with an exampleSite folder that contains the configuration info.

Configuring a Theme

After testing out several alternatives, I decided to go with Even - at least to start with. I installed the theme and copied the contents of the example config.toml to my own config.toml file and started configuring.

I wasn’t happy with some of the fonts, but soon worked out how to change the CSS in the theme and then re-build it to apply the changes. And I changed the theme colour from the default red to “Cobalt Blue”.

Most of the other changes were done using the config.toml file. I was able to set up menus, configure the social media links I wanted to show, set date formats, set the number of items to show per page and so on.

I had a couple of more static pages that I wanted to show, so I added their Markdown files to the content folder.

One nice feature which I had missed in Jekyll (or at least the way I had it set up) was the ability to separate blog posts from more static web pages. Each of my apps has an information/support page that does not accept comments and doesn’t need to be listed in the Archives. By moving these Markdown files from contents/posts to contents/pages, I was able to achieve this.

Adding Google Analytics and Disqus commenting was as easy as entering my IDs in the relevant places in the config.toml file.

I had to do some editing of my imported posts from Jekyll - mainly getting rid of references to {{ site.url }} so that images and internal links would work. And sometimes I just needed to re-save a file to make Hugo re-evaluate it (there is probably a command to force a complete re-build if I looked for it.)

Working out the Structure

One thing that I was puzzled by was what templates the various pages are generated from.

The main page is easy enough as the theme folder has a layouts folder with an index.html file containing the templating. When a post is displayed, that looks like it comes from layouts/posts/single.html while layouts/posts/summary.html contains the templating for each entry in the index page.

But clicking on the Archives link in the me takes me to https://troz.net/post/ and there is no post.html file in layouts. There is a post folder, but it contains the single.html & summary.html files described already.

Delving ever deeper, layouts/_default/section.html appears to contains the Archives page template. But how does that relate to the https://troz.net/post/ link? And the Tags template is in layouts/_default/terms.html but appears in https://troz.net/tags/. Checking the Hugo documentation for creating a theme, I find the information I need. Hugo has a selection of file paths that it checks for such templates, and these file paths match some of those. So now I know where to go to customise further.

One feature that I really like about the Even theme is the ability to have a table of contents displayed beside each blog post if your page is wide enough. It takes the headers in the post and uses them to make the table. I may need to add or edit the headers in some posts, but I really like this feature.

And if you want a laugh, test out the 404 page - here is a bad link - which generates a random text emoji each time!


I wanted to use my existing GitHub Pages setup, so I replaced the site files in my local repository with the new Hugo site files. I generated the static site files using hugo in Terminal, then pushed the pages to GitHub. All I had to do then was change the settings so that GitHub Pages knew my site was coming from the docs folder and I was live with the new site.

Final Thoughts

So how am I going with my check list?

  • Responsive - ALMOST, not Hugo’s fault
  • Blog style - YES
  • Written using Markdown - YES
  • Static pages for apps listing, about, contact etc. - YES
  • Syntax highlighting - YES
  • Social links - YES
  • Google Analytics - YES
  • Disqus commenting - YES
  • Twitter cards - NO
  • JSON Feed - NO
  • Searching within the site - NO

The Hugo generated pages are all responsive and look great on my iPhone, but my old static page for listing my apps does not look good, so I need to re-design that.

Twitter cards - I have found some articles on how to set that up, so it is possible, but I haven’t done it yet.

JSON Feed is not working. There are themes that apparently have this, but I haven’t yet worked out how to implement it - hopefully later.

In-site search - this was something I was able to get in my old WordPress site, but not in Jekyll. There are Hugo themes listed that support search, but they seem to just give a link to Google or DuckDuckGo. Maybe this can be edited to restrict it to the site, but I dislike using such searches, so I will not add a search unless it works internally. One theme I found uses Algolia to search the site, so I will investigate that.

Overall, I am impressed. The transition was relatively easy, especially considering that I didn’t take the time to learn anything about Hugo first, but just blundered in and tried to work it out on the fly.

The speed of generating pages and the live reload while developing make Hugo a pleasure to work with. Now all I have to do is write some interesting posts…

And I want to tidy up the URLs, headers and tags for the older pages as well as investigating Twitter cards, search & JSON Feed.


Permalink - Posted on 2017-11-26 01:22

JSON Parsing in Swift 4

Permalink - Posted on 2017-06-18 00:00

Updated: 3rd September 2017.

Since JSON has become the de facto standard for data transfers around the internet, there has always been a lot of interest in Swift libraries to parse JSON into Swift classes or structs. Searching for “swift json library” on GitHub discovers 77 86 repositories. So why are there so many? And what has Swift 4 done to sherlock them all?

The problem has always been converting loosely typed JSON to strictly typed Swift which involves a lot of type casting, checking, optionals etc. Swift has always provided access to the Objective-C methods for converting JSON to and from NSData, NSDictionary and NSArray. (These are now called Data, Dictionary and Array, but those labels are so universal, that I sometimes feel a more specific nomenclature would be useful. Have you tried doing a search for ‘Data’?)

For sample data, I am using https://jsonplaceholder.typicode.com/users which returns 10 user objects in this format:

  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "Sincere@april.biz",
  "address": {
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough",
    "zipcode": "92998-3874",
    "geo": {
      "lat": "-37.3159",
      "lng": "81.1496"
  "phone": "1-770-736-8031 x56442",
  "website": "hildegard.org",
  "company": {
    "name": "Romaguera-Crona",
    "catchPhrase": "Multi-layered client-server neural-net",
    "bs": "harness real-time e-markets"

The goal will be to convert this to an instance of this matching Swift struct:

struct User {
    let id: Int
    let name: String
    let username: String
    let email: String
    let phone: String
    let website: String
    let address: Address
    let company: Company

    struct Address {
        let street: String
        let suite: String
        let city: String
        let zipcode: String
        let geo: Coordinates

        struct Coordinates {
            let lat: Double
            let lng: Double

    struct Company {
        let name: String
        let catchPhrase: String
        let bs: String

The first thing to note is that the Swift struct (and its embedded structs) use multiple different types: Int, String, Double, Address, Coordinates, Company. The JSON data only has strings and numbers and even then, some of the numbers are really strings - look at the lat & lng entries. So converting from JSON to a struct and back again has always been problematic, but let’s give it a go using built-in Swift 3 processing with no external libraries.

Decoding in Swift 3

You can insert this into a playground or download my playground and check out the Swift 3 JSON page:

import Foundation

let sampleDataAddress = "https://jsonplaceholder.typicode.com/users"
let url = URL(string: sampleDataAddress)!
let jsonData = try! Data(contentsOf: url)

struct User {
    let id: Int
    let name: String
    let username: String
    let email: String
    let phone: String
    let website: String
    let address: Address
    let company: Company

    init?(dict: [String: Any]) {
            let id = dict["id"] as? Int,
            let name = dict["name"] as? String,
            let username = dict["username"] as? String,
            let email = dict["email"] as? String,
            let phone = dict["phone"] as? String,
            let website = dict["website"] as? String,
            let addressDict = dict["address"] as? [String: Any],
            let address = Address(dict: addressDict),
            let companyDict = dict["company"] as? [String: Any],
            let company = Company(dict: companyDict)
            else {
                return nil

        self.id = id
        self.name = name
        self.username = username
        self.email = email
        self.phone = phone
        self.website = website
        self.address = address
        self.company = company

    struct Address {
        let street: String
        let suite: String
        let city: String
        let zipcode: String
        let geo: Coordinates

        init?(dict: [String: Any]) {
                let street = dict["street"] as? String,
                let suite = dict["suite"] as? String,
                let city = dict["city"] as? String,
                let zipcode = dict["zipcode"] as? String,
                let geoDict = dict["geo"] as? [String: Any],
                let geo = Coordinates(dict: geoDict) else {
                    return nil

            self.street = street
            self.suite = suite
            self.city = city
            self.zipcode = zipcode
            self.geo = geo

        struct Coordinates {
            let lat: Double
            let lng: Double

            init?(dict: [String: Any]) {
                    let latString = dict["lat"] as? String,
                    let lat = Double(latString),
                    let lngString = dict["lng"] as? String,
                    let lng = Double(lngString) else {
                        return nil
                self.lat = lat
                self.lng = lng

    struct Company {
        let name: String
        let catchPhrase: String
        let bs: String

        init?(dict: [String: Any]) {
                let name = dict["name"] as? String,
                let catchPhrase = dict["catchPhrase"] as? String,
                let bs = dict["bs"] as? String else {
                    return nil

            self.name = name
            self.catchPhrase = catchPhrase
            self.bs = bs

if let json = try? JSONSerialization.jsonObject(with: jsonData, options: []) {
    if let jsonArray = json as? [[String: Any]] {
        let users = jsonArray.flatMap {
            User(dict: $0)

I don’t actually expect you to go through all this code in detail, but I included it here to make it obvious how verbose this method is.

The first 3 lines get the data, and I have force-unwrapped the URL and the Data which I would not do in a production app but which is OK while testing in a playground. Then there is a declaration of the Users struct with all its sub structs. Each one has a failable init that tries to parse the JSON dictionary and returns nil if the data doesn’t match, by way of a lengthy set of guard statements. The basic layout of each struct is the same but it is very verbose. And as an extra step, the lat and lng properties need to be converted from Strings to Doubles.

I have to confess that it took quite come time to get this right … lots of guard statements to check that the data can be converted to the required types which meant that any typos produced an empty array. The sub-structs have to be extracted from the JSON as Dictionaries and then initialised by themselves.

Decoding in Swift 4

So this works, and I get an array of Users objects. But it isn’t pretty and it takes a lot of code to do the processing. So now I am going to move on to doing this in Swift 4. I am using Xcode 9.0 beta 6 (9M214v) so if you have a later version, you may need to adapt to any changes.

struct User: Codable {
    let id: Int
    let name: String
    let username: String
    let email: String
    let phone: String
    let website: String
    let address: Address
    let company: Company

    struct Address: Codable {
        let street: String
        let suite: String
        let city: String
        let zipcode: String
        let geo: Coordinates

        struct Coordinates: Codable {
            let lat: String
            let lng: String

    struct Company: Codable {
        let name: String
        let catchPhrase: String
        let bs: String

let jsonDecoder = JSONDecoder()
let users = try? jsonDecoder.decode(Array<User>.self,
                                    from: jsonData)

Ignoring the complexities of converting latitude and longitude to Doubles, I get vastly simpler code. I declare all the structs as conforming to the Codable protocol and then I can remove all the init methods and just let JSONDecoder do its magic. I just have to tell it what data type to expect - in this case an Array of Users. I don’t have to worry about the initial conversion of the JSON data to a Dictionary or looping through the elements using flatMap.

In the playground, I used a do…catch structure to check the result of the decode function, but I have used try? here to keep the code short.

Changing data types

The lat & lng coordinates are stored in the JSON as Strings, but need to be converted to Doubles for the Swift struct.

This requires a custom init method for the Coordinates struct to do the conversion from String to Double.

So here is the complete code for Swift 4 - again, if you don’t want to create your own playground, you can use mine, this time looking at the Swift 4 JSON page:

import Foundation

let sampleDataAddress = "https://jsonplaceholder.typicode.com/users"
let url = URL(string: sampleDataAddress)!
let jsonData = try! Data(contentsOf: url)

struct User: Codable {
    let id: Int
    let name: String
    let username: String
    let email: String
    let phone: String
    let website: String
    let address: Address
    let company: Company

    struct Address: Codable {
        let street: String
        let suite: String
        let city: String
        let zipcode: String
        let geo: Coordinates

        struct Coordinates: Codable {
            let lat: Double
            let lng: Double

            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                let latString = try values.decode(String.self, forKey: .lat)
                let lngString = try values.decode(String.self, forKey: .lng)
                lat = Double(latString) ?? 0
                lng = Double(lngString) ?? 0

    struct Company: Codable {
        let name: String
        let catchPhrase: String
        let bs: String

let jsonDecoder = JSONDecoder()
let users = try? jsonDecoder.decode(Array<User>.self, from: jsonData)


For comparative purposes, I counted the lines of code in each, removing the common boiler plate of the top of each and the two lines for displaying the results in the playground. I also removed the blank lines which I always use a lot in my code for readability but which are not relevant when comparing code efficiency:

Version Lines Lines if lat & lng are Strings
Swift 3 95 93
Swift 4 35 28


Encoding back to JSON is very similar. In the Swift 3 version, I would have written a method for each struct that created a Dictionary and then used JSONSerialization to convert the Dictionary back to JSON. This is very verbose and tedious to write so I am not going to bother to demonstrate it here.

But in Swift 4, this is even easier than decoding. Add this code to the end of your Swift 4 JSON playground or playground page:

if let users = users {
    let jsonEncoder = JSONEncoder()
    jsonEncoder.outputFormatting = .prettyPrinted

    if let backToJson = try? jsonEncoder.encode(users) {
        if let jsonString = String(data: backToJson, encoding: .utf8) {

The JSONEncoder returns Data and I have converted that to a String for checking. I set JSONEncoder’s outputFormatting property to .prettyPrinted get a more readable String.

Notice how the encoded data is not quite the same as I received because the lat & lng properties are now Doubles. In a production app, if I needed to be able to convert back to JSON, I probably would have left them as Strings so as to enable data transfer in both directions. I would add computed properties to the struct to convert these Strings to Doubles as I needed them.

Advanced Decoding

Now that we have the basics, I want to look at three more features: changing property names, date handling and allowing for nulls.

Changing Property Names

In these examples I used exactly the same names for the properties as were used in the JSON. In the Swift 3 version, it would have been easy to change the property names, since the data for each property was being extracted manually. In Swift 4, if you want the decoder to change names, you have to tell it what you want.

Make a new playground or playground page and replace the contents with this - or go to the Swift 4 Extras page on my playground:

import Foundation

let jsonString = """
"name1": "Jane",
"name2": "Smith"
let jsonData = jsonString.data(using: .utf8)!

struct Person: Codable {
    let firstName: String
    let lastName: String

let jsonDecoder = JSONDecoder()
let person = try? jsonDecoder.decode(Person.self, from: jsonData)

This uses the new multi-line literals in Swift 4 to assemble the JSON string which is amazingly useful as it allows quotes to be embedded in the string without having to escape them. As you can see, the JSON property names are not very helpful, so I want to change them in my Person struct. At the moment, person is nil because I have not given the decoder any clues to help it translate the names. To do that, I have to add a CodingKeys enum to the Person struct and it tells the decoder what names in the JSON match up to what properties in the struct.

struct Person: Codable {
    let firstName: String
    let lastName: String

    enum CodingKeys: String, CodingKey {
        case firstName = "name1"
        case lastName = "name2"

And that’s all I have to do. Now the JSON is correctly converted to a Person. As an exercise, use JSONEncoder to get back to JSON from the Person. You will see that the JSON correctly names the elements using “name1” and “name2”.

Date Handling

Next let’s look at dates - add this code to the playground:

let jsonString2 = """
"name": "My New Project",
"created": "2017-06-18T06:28:25Z"
let jsonData2 = jsonString2.data(using: .utf8)!

struct Project: Codable {
    let name: String
    let created: Date

let jsonDecoder2 = JSONDecoder()
let project = try? jsonDecoder2.decode(Project.self, from: jsonData2)


When this runs, project is nil because the decoder has no idea how to get from the String “2017-06-18T06:28:25Z” to a Date object. Add this line after creating jsonDecoder2:

jsonDecoder2.dateDecodingStrategy = .iso8601

Now the date can be converted and an instance of the Project struct will be created.

And to get back to the JSON, converting the Date back to ISO8601 format:

let jsonEncoder = JSONEncoder()
jsonEncoder.dateEncodingStrategy = .iso8601

if let backToJson = try? jsonEncoder.encode(project) {
    if let jsonString = String(data: backToJson, encoding: .utf8) {

Allowing For Nulls

JSON data will often include null where there is no value for a particular property name. When using JSONDecoder or JSONEncoder, this can be allowed for by using Optionals. If you are not clear about Optionals, have a look at my previous article: Learning Swift - Optionals.

The crucial step is to declare the properties of the Swift object as optionals if you think they could get a null value.

struct Role: Codable {
    let firstName: String
    let lastName: String
    let nickName: String?

let jsonStringWithNulls = """
        "firstName": "Sally",
        "lastName": "Sparrow",
        "nickName": null
        "firstName": "Doctor",
        "lastName": "Who",
        "nickName": "The Doctor"
let jsonDataWithNulls = jsonStringWithNulls.data(using: .utf8)!

let jsonDecoder3 = JSONDecoder()
let roles = try? jsonDecoder3.decode(Array<Role>.self, from: jsonDataWithNulls)

In this example (which you can find in the Swift 4 Extras page on my playground), I have declared a struct called Role with 3 String properties. The 3rd String - nickName - is an Optional so it may be a String or it may be nil.

The JSON contains 2 elements - one has a nickName value and the other has it as null. Because the matching property in the Swift struct is an optional, this works as expected and the nickName property for Sally Sparrow is decoded as nil. If you remove the question mark to make nickName non-optional, the decoding will fail.

Going back to JSON from a Swift object with optionals works much the same except that it does not specifically mark items as null, it just leaves them out.

let jsonEncoder2 = JSONEncoder()
jsonEncoder2.outputFormatting = .prettyPrinted

if let backToJsonWithNulls = try? jsonEncoder2.encode(roles) {
    if let jsonString = String(data: backToJsonWithNulls, encoding: .utf8) {

Property Lists

As well as JSONDecoder and JSONEncoder, Swift 4 has introduced PropertyListDecoder and PropertyListEncoder, so let’s take a quick look at that.

Add this to the bottom of the last playground as it uses the Project struct and data:

let plistEncoder = PropertyListEncoder()
plistEncoder.outputFormat = .xml
if let plist = try? plistEncoder.encode(project) {
    if let plistString = String(data: plist, encoding: .utf8) {

    let plistDecoder = PropertyListDecoder()
    let project2 = try? plistDecoder.decode(Project.self, from: plist)


I don’t see this is being quite as useful as the JSON Encoding & Decoding, but I mention it here for completeness.


In all the Swift 4 examples above, I set the structs to conform to Codable. Reading Apple’s docs, I see that Codable is actually a typealias referring to 2 separate protocols:

typealias Codable = Decodable & Encodable

If you only need to convert data one way, it will be more efficient to set your struct or class as confirming to only one of these protocols. For example, if you download JSON data from an API but never need to send it back, just conform to Decodable to transform the JSON data into your data structure.

Much more information can be found in the Apple documentation.

Posting from my new iPad

Permalink - Posted on 2017-06-17 00:00

Last week I got a 10.5” iPad Pro. I have had an iPad ever since the original release, but I have to confess to mainly using it for content consumption rather than creation. Since I am usually close to a Mac anyway, there didn’t seem a lot of point. But now that iOS 11 is really addressing the issue of making the iPad a “pro” device, I decided to give it a try.

So here I am, sitting in an armchair with my iPad on my lap, writing this post and working out the details as I go. Any typos are due to the cat trying to compete with the iPad for space on my lap!


As already mentioned, I have a new iPad Pro. I also have an Apple Pencil which I use for taking notes. I do not have a keyboard, so I am using the on-screen keyboard right now.

I don’t usually install beta versions of operating systems, but iOS 11 is a huge part of making the iPad more professional, so I have installed it. As you would expect, there are a few issues (apps quitting, layout issues especially when rotating) but so far I am loving it.


My site is published on GitHub Pages using Jekyll with all the posts and pages written in Markdown. One key feature is that every post or page requires a chunk of “front matter” that must be formatted correctly for the Jekyll parser to interpret it and create the static content. After a bit of research, it looked like Editorial was going to be the best option for an editor app. I moved my site files to Dropbox, linked my Dropbox account to Editorial and I was ready to start writing.

I didn’t want to create the front matter manually for each post. On my Mac I have a text expander snippet that handles that but copying from Matt Gemell’s post on the topic, I created an Editorial workflow to create a new post. As a side-note, Matt has a series of posts on using an iPad which I have found very useful and inspirational.

Editorial workflow

Text entry and editing is a task that I have always felt was too difficult in iOS, particularly when it came to selecting text and moving the cursor. However there are now several improvements. As with iOS 10, a two-fingered press on the keyboard transforms it into a trackpad for moving the cursor. If you already have text selected, this moves the selection handles. The new iOS 11 keyboard has a really nice feature for entering non-alphabetic characters. The keys now show a small grey character above the main character. Drag down on the key to move the small character into the main key and type it. For example, drag down on the h key to type (.

Keyboard drag

Editorial has its own editing helpers. There is an additional toolbar above the keyboard with a tab key as well as frequently used Markdown modifiers. And swiping across this toolbar moves the cursor. This is a much slower move than when using the keyboard as a trackpad so might be better for more precise movements.

I have referenced a few sites now, so I guess it is time to work out how to link to them. I always use Markdown’s referenced link method, with the links collected at the foot of the document, so that is what I plan to do here. To set text as a link, I selected it and used the Editorial toolbar to type an opening square bracket which surrounded the selection in square brackets. Then I moved the cursor to after the closing bracket and typed another opening square bracket. This auto-closed and I was able to type a number which will be the reference.

Next step is to find the relevant URLs - drag & drop with multi-tasking to the rescue! Swipe up from the bottom of the screen to see the new Dock. This also makes the keyboard disappear. Hold down on the Safari icon until you grab it, then drag it up into the Editorial window. Now it is open as an overlay.

Safari as overlay

At this point, I have several options:

  • Swiping from the left or right of the overlay window lets me position it to the right or left of the screen, still as an overlay.
  • Dragging from the bar at the top of the overlap allows me to convert to split screen mode, and I can then drag the divider to adjust the ratios.
  • Swiping all the way to the right disappears the overlay, but swiping back from the right edge returns it. Since I want to copy and paste some links, this looks like the best option right now.

This swiping conflicts slightly with Editorial’s swiping from the side to see a preview. Swipe from off the edge for the overlap and from well inside the edge for preview.

And here my plans come crashing down. I can drag from Safari’s address bar into the Editorial document, but the drop doesn’t take. I guess I need an update to Editorial for this to work. But I can still use the old style copy and paste to get the links.


So now I have my links, but I want to insert a few images. I used iOS 11’s new screen shot abilities. Press the usual home button & power button combination to take a screen shot and it appears as a small picture in the bottom left of the screen. Tap it to start editing: markup, crop etc. Then I used the sharing button to save the picture to Dropbox, putting it inside the images folder in my web site folder.

Editing a screenshot

I want to insert an image link but I have just worked out that I saved this Markdown file in the root folder instead of the _posts folder. I can’t see a way to move it from inside Editorial, so I will swap to the Dropbox app to move the file - be right back… (I see now how I could have done this in Editorial.)

Ok, this file is in the right place and the images are in the right folder, so how to add an image link? Checking back at previous posts, I see that the format I use for inserting an image is: ![Alt text][#] and the reference at the foot of the page is like[#]: /images/image_name.jpg but I don’t want to have to remember that every time, so I think it is time for some snippets. Tapping the lightning icon on the Editorial keyboard lets me edit and create snippets, so I have made one for the image link and one for the image reference. Time to scroll back up the page and try them out.

I opened the Dropbox app in an overlay so that I could find the file names for the images I just saved, then I created the links. The images don’t appear in the preview but that is expected because Jekyll has not parsed the addresses. Looking at the information about the images in Dropbox, I see that they are far too big. I need a way to resize them. The screen shot editor doesn’t have a way to resize apart from cropping, at least not in this beta.

Workflow is another Pro level app that I have never really used, but it seems that it might do the job. I tried a few workflows to edit the size of an image from a Dropbox file and save it back, but they although they appeared to complete, the image file remained the same size. So then I went to the Workflow Gallery and found a workflow called Quick Resize Screenshot. When editing a screen shot, I can use the sharing button to run the workflow and then I can save the smaller images to Dropbox for use in the page. For the large images that I have already saved, I will resize them on my Mac before publishing.


This brings me to the final step - publishing the changes to GitHub Pages. Jekyll is a system that creates static web pages from the Markdown and other files. on my Mac, I run the jekyll build command in Terminal and the pages are created or re-generated as required. Then I use git to commit my changes and push them to GitHub which serves them.

There appear to be Editorial workflows written in Python that use the GitHub APIs to upload files, but this wouldn’t work well for me. Because of the structure of my site, many different pages need to be re-generated when I publish a new post, so I will keep the publishing phase on my Mac. However there is no need to make it any more difficult than necessary, so I have written a shell script to do the work.

The script takes an optional commit message parameter, builds the site, commits changes and pushes then to GitHub. I have only tested this when no files had changed, so this post will be the first real test. Shell scripting is outside my comfort zone, so we will have to see how that works.


So now I have a workflow on my iPad that uses Editorial, Dropbox and Workflow. This allows me to do 100% of the writing task. Then I have a single shell script on my Mac that does the publishing part. I can edit and create posts anywhere. I can easily use split screen or screen overlays to add links. iOS 11 makes creating and annotating screen shots very easy.

I am hoping for an update to Editorial that will allow it to accept drag & drop. The ability to resize screen shots before saving them would also be really useful.

Sometimes my posts are more code-based and need access to Xcode and in those cases, I will stick to my Mac, especially considering Xcode’s new ability to connect directly to GitHub which will make it great for publishing Swift playgrounds. But for more narrative-style posts like this one, I will use my iPad and see how I can improve my workflow and expand my tool set.

It feels good to be using the iPad as a content creation device at last.

Extra Notes from a Mac:

Since this was my first time writing a blog post using an iPad and this workflow, I decided that I should test the results before publishing, so I switched back to the Mac and in Terminal, ran jekyll serve so that I could see the results. There were a few issues mainly to do with the formatting of the front matter. The three dashes at the top & bottom of the front matter had become munged into an emdash plus a dash, so that didn’t work. Jekyll is also fussy about the spaces in the tag & summary lines and it doesn’t handle non-alphanumerics in the summary text.

I also used the Mac to shrink some of the images that I had saved before working out how to reduce the size of screen shots.

So I need to check the structure of the front matter workflow before next time, but this post is ready to go with only minor editing on the Mac side. Now to test my shell script…

JSON Feed for TrozWare

Permalink - Posted on 2017-05-20 00:00

jsonfeed.org has announced a new format for web site feeds, designed as an alternative to RSS. TrozWare has had an XML RSS feed for years, but I don’t think anyone ever uses it (I certainly don’t), so today I have replaced it with a JSON feed, which you can access through the button at the top of every page.

I am sure many JSON Feed viewers will appear soon, but the only one I know about so far is at http://json-feed-viewer.herokuapp.com. As soon as this update to my site goes live, I will apply to have TrozWare added to the list of sites on this page. Meanwhile, you can paste in the URL: https://troz.net/feed.json.

This site is constructed using Jekyll, so I am very grateful to Niclas Darville for his very easy to follow guide. However it is still well worth reading through the official specs to see what else you want to add, or if you want to remove anything. I had to tweak a few settings to make it work for my configuration, and I added some more objects, but Niclas got me off to a flying start.

Two things to watch out for:

  1. Make sure your feed is producing valid JSON (I had an extra comma that was breaking it…).
  2. As third-party apps & sites may be displaying your content, you need to make sure that you are not using relative URLs for images and internal links. I was using relative image URLs like /images/WorkHelp1.png but that showed a broken link in the feed viewer, so I have changed all such links to /images/WorkHelp1.png. Hopefully that will work correctly on my local test server as well as when published.

JSON Feed icon

JSON Feed offers a nice icon which I would have liked to use, but I could not work out a way to make it play nicely with the existing icons on my pages which all use Font Awesome icons. So I ended up just using the existing Feed icon. Hopefully Font Awesome will soon add a JSON Feed icon to their already impressive list.

If anyone still wants to use the RSS feed, it is no longer linked to the buttons at the top of the pages, but you can access it manually.

Blackmail Marketing

Permalink - Posted on 2017-03-08 00:00

I use my iPad to play games as a form of relaxation. Nearly all the games I play are puzzle apps with levels that can be played in a few minutes. Nearly all of them are free to install. So how do they make money?

Now I would be the last person you should consult about marketing but it has always seemed to me that the best way to market your product is to convince people that it offers something they want so that they are prepared to pay for it.

This is not the currently favored approach for mobile apps - at least certainly not for games. No, the theory at the moment is to cause so much frustration and annoyance that people give you money to make it stop. Blackmail marketing.

A frequently used method is showing ads, sometimes just banner ads but more often full screen video ads that run for up to 30 seconds. If you interrupt the ad, you don’t get the reward.

  • Every goal reached triggers an ad.
  • Quitting and resuming the app triggers an ad.
  • Wanting to play another level triggers an ad.

The theory is that you get so annoyed with this that you pay money to disable the ads.

The other common tactic is the delay. A tower defence game needs you to build a tower? OK, that will take 12 hours real time and you can’t proceed until it’s finished. Or you can spend 12 gems which are sold as an in-app purchase. Maybe you can only play 3 levels and then you need to recharge: again, pay up or wait. You keep dying on that level? You’re out of lives. Pay up or wait until tomorrow. These delays are completely artificial. They have nothing to do with game play but are solely designed to infuriate you enough to get you to pay.

So when, and perhaps more importantly why, did mobile app marketing become so negative? What happened to making your customers happy? Do unhappy customers spend more?

Financially, it appears that irritating your users is a successful strategy. Nearly all the top grossing games in the App Store are “free to play” in that the initial download costs nothing. But these big studios are raking in enormous sums of money, so many people are persuaded to spend significant money by these infuriating schemes.

A large part of this must be due to the various App Stores driving prices to the bottom. Gone are the days when the price of a mobile app was other than risible. So app developers have four choices:

  1. Do it as a hobby or learning exercise.
  2. Distribute apps as a form of self–promotion for other work.
  3. Work for someone who pays you a real wage to develop apps.
  4. Join the blackmailers.

So how does this relate to indy developers like me? I care about my users and want them to be happy.

I have tried several different approaches to app distribution:

  • Totally free gets by far the most downloads but is economically ridiculous unless the app adds value to your business in some other way.

  • A tip jar gets you nothing.

  • In-app purchases (in my limited experience) make less than selling the app up-front for a small price.

  • Banner ads with no method of forcing people to watch them generate almost no revenue.

So that leaves me with where I am today - selling apps for a few dollars and nothing more. Happily, I have found that Mac users are more prepared to pay a few dollars for an app, so I have shut down many of my iOS apps and am concentrating on the Mac app market.

Am I letting my principles stand in the way of mobile app profits? Should I just join the gang and start blackmailing my customers? If so, what form should this take?

At the moment, I am considering banner ads on the screen with an in-app purchase to disable them entirely. I read a suggestion for a less invasive method of doing this by creating your own ads for your other apps. This might be what I end up doing.

I would welcome any suggestions, advice or comments. Please join the discussion below or contact me using one of the links at the top of the page.

NCSS 2017

Permalink - Posted on 2017-01-06 00:00

I gave a Masterclass on Swift at the NCSS Summer School 2017 in Sydney on 8th January 2017. This post contains useful links for use during and after my class.

Sandbox Code Samples

Contact Details:

Looking for beta testers

Permalink - Posted on 2016-11-17 00:00

I am looking for beta testers for my latest Mac app: Work.

Work is a project organizer app for developers, designers, students or any professional who works with multiple projects involving files & folders, web pages, email addresses and lists of tasks. Click the link above for more information and help for getting started.

Work requires macOS 10.12 or OS X 10.11.

If you would like to test this app, please contact me, giving details of your Mac and operating system. The easiest way to do this is to select About This Mac in the Apple menu and send me a screen shot of the window that appears.

All beta testers will receive a free license to Work when it is released. If you report a legitimate bug or provide valuable feed-back, you will also receive a free license to your choice of one of my other apps.

Another Man Reader Update...

Permalink - Posted on 2016-11-05 00:00

A quick update to Man Reader to version 1.8 is now available through the Mac App Store.

The main reason for this version was that Man Reader was not previously detecting man pages installed by third-party IDEs in the Applications folder. There was also an issue with Man Reader failing to display the text of the previously selected man page on app launch.

  • More complete search for man pages, including in third-party IDEs.
  • Fix for glitch when displaying previously selected page on launch.

Man Reader Update

Permalink - Posted on 2016-10-12 00:00

Man Reader has just been updated to version 1.7 and is available through the Mac App Store.

The main reason for this update was to make the app work well with macOS Sierra, as I found that version 1.6 was sometimes crashing on launch. While doing this, the update was rejected by the App Store reviewers because it crashed on OS X 10.10. Since I no longer have a Mac running 10.10, I decided to set the minimum supported system version to OS X 10.11. If you need support for older versions, you should still be able to download version 1.6 which will work back to 10.7.

I also took the opportunity to fix some graphical issues, dealing with different color schemes:

  • The man page list now shows alternating colors even when not using the default scheme.
  • When scrolling the man pages past the top or the bottom with a non-white background, you should no longer see white blocks top & bottom.


Permalink - Posted on 2016-10-11 00:00

I have recently started what I hope will be a weekly podcast with my friend and colleague, Jerry Daniels. Each podcast will be about 30 minutes in length.

We will discuss Macs, iPhones, iPads, macOS, iOS, programming and anything tech-related that we find interesting. I hope you will find it entertaining and informative, so please join us.

We are using ZCast which has an iPhone app that makes it super easy to get together and record our chats. It doesn’t allow any post-processing, but really lowers the barrier to entry into the world of podcasting.

If you get the ZCast app for iPhone, go to the ZCasters tab and search for “Trozware” or “Jerry Daniels” to find all our podcasts. Or use these links to listen in your browser.

Since the first one was recorded using my name instead of my @trozware Twitter account, I will embed it here as it will not show up if you search for “Trozware”.

Dice Pass Updated

Permalink - Posted on 2016-09-17 00:00

Dice Pass 1.1 is now available from the Mac App Store.

What does Dice Pass do?

Dice Pass is a utility to app to generate random passphrases based on the Diceware system. Diceware uses a table of pre-defined words, each assigned a 5 digit code number containing the digits 1 to 6. The official way to generate a phrase is to roll 5 dice for each word you want in your passphrase and then consult the words table to find the matching word.

The resulting phrase uses real words or common abbreviations so it is easier to remember than a random collection of characters. At the same time, the random selection of words makes the generated passphrase much more secure as it avoids the human tendency to pick words with personal meaning.

Dice Pass allows you to select the number of words in your passphrase, re-generate the entire passphrase any time, re-roll a single word in your passphrase or set the dice rolls manually for maximum security and randomness.

What’s New in Version 1.1:

You can now select from three word lists in the Word Lists menu:

  • original Diceware list
  • Beale list (fewer Americanisms and obscure words)
  • Diceware 8k list (a list of words that is a whole power of two in length)

You can also import your own word list if you prefer.

Dice Pass 1.1 is compatible with macOS Sierra.

How much work does Icon Builder save you?

Permalink - Posted on 2016-09-17 00:00

Icon Builder is a Mac app that takes a single image file and creates all the different image sizes that you need to make a set of icons for your app: Mac, iPhone, iPad, iOS Universal or Apple Watch.

Version 4, released 16 September 2016 is available through the Mac App Store.

What’s New in Version 4:

  • Added support for iMessage apps and Sticker Pack apps.
  • Added support for creating Mac .icns files.
  • Better removal of alpha channel for Apple Watch icons.
  • Clearer usage instructions in ReadMe files.
  • iTunes Artwork folders will no longer be over-written with the latest image files.
  • Supports macOS Sierra and Xcode 8

Icon Builder

While working on version 4 and accommodating all these new icon sets (and wishing I had the time to re-write the app in Swift…), I counted up all the icon files that Icon Builder makes for each app type:

App Type Number of Icons
Mac 10
iPhone 8
iPhone supporting pre iOS 7 11
iPad 9
iPad supporting pre iOS 7 13
iOS Universal 14
iOS Universal supporting pre iOS 7 20
Apple Watch (also requires iOS app icons) 8
Sticker Pack app 11
iMessages app 14
iMessages app Messages extension 9

So as you can see, Icon Builder is doing a lot of work for you. It also names all the icon files using the expected format, stores them in an concept folder, creates the JSON file that identifies them all to Xcode and optionally installs them in your Xcode project automatically. That’s a lot of value for dragging in an icon and clicking a button!

So next time your designer sends you the twentieth tweaked icon for the day, don’t get mad. Just drop it into Icon Builder and sit back while it does all the work. (No need to tell the designer that…)

Retiring old apps

Permalink - Posted on 2016-09-15 00:00

With the release of iOS 10 and the need to update iOS apps to suit, I have decided it is time to retire some of my lesser-performing apps as it is not worth the effort required to maintain them.

At the moment, the following iOS apps are no longer available:

  • A Knight’s Move
  • Dice Pass
  • Pic-a-POD
  • Quick Score - Tennis

For the first three listed there, the Mac versions are still available:

If you bought any of these apps and would like a promo code for the Mac version, send me a screen shot of the app running on your iPhone or iPad and I will send you a code.

Man Reader updated to 1.6

Permalink - Posted on 2016-07-16 00:00

Man Reader has been updated to version 1.6 with the permissions needed for finding all available man pages and a fix for search terms being over-written after a background update.

Man Reader 1.6 is now available through the Mac App Store.

Change Log:

  • Permissions fix when searching for available man pages.
  • Fixed error with new search term being over-written.
  • Sand-boxed version now works just as well as the non-sand-boxed so please switch back to this version.

This version fixes a problem with sand-boxing permissions potentially not allowing access to all the installed man pages on your system. This should now be fixed but if you discover any man pages that are available through Terminal but not through Man Read, please email me the details and help me make Man Reader better.

There was also an issue with a previous search being restored after a background update, even if a new search term had been entered. This has been fixed.

If you previously had downloaded the Man Reader (no SB) version of the app from this site, please revert to the App Store version which you would have needed to have bought in order to use the downloaded app. If you bought the app from Paddle, contact me and I will transfer you to the App Store version. Neither of these other versions will be supported or updated any more.

Dice Pass Mac Update

Permalink - Posted on 2016-07-03 00:00

I recently got an email from someone who had purchased Dice Pass for Mac from the Mac App Store but had been unable to get it to run. This person was using OS X 10.9.3.

I checked the App Store specifications and it showed that 10.9 was the minimum system requirement, so it should have worked. But going back to my Xcode project, I found that it was set to a minimum of OS X 10.10.

I tried to re-compile for OS X 10.9 but this failed as the app uses several features that are not available prior to 10.10.

The minimum system version as displayed in the App Store is supposedly deduced automatically by the App Store servers from the app’s binary. Somehow this was incorrect in the App Store, so some people may have bought that app and found that it did not work despite them having what was listed as a compatible system.

If you bought Dice Pass for OS X 10.9 and are unable to run it, I have two possible solutions for you:

  1. Upgrade your operating system to at least 10.10.
  2. Ask Apple for a refund since it was their error that caused you to buy an app that you cannot run.

I have updated the app in the App Store changing nothing but the version number and it is now showing the correct minimum system requirement. My apologies if you have been inconvenienced by this error.

Learning Swift - Sets

Permalink - Posted on 2016-05-28 00:00

Sets are the forgotten collection type in many languages, including Swift. I think most developers use Arrays without really considering the advantages of using a Set but they have some amazingly useful features that should make them a part of any progammer’s toolkit.

If you want to follow along with a playground, you can download it here.

What is a Set?

A Set is an un-ordered collection of unique items. That’s it - nothing more than that. So it is very similar to an Array, but it is not indexed like an Array and it cannot contain more than one of each entry.

Creating a Set

Creating a Set is as easy as creating an Array:

var myArray = ["dog", "cat", "hamster", "dog"]
var mySet: Set = ["dog", "cat", "hamster", "dog"]

If you are running these commands in a playground, notice that the differences between the 2 results:

["dog", "cat", "hamster", "dog"]    // myArray
{"hamster", "cat", "dog"}           // mySet
  1. The Array is shown wrapped in square brackets, the Set is shown wrapped in curly braces. This is just a visual clue and doesn’t really mean anything. You cannot initialize a set using curly braces.
  2. All the supplied elements of the Array are listed, but the Set has removed the duplicate “dog” element. This did not cause an error or warning, it just happened quietly.

When initializing a Set, you must add : Set to distinguish it from an array initialization. In the example above, I did not specify the data type of the elements in the Set as the Swift compiler was able to infer this from the contents. But if initializing an empty array, the data type must be specified. To check how to do this, I option-clicked on mySet to see what the Swift compiler thought it was.


So mySet is actually Set<String>. This means that to create an empty Set, you need to use something like this:

var emptySetOfStrings: Set<String> = [] var
emptySetOfInts: Set<Int> = []

Adding and removing elements

If you have been using an Array to store unique values, then you have probably written code like this:

if !myArray.contains("cat") {

With Sets, you don’t have to care. Just use insert() and let the Set work out whether to add the item or not.

// goldfish added: {"hamster", "cat", "dog", "goldfish"}
// dog already there: {"hamster", "cat", "dog", "goldfish"}

Removing elements is also easier than in Arrays. For an Array, you first have to find the index of the element and remove it by index:

// myArray.remove("hamster") // will not compile
if let index = myArray.index(of: "hamster") {
  myArray.remove(at: index)

But in a Set, you can remove any element easily and trying to remove an element that doesn’t exist will fail without an error.

mySet.remove("hamster")   // returns "hamster"
mySet.remove("canary")    // returns nil

Converting between Sets and Arrays

Sometimes you need to be able to switch between the two. My most recent example was when I wanted to store data from a Set in a plist. Sets are not property list types but Arrays are, so I converted the Set to an Array before storing it in the plist. When reading the data in from the plist, I converted it back to a Set.

let myArrayAsSet = Set(myArray)
let mySetAsArray = Array(mySet)

One useful side-effect of these easy conversions is the ability to ‘unique’ an Array in a single line. This may be inefficient for large arrays, but works very well for small ones. Just be careful if the order of the elements is important as you cannot guarantee the order of elements in a Set.

let myArrayUniqued = Array(Set(myArray))
// ["cat", "dog"]

Iterating over elements in a Set

As with an Array, you can use a for element in set structure, or you can use enumerated(). But you cannot subscript a Set.

for animal in mySet {

for (index, animal) in mySet.enumerated() {
  print("\(index) = \(animal)")

// will not compile
// for index in 0 ..< mySet.count {
//   print("\(index) = \(mySet[index])")
// }

Where Sets get really interesting

Remember in school when you learnt about Venn diagrams with pretty interlocking circles? Sets can do the same things, although you will have to do your own pretty drawings :-)

let set1: Set = ["dog", "cat", "pig"]
let set2: Set = ["cow", "horse", "pig"]

let intersect = set1.intersection(set2)
// {"pig"}

let subtract = set1.subtracting(set2)
// {"cat", "dog"}

let union = set1.union(set2)
// {"pig", "cat", "dog", "cow" "horse"}

let xor = set1.symmetricDifference(set2)
// {"cat", "dog", "cow", "horse"}

In the code example above, we have two Sets of animals, with one animal in common.

  • intersection() lists the elements in common.
  • subtracting() lists the elements in one Set after removing all elements that are in the other.
  • union() joins all the elements without duplicates.
  • symmetricDifference() lists the elements that are in one or other of the Sets but not in both. (Swift 3 renamed this function from exclusiveOr())

Here is my best attempt at a pretty drawing to show how these go together:


The next fun trick is working out sub-sets, super-sets and disjoint sets.

let set1: Set = ["dog", "cat", "pig"]
let set2: Set = ["cow", "horse", "pig"]

let smallSet: Set = ["pig", "cow"]

smallSet.isSubset(of: set1)   // false
smallSet.isSubset(of: set2)   // true

smallSet is not a subset of set1 because it contains an element that is not in set1. smallSet is a subset of set2 because every element in smallSet is also in set2.


If you want to get technical, a Set should not be considered a subset of an identical Set. The default isSubset(of:) allows this, but you can use isStrictSubset(of:) if you prefer.

set1.isSubset(of: set1)         // true
set1.isStrictSubset(of: set1)   // false

Superset works just the same but in reverse so the diagram above explains it too:

let set1: Set = ["dog", "cat", "pig"]
let set2: Set = ["cow", "horse", "pig"]

let smallSet: Set = ["pig", "cow"]

set1.isSuperset(of: smallSet)       // false
set2.isSuperset(of: smallSet)       // true

set1.isSuperset(of: set1)           // true
set1.isStrictSuperset(of: set1)     // false

set1 is not a superset of smallSet because it does not contain every element in smallSet. set2 is a superset of smallSet because every element in smallSet is also in set2.

The isSuperset(of:) and isStrictSuperset(of:) functions allow or reject identical sets.

The final comparison tool that might be useful is isDisjoint(with:) which returns true only if the two Sets have no elements in common i.e. if there is no overlap in the circles.

let set1: Set = ["dog", "cat", "pig"]
let set2: Set = ["cow", "horse", "pig"]

let otherSet: Set = ["duck", "chicken"]

set1.isDisjoint(with: set2)       // false
set1.isDisjoint(with: otherSet)   // true

“pig” occurs in both set1 and set2 so they are not disjoint. otherSet and set1 have no matching entries so they are disjoint.

When should you use a Set?

  1. If you want the elements to be unique.
  2. If you want easy methods of comparing the contents of different collections.
  3. If you want to be able to remove elements easily.

When should you not use a Set?

  1. If you need the collection to be able to hold multiples of an element.
  2. If the order of the collection is important.

For more details on Sets, check out SwiftDoc.org.

19th Hole Golf Scorer 3.1

Permalink - Posted on 2016-05-07 00:00

One of the problems with using 19th Hole on the Apple Watch is making the app show every time you raise your wrist. My solution to this was to go into Settings (either on my iPhone through the Watch app, or directly on the watch) and change it to “Resume Last Activity” on wrist raise. This worked fine but as I usually prefer the watch face to show on wrist raise, I had to keep setting and re-setting this which was a pain.

But last week I noticed the fine print when changing this setting. In this screen shot from the Watch app on my iPhone, you can see that “session-based apps” and “some third-party workout apps” will over-ride the “Show Watch Face” setting.

Wrist raise settings

I started to research this and found that if an app starts a “workout session”, then it will become the active app until the session is ended or some other app starts a session. So I got to work and added a workout session to the 19th Hole’s Apple Watch app.

When you start scoring a round on the Apple Watch, you will see this dialog asking if you would like to start a workout:

Start workout dialog

The workout will be stopped automatically when you have scored the last hole. You can also use a force-press on the scoring screen to turn the workout off or on at any time.

Stop workout

This should make the app much more usable as an Apple Watch app, so happy golfing :-)

My Year With Apple Watch

Permalink - Posted on 2016-04-28 00:00

As the Apple Watch hits its first birthday, there seems to be in increasing number of bloggers complaining about it. One (which I refuse to link to) titled “My Year of Hell With the Apple Watch”. I think the article has since been re-published with a slightly less inflammatory title, but really! Did somebody rivet the watch to his wrist? If it was so awful, why not just stop using it?

I am a watch nerd and have always loved watches and having one on me. I liked watches with features and even had a calculator watch at one point although as a woman with skinny wrists, I found it constantly annoying that watch makers put all the gadgets into man-sized watches so I was left with the choice of no features or a watch that looked stupidly large on my wrist.

A few years ago I stopped wearing a watch. I can’t remember now why I did it - maybe my watch strap broke and it wasn’t important enough to get a new one. I always had my iPhone to give me the time.

But I ordered three Apple Watches as soon as they were available and myself, husband and eldest son have been using them ever since.

Here are what I consider to be the best features of the Apple Watch:

  • Accuracy: It is a fantastically accurate time-piece. Not enough people give this credit, but we have always been used to clocks and watches that were inherently inaccurate. Having a device on my wrist that I know to be perfectly accurate is an amazing thing.

  • Notifications: this takes a bit of work to get right and with every new app, you need to assess whether to have its notifications appear on your wrist. But the wonderful thing is knowing that you haven’t missed anything and being able to glance at your wrist when a notification arrives and tell - unobtrusively - whether this is something that needs immediate attention. And the ability to respond instantly to messages and emails with just a couple of taps is amazingly useful.

  • Customisable watch faces: depending on what I am doing, I need quick access to different pieces of information. When travelling, I can set up a watch face with multiple time zones. When working, I need a timer. When on holiday, I prefer one of the more relaxing but less detailed watch faces.

  • Activity: I am not the world’s most active person so I find the three rings to be a really good motivator. In fact I just had to stop typing and run up & down the stairs to get another notch to the blue ring. The goals are not out of my reach, so I like trying to fill in the rings every day.

  • Voice commands: being able to send a text message completely by voice when driving or when my hands are busy is fantastic. Starting a timer, doing unit conversions and navigating are things I do frequently by voice.

  • Excellent battery life: I started off having the battery life complication always visible, but it very quickly became apparent that this was unnecessary. Right now I have been wearing the watch for about 11 hours and the battery is at 74%. And charging is so fast that if I did run it down, a 30 minute charge would get me through most of a day.

  • The Milanese Loop: best watch band ever.

There are other good features, but I think those are my favourites.

So what don’t I like?

  • Third-party apps are still a problem. I know. I have published three myself and sometimes they just doesn’t happen. However this appears to vary a lot. Some people say they can never get apps to run, even Apple’s apps. Others say they work but with a long delay. My watch seems to be better than the average but it is still an issue.

  • Sketches don’t always get through or can take ages. We thought it would be a lot of fun to send each other little sketches and so it is, despite our total lack of any artistic skills. But it loses a bit of impact when you have to send a message 20 minutes later asking if the sketch has arrived.

  • The exercise tracking seems to be a bit erratic. If my husband and I go for a walk together, he comes back with 25 minutes of exercise and I only have 7 minutes. Am I not going fast enough? Are my arms not swinging enough? If it is very hot and my wrist gets sweaty, I seem to get better numbers - is this because my heart is beating faster or the capillaries closer to the surface have expanded? Or is the watch picking up a better signal that way? Either way, I still like the activity circles, but the green ring frustrates me a bit.

And what would I like to see in Watch 2 / watchOS 3?

  • Some sort of always-on display of the time.

  • A speaker to allow Siri to talk back to me and to play audio.

  • FaceTime audio calls.

  • Better support for third-party apps - perhaps open up some private APIs?

  • Allow developers to create watch faces or apps that told the time.

  • Allow developers to say that an app should stay as the frontmost app once opened.

Will I buy Watch 2?

At this stage I would say no. We bought the bottom-of-the-line Sport models because with version 1.0 of anything, you don’t want to spend so much that upgrading is ruled out. However these watches are still going great and a lot of the improvements I am looking for will be in software not hardware.

But 14 months ago, I was waiting for Apple to announce the iWatch as we all thought it would be called, and saying that I didn’t think I would get one. The feature list convinced me and I have been delighted with it. So if Watch 2 comes up with some killer feature that matters to me, then I might have to re-consider…

How To Confuse TestFlight

Permalink - Posted on 2016-04-24 00:00

I ran into an unusual problem when testing my latest app: “What Is My Speed?”. It is now available from the iTunes App Store, but getting there was a struggle.


Xcode is terrible at renaming projects, so it is a really good idea to have worked out your app’s name before starting. I would even recommend creating an app ID in your Apple Developer account and registering the app name in iTunes Connect. Only once you get to iTunes Connect will the name be checked for uniqueness. Searching the App Stores is not enough as it does not cover un-released apps or apps that are not available in your country.

So I set up my app. I was hoping for “What’s My Speed?” but was happy with “What Is My Speed?”.

Next step was to create the project in Xcode which I did using the app name and manually entering the bundle identifier that I had registered at Apple Developer. Xcode accepted the name without any warnings and created the default targets using that name.

In the default unit testing file, the module was defined like this:

 @testable import What*Is_My_Speed* 

which made me think that Xcode was quite happy to have parsed the app name as required to replace any unwanted characters to suit.

The app was built, passed all unit tests, profiled, analyzed, tested on real devices as well as the simulators and uploaded to TestFlight.


This app cannot be installed


(I forgot to take a screenshot but found a similar one online. Thanks Simple Techs)

I have had experience with TestFlight’s oddities in the past, so I incremented the build number and tried again, thinking that maybe there had been a processing issue. Same result.

This started a very frustrating 24 hours as I ran through all the possibilities I could think of or find suggested on the net. Due to disastrous Australian internet speeds, especially uploads, each attempt took from 40 - 120 minutes. About 5 minutes to implement the next idea, 25 minutes upload time, then the rest waiting for Apple to process the app so I could try again.

Here is what I tried:

  1. Uploaded a fresh build.
  2. Removed Bitcode.
  3. Fixed the code signing identity which was set to iOS Developer for some reason.
  4. Manually specified the provisioning profiles for all three components (iPhone app, WatchKit app, WatchKit Extension).
  5. Manually selected the code signing identity for the provisioning profiles.
  6. Uploaded using Application Loader instead of Xcode.
  7. Removed third-party framework.
  8. Removed WatchKit app.
  9. Revoked my distribution profile, re-created it and updated all provisioning profiles.
  10. Created a completely blank project with same app name and bundle identifier.

As you can see from this list, I thought it was a code signing or profile error. Using Apple Configurator 2 (the modern version of iPhone Configuration Utility), I was able to get the logs from my iPhone and entries like the following seemed to confirm this:

installd.staging/temp.2LWJ2h/extracted/Payload/What Is My Speed?.app : 0xe8008017 (A signed resource has been added, modified, or deleted.)}```

But when I got to the stage of a completely blank app still failing, I suddenly thought of the question mark. With the benefit of my preamble to this post, you all probably got there long before I did, but I got there in the end.

The solution was to remove the question mark from the names of the targets in Xcode. I had to fix up the module names in my unit testing files, but apart from that, there were no changes. After this I was able to upload the complete app to TestFlight and install it on my iPhone.

It is possible that it was the Product Names that were the issue, rather than the target name as in Build Settings, Product Name is set to be $(TARGET_NAME) by default but I didn’t test that. Maybe next time…

TL;DR Do not put any unusual characters in your target names. Alphanumerics and spaces are OK, but I am not sure about anything else.

What Is My Speed?

Permalink - Posted on 2016-04-17 00:00

“What Is My Speed?” is available now from the iTunes App Store for iPhone and Apple Watch.

What Is My Speed? - iPhone

If you read my recent blog post on Road Trip Apps you will have realised that I was working on an app to fill a gap that I discovered in our road trip app arsenal. So here it is: “What Is My Speed?” for iPhone.

Track your speed on your iPhone while driving, bicycling, running or walking. See your course and altitude at all times.

Optionally set a speed limit and get audible warnings on your iPhone when you exceed it. Reduce the speed limit to zero or extend it over the maximum to turn off speed limit warnings.

Designed for easy viewing in all light conditions and with very accessible swiping to change the speed limit quickly and easily.

If you want more detailed information, tap the info button to see a complete list of available data about your current location. Altitude and floor data may not always be available but will be displayed whenever possible.

What Is My Speed? details - iPhone

Your current iPhone settings are used to set the default units for speed and altitude, but these are easily changed after tapping the info button.

To adjust the speed limit, swipe from side to side. The speed limit indicator will expand for easier viewing and the speed limit will increase or decrease. Tap again to shrink the speed limit indicator or leave it for a few seconds and it will shrink automatically.

Tap the “?” button on the main screen to be reminded of the available swipes.

What Is My Speed? adjust speed limit - iPhone

Location permissions: On startup, the app will request permission to access your location. This is how the speed, course and altitude data is gathered so is essential for the app to operate. Your location will only ever be tracked when the app is the current foreground app.

Road Trip Apps

Permalink - Posted on 2016-04-07 00:00

Over the past few months, we have done two long road trips: one approximately 4,000 km and the other about 1,800 km. These gave us the chance to try out various apps for navigation and travel information. We live in Queensland, Australia and some of these comments may be country-specific.

The basic navigation came down to three apps:

Each has their strengths and weaknesses:

  • Apple Maps is by far the most beautiful and easy to read. It integrates perfectly with Contacts (as you would expect). Turn-by-turn directions were mostly excellent. The biggest downside is that it does not allow you to specify a route avoiding tolls.

  • Google Maps allows you to plot a route avoiding tolls… if you can find the setting. Its traffic reporting is by far the best and it would offer suggested changes of routes during the trip to get around traffic. The interface is confusing at times. Turn-by-turn directions were good, although I would have preferred an Australian voice option.

  • Metroview has all the maps downloaded which saves on data connection costs and handles bad connectivity areas better. Its best feature is notification of speed limits and alerts if you go over the limit, although it gets confused when on over or under-passes. Another very useful feature is the display of lanes when approaching highway exits, so you could tell which lane to be in. Apparently the voice guidance is now more natural but we didn’t try this. The display is messy and cluttered compared to the others.

We ended up with the following sequence:

  1. Apple Maps for the bulk of the trip.
  2. Google Maps & Metroview (on 2 separate iPhones) in the metropolitan areas and when about to take a highway exit.

Even then it was amusing to see the apps panic when you took a new road and the apps assumed you had left the road and were heading through the bush! And at one point there was a large and official sign saying “Ignore GPS - do not take this turn” and sure enough, both Apple Maps and Google Maps wanted us to turn down a little country lane instead of keeping to the highway.

Speed Display:

Apart from the basic navigation apps, we tried a couple of speed display apps. There are a lot of HUD speed apps out there that project the data on the the windscreen but they had two problems:

  • They only worked when it was dark. As soon as the sun got up, they became invisible.
  • They required you to place your iPhone flat on the dashboard so even if they had worked during the day, the iPhone would have got far too hot and shut-down. (We have a mount that holds our iPhones in front of the air vents to avoid this over-heating problem. Any mount that sticks to the windscreen itself leaves the iPhone too exposed to the sun.)

One we stuck with (in non-HUD mode) was Speedometer + HUD. This had a clear display with a few flaws:

  • When moving from 99 kph to 100 kph, the display was not re-arranged for 3 digits. Moving from 101 down to 100 fixed it, but as 100 kph is the standard speed limit, this was a frequent annoyance.
  • Adjusting the speed limit was too fiddly and difficult even for the passenger. It would have been impossible for the driver.
  • It only works in landscape mode which does not always suit the car mounts - we ended up perching the 2nd iPhone on the unused ashtray.

We also tried Talking HUD but didn’t like it. It worked solely in HUD mode, so was only useful at night or very early morning. It had voice prompts to tell you when to change gear but in an automatic car, they were just a distraction and it was not obvious how to turn them off.

But overall, we found having a speed display app as well as a navigation app to be the best combination. The audible alerts when you went over speed were very useful when over-taking or getting up to speed as you could get the information without having to take your eyes off the road.

Future App Plans:

Having determined that a speed display app is really useful, but not finding one that suited us perfectly, the obvious next step was to design my own. I wanted it to have the following features:

  • clean display, visible in all light conditions
  • easily settable speed limit
  • audible and visual over-speed warnings
  • no HUD mode
  • Apple Watch component for when you only had a single iPhone and it was navigating but you still wanted a speed display

So watch this space for further news of my up-coming app…


What Is My Speed?” is available now from the iTunes App Store for iPhone and Apple Watch.

Structs vs Classes

Permalink - Posted on 2016-03-30 00:00

One of the big debates among Swift developers is when to use structs and when to use classes.

Classes are the building blocks of object-oriented programming but structs as provided by Swift are newly powerful. Structs have been around in C-based languages for a long time, but Swift has made them more powerful and given them more features so that they are almost indistinguishable from classes. So what are the differences and which one should you use?

Where they are the same?

  • both can define initializers
  • both can define properties
  • both can define methods
  • both can conform to protocols

Where they are different?

  • classes can inherit from other classes
  • structs cannot inherit from other structs
  • classes are reference types
  • structs are value types

The reference type vs value type difference is where things really get interesting. Have a look at this example of a class with a single property:

class PersonClass {
    var name: String

    init(name: String) {
        self.name = name

var personA = PersonClass(name: "Woody")
personA.name // Woody

var personB = personA
personB.name = "Buzz"
personB.name // Buzz

That looks like standard stuff, but what do you think personA’s name is now? If you guessed “Buzz” then you win a prize! (No, not a real prize - pat yourself on the back.)

This is because when we created the personB variable and assigned personA to it, we did not assign the VALUE of personA, we assigned a REFERENCE to personA - actually the address in memory of personA rather than the data inside.

So now we have two objects and they are both looking at the same spot in memory for their data. This means that changing the name of personB changed the name of personA as well.

Let’s try the same thing with a struct:

struct PersonStruct {
  var name: String

var personC = PersonStruct(name: "Rex")
personC.name // Rex

var personD = personC
personD.name = "Hamm"
personD.name // Hamm

personC.name // Rex

This time, because we are using a struct, when we assign personC to the new personD variable, we are actually making a copy of personC and setting the values of personD to this new copy. So now we can change personD without messing with personC.

Note that I did not have a define an init for the struct because it creates one automatically. You can still add one yourself if you want to do anything different, but you do not have to.

At first glance, you may think that you should now use structs all the time to avoid these unintended consequences, but it isn’t quite as simple as that. Sometimes a class is still the best thing to use.

The inheritance capabilities of classes can make your decision simple: if you need to create a button and want to start by sub-classing UIButton or NSButton, then your button must be a class, not a struct. This will apply to most user interface objects.

Apple really wants us to use structs and in the Swift standard libraries, a very high percentage of the objects are structs. But structs are especially well suited to a certain subset of objects.

The best explanation that I have found of when to use a struct is the Jeff Trick. Reduced down, the rule is:

If you can overload == to compare two instances of your object, use a struct. If this doesn’t make sense, use a class.

So use structs for your things: Person, Shape, Brick, Cat. Use classes for everything else.

I would add one caveat: don’t fight the compiler. If using a struct is giving lots of errors and warnings, change to a class.

A logical consequence of this is that all structs should conform to the Equatable protocol.

Extending PersonStruct to make it conform just requires a single function:

extension PersonStruct: Equatable {
  static func == (lhs: PersonStruct, rhs: PersonStruct) -> Bool {
    return lhs.name == rhs.name

Since this struct only has one property, we can say that two instances of this struct are equal if the names are equal.

Testing this, we can see:

var personC = PersonStruct(name: "Rex")
var personD = personC
personD.name = "Hamm"

personC == personD // false

let personE = PersonStruct(name: "Rex")
personC == personE // true
personC != personE // false

Conveniently, providing an == function effectively gives us a != function for free as you can see from the last example.

There is one final point I would like to make about struct and that concerns mutating functions. Look at what happens if we include a function that changes the name property in the struct:

Mutating error

Fix-it is very helpfully pointing out that the method needs to be marked as mutating for this to work and is showing where this should go. Accepting the suggestion will get rid of the error and then the name can be changed using this method.

struct PersonStruct: Equatable {
    var name: String

    mutating func changeName(to newName: String) {
        if !newName.isEmpty {
            name = newName

var personC = PersonStruct(name: "Woody")
personC.name // Woody

personC.changeName(to: "Sid")
personC.name // Sid

There is no problem about using mutating and it will not have the unintended consequences of using classes. Despite the scary name, a mutating function actually returns a new copy of the struct.

The problem arises if you have many nested structs and the mutating has to spread through the list. So don’t nest your structs - at least not more than two deep!

Learning Swift - Optionals

Permalink - Posted on 2016-03-12 04:24

Today I plan to discuss optionals since they were a feature of Swift that I found difficult to grasp at first.

What is an optional in Swift?

An optional is a variable of a specified type that can also be nil.

Why does this matter?

In Objective-C, any object type could be nil. If you declared a variable like this:

NSString *myString;

then myString was set to nil by default.

But this could cause issues, especially as Objective-C does not complain if you send a message to nil. This could lead to bugs that were very difficult to track down.

The other big use for nil is when returning from a function which has found no appropriate data to return. The classic example is when looking for the index of an element in an array. What should be returned if the element is not found in the array?

Some languages return -1, Objective-C uses NSNotFound, but you have to know what each language is going to do. The more logical answer is nil. However if your function is expected to return an integer, then it cannot return nil because nil is not an integer.

This is where optionals come in: if the function is expected to return an optional integer, it can return with an integer with the index of the matching element, or it can return nil if the element was not found. This is much clearer and less prone to error.

How does Swift handle optionals?

One of the first things that struck me about Swift was how clean the code looked, without so many non-alphanumeric characters scattered around. Gone were all the:

* ; [ ]

But instead, Swift code sprouted:

! ?

What were these?

The key to understanding optionals is to realise that when you declare an optional variable of a certain type, you are actually declaring a box that can hold a variable of that type or can hold nil.

Once you grasp that concept, it all becomes much more obvious.

var optionalInteger: Int?

The ? indicates that this is an optional variable. It does not have to be initialised as it is already set to nil which is valid for an optional variable. Without the ? this would require initialisation as it would not be valid for it to be nil.

Setting an optional

Setting the value of an optional variable is just the same as any other variable:

optionalInteger = 3
optionalInteger = 42

Getting an optional

The difference arises when you need to get the data out of the optional variable in order to use it. This process is called un-wrapping and it means to get the variable value out of the ‘box’ it is stored it.

The most obvious way is to use !

let newInteger = optionalInteger!


This is called forced-unwrapping and assumes that the optional variable is not nil. If the optional is nil, this will crash. In Xcode, when you connect interface elements from your storyboard to a Swift file, Xcode will use ! like this:

@IBOutlet weak var startButton: UIButton!

I have to assume Xcode knows what it is doing and the button will be available when needed, but you should not use ! - it is un-safe. By using it, you are vowing to the compiler that when it gets to that point, the optional value will not be nil. There are much better and safer ways of doing that.

Use ‘if let’

func doubleNumber(_ optionalInteger: Int?) -> Int? {
    if let integerValue = optionalInteger {
        // integerValue is not an optional
        // and is guaranteed to contain an Int
        return integerValue * 2

    // no integer found in the optional,
    // so return nil to indicate failure
    return nil

Use guard

func doubleNumber(_ optionalInteger: Int?) -> Int? {
    guard let integerValue = optionalInteger else {
        // get out quickly,
        // returning nil to indicate failure
        return nil

    // integerValue is not an optional
    // and is guaranteed to contain an Int
    return integerValue * 2

These two alternatives (if let & guard) do the same job but in opposite ways. In both cases, they perform a conditional un-wrapping that may or may not give a valid result. if let checks if it is OK to proceed. guard checks to see if it is NOT OK to proceed. Which you use is really a matter of personal preference and working out what is more logical in each case.

The guard statement is really good for checking data early in a process and making a quick exit it something is wrong. The if let construct encloses your success code inside a block and can sometimes leave the failure code a long way from the check which can make it less obvious. The other potential issue with if let is the “pyramid of doom” common in early Swift code as demonstrated in this rather contrived example:

func isValidAddressBookEntry(firstName: String?,
                             lastName: String?,
                             emailAddress: String?,
                             phoneNumber: String?) -> Bool {
        if let validFirstName = firstName {
            if let validLastName = lastName {
                if let validEmail = emailAddress {
                    if let validPhone = phoneNumber {
                        return true
        return false

Thankfully, Swift now allows us to chain both if let and guard statements. Here is the previous example re-factored to use if let:

func isValidAddressBookEntrySwift2(firstName: String?,
                                   lastName: String?,
                                   emailAddress: String?,
                                   phoneNumber: String?) -> Bool {
      if let validFirstName = firstName,
          let validLastName = lastName,
          let validEmail = emailAddress,
          let validPhone = phoneNumber {
          return true
      return false

And here is the same function but using guard which allows the inputs to be checked immediately and the function exited if the u=inputs are not valid. For a short function like this, the change is not really significant, but if the function does a lot of processing of the input data, checking first and getting out as soon as possible is more efficient.

func isValidAddressBookEntryUsingGuard(firstName: String?,
                                       lastName: String?,
                                       emailAddress: String?,
                                       phoneNumber: String?) -> Bool {
        let validFirstName = firstName,
        let validLastName = lastName,
        let validEmail = emailAddress,
        let validPhone = phoneNumber else {
            return false

    return true

Use optional chaining

The final way to deal with optionals safely is to use optional chaining:

struct SocialMediaAccounts {
    var facebook: Person?
    var twitter: Person?

struct Person {
    var firstName: String?
    var lastName: String?
    var handle: String?

var socialMedia: SocialMediaAccounts?
socialMedia = SocialMediaAccounts()
var twitterAccount = Person()

socialMedia?.twitter = twitterAccount
let twitterHandle = socialMedia?.twitter?.handle

In this example, we have defined a SocialMediaAccounts struct that holds optional Person structs for the various social media outlets. The socialMedia variable is defined as an optional and then created. A twitterAccount variable of type Person is also created but contains no data at the moment.

When assigning the twitterAccount to the socialMedia.twitter property, a ? is inserted which checks to see that socialMedia is not nil. If it is nil, then execution of that line stops at the ? and nothing bad will happen.

In the same way, when trying to read back the twitter handle, we chained together 2 optionals with ?’s. If either socialMedia or socialMedia.twitter is nil, that line will not complete. Again this is perfectly safe and the app will not crash.

All the examples in this article are available in a Swift playground which has been updated to Swift 4 syntax.

Learning Swift - For-Loops

Permalink - Posted on 2016-03-12 00:00

Loops are a fundamental building block of any program. Doing repetitive tasks fast and accurately is what computers are really good at and what we humans get very bored doing. Swift offers several different ways to perform loops, but today we are going to concentrate on for-loops.

The most basic form of loop is the for-in loop. There are two ways this can be used: looping over the numbers in a range or looping over the elements in an array or dictionary.

Firstly, the range:

for x in 0 ..< 5 { printWithSpace(x) }
// prints: 0 1 2 3 4

I am using a custom print function that allows me to print the results on a single line for convenience.

This for-in loop uses a half-open range and it is effectively saying:

start with x at 0
print x with a space
add 1 to x
is x still less than 5?
    yes - go back to the print stage
    no - stop

If we wanted to go all the way to 5 instead of stopping before 5, we would use a closed range by replacing ..< with ...

for x in 0 ... 5 { printWithSpace(x) }
// prints: 0 1 2 3 4 5

These methods work fine if we want to loop through a range of numbers one at a time but what if we want a different increment? There are several ways to vary the step.

  • stride(from:to:by:)
  • stride(from:through:by:)
  • where
for x in stride(from: 0, to: 10, by: 2) {
// prints: 0 2 4 6 8
for x in stride(from: 0, through: 10, by: 2) {
// prints: 0 2 4 6 8 10

The 2 variations of stride are analogous to the 2 ways of expressing the range in the the for-in loop.

stride(from:to:by:) starts with the number in the from parameter and each time through the loop, increments that number by the amount of the by parameter. If the incremented number is less than the to parameter, the loop continues.

stride(from:through:by:) works the same way but continues until the incremented number is greater than or equal to the through parameter.

Using a negative value for by allows counting backwards:

for x in stride(from: 10, through: 0, by: -2) {
// prints: 10 8 6 4 2 0

Stride can also be used for floating point loops although the result may contain some unexpected changes in precision e.g 0.7000000000000001 instead of the expected 0.7

let startingNumber = 0.1
for x in stride(from: startingNumber, through: 1.0, by: 0.2) {
// prints: 0.1 0.3 0.5 0.7000000000000001 0.9

Note that the result does not contain the through parameter as the next iteration would have produced 1.1 which is greater than it. And also startingNumber did not have to be a variable as it is never actually changed.

Using where makes it possible to step through a loop while conforming to some conditional:

for x in 0 ... 10 where x % 3 == 0 {
// prints: 0 3 6 9

The other main use for for-in loops is for iterating through the elements of an array or dictionary:

let arrayOfInts = [ 1, 2, 3, 4, 5, 6 ]
for x in arrayOfInts {
  printWithSpace(x * 2)
// prints: 2 4 6 8 10 12
let myDict = [ 1: "one", 2: "two", 3: "three" ]
for (key, value) in myDict {
  print("\(key) = \(value)")
// prints:
// 2 = two
// 3 = three
// 1 = one

As a dictionary is un-sorted, the order of the items may vary.

If you want to loop through an array while also monitoring the index of each element, you can use enumerated()

let arrayOfNames = [ "Andy", "Buzz", "Woody" ]
for (index, element) in arrayOfNames.enumerated() {
  print("The name at index \(index) is \(element)")
// prints:
// The name at index 0 is Andy
// The name at index 1 is Buzz
// The name at index 2 is Woody

If your array contains optionals, you can use for case let to test each value:

let arrayWithOptionals: [String?] = [ "Woody", nil, "Buzz", nil, "Rex" ]
for case let name? in arrayWithOptionals {
// prints: Woody Buzz Rex

The name variable is un-wrapped each time through the loop so can be used safely.

Any of these loop styles can be combined with where to perform checks on each iteration:

let arrayWithOptionals: [String?] = [ "Woody", nil, "Buzz", nil, "Rex" ]
for case let name? in arrayWithOptionals where name.count < 5 {
// prints: Buzz Rex

Some of you may be wondering what happened to the old C-style loops like this:

for var x = 0; x < 5; x++ { print(x, terminator: " ") }

This does not work in Swift 3+: the ++ and -- operators and this style of loop declaration have been removed from the language. For further details, check out the relevant proposals at Swift Evolution:

All the examples in this article are available in a Swift playground now updated to Swift 4 syntax.

Learning Swift - Generics

Permalink - Posted on 2016-02-29 00:00

One of the nice things about Swift is how clean your code looks. A lot of the weird characters that pepper the code of other languages has been eliminated: No more semi-colons, asterisks etc.

But then you are reading somebody else’s code and you find these angle brackets all over the place and they don’t seem to make sense.

What does this mean?

func mid<T: Comparable>(array: [T]) -> T

It looks like it is a function to find the middle element in an array, but what is <T: Comparable> or [T] or even just T? They are describing Generic data types.

Using the dictionary, I find the following definition for generic:

characteristic of or relating to a class or group of things; not specific.

And that really provides quite a good definition for Swift’s generics too. They allow you to assign a non-specific data type to a function so that function can be used for many different data types.

But enough of the theory: by far the best way to understand generics is to encounter the problem they are meant to solve and then to solve it.

The other day I was processing data to feed to a charting library. I ended up with an array of CGFloats, but there were too many of them, so I wrote a function to give me the last x elements of an array of CGFloats:

func endOf(array: [CGFloat], numberOfElementsToInclude: Int) -> [CGFloat] {
  if numberOfElementsToInclude > array.count { return array }

  let startingElement = array.count - numberOfElementsToInclude
  let endOfArray = Array(array[startingElement ..< array.count])
  return endOfArray

let largeArray: [CGFloat] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
let smallArray = endOf(array: largeArray, numberOfElementsToInclude: 3)
//smallArray now equals [8.0, 9.0, 10.0]

OK, so largeArray isn’t actually the largest array you have ever seen, but it works for demo purposes. In my code, I had over 20,000 entries in the large array and only wanted the last 5,000.

I was completely happy with that until I found another data source where the data was an array of Ints. Still perfectly chartable using my charting library, but I could not get the end of the array using my nice function. First thought was to replicate the function:

func endOf(array: [Int], numberOfElementsToInclude: Int) -> [Int] {
  if numberOfElementsToInclude > array.count { return array }

  let startingElement = array.count - numberOfElementsToInclude
  let endOfArray = Array(array[startingElement ..< array.count])
  return endOfArray

let largeArrayInt = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] // type inferred to be Int
let smallArrayInt = endOf(array: largeArrayInt, numberOfElementsToInclude: 7)
// smallArrayInt now equals [4, 5, 6, 7, 8, 9, 10]

A quick glance will reveal that the declaration line was the only thing that changed. I didn’t have to give the function a new name because the compiler worked out which of the two functions to use based on the types supplied. So all I was doing was replacing CGFloat with Int in two places (the numberOfElementsToInclude parameter remains an Int in both cases).

As soon as you find yourself replicating code and only changing the types of the data, that is a sign that you need to use generics.

For my first attempt at creating a generic function, all I did was replace the word CGFloat with T where T indicates some type that will be specified when the function is called. The convention is to use single letters for generic types: T for Type, A for AnyObject, Z because you feel like it. The choice is up to you.

That produced this error:

Generics error

Use of undeclared type 'T'. Well that seems fair enough… how is the compiler supposed to know what a T is?

It turns out that this is where the angle brackets come into play. You have to warn the compiler that this function is going to get a generic type and that the T is only a placeholder, not a real type. So this version compiles and works - notice the <T> between the function name and the opening bracket:

func endOf<T>(array: [T], numberOfElementsToInclude: Int) -> [T] {
  if numberOfElementsToInclude > array.count { return array }

  let startingElement = array.count - numberOfElementsToInclude
  let endOfArray = Array(array[startingElement ..< array.count])
  return endOfArray

Now I have no code duplication and if I ever get another data set that uses a different object type, my function will still work.

Now we know to use generics instead of replicating code that operates in the same way on different data types.

And we know how to construct a generic function.

Using it is identical to using the two functions I had before:

let largeArray: [CGFloat] = [ 1.0, 2.0, 3.0, 4.0, 5.0,6.0, 7.0, 8.0, 9.0, 10.0 ]
let smallArray = endOf(array: largeArray, numberOfElementsToInclude: 3)

let largeArrayInt = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] // type inferred to be Int
let smallArrayInt = endOf(array: largeArrayInt, numberOfElementsToInclude: 7)

You do not have to specify what T is when calling the function, that will be inferred from the supplied data.

Moving on into more advanced use cases, we have two things to consider:

  1. Functions where the generic parameters must conform to a protocol.
  2. Functions that take generic parameters of different types.

The example function I started with (not mine but I forget where I got it… If it is yours, thanks you very much) used:

func mid <T: Comparable> (array: [T]) -> T

Instead of specifying the type as completely generic, it specified that it must conform to the Comparable protocol. This is because the function body used a sort() function so the generic function needed to be sure that the elements in the array could be compared. This technique can also be used to restrict the parameter types to sub-classes of a certain class.

For a function with more than one generic data type, you need to use more than one placeholder letter:

func genericWithTwoDifferentTypes<T, U>(param1: T, param2: U) -> Bool {
  // ...

And in exactly the same way, both T and U can be set to conform to a protocol or be members of a certain super-class.

Hopefully this has taken some of the mystery out of generics, but if you have any questions, please get in touch using the Contact page, comment below or contact me via Twitter: @trozware.

Singleton to Protocol

Permalink - Posted on 2016-02-26 00:00

I was driving through the town of Singleton the other day and of course, it got me thinking about using singletons in my apps. Singletons were a commonly used pattern in Objective-C programming and appear in many of Apple’s own APIs, but seem to be increasingly frowned upon in the Swift world.

So what is a singleton?

A singleton is a class that only expects to have a single instance. Think of it as a global instance of a class. In some cases this makes perfect sense if there can only ever be one instance of a particular class or if there is a default variant that suits most cases e.g.


If you are using an object with a property name of “shared”, “standard” or “default” you can be pretty sure it is an singleton.

And what’s the problem with singletons?

There are probably many different opinions here but I have two thoughts about this:

  1. They are effectively global variables and global variables can make your code messy and un-predictable.
  2. If they can be accessed by multiple other objects, possibly at the same time, then you can get conflicts. These can be handled by clever use of background queues, but it isn’t easy.

What to use instead?

As I drove, I mused on a singleton that I had implemented recently. It was a logging utility that allowed any object in my app (mostly view controllers) to save a new entry to a log file. The basic structure of the Logger class was this:

class Logger {
    static let sharedLogger = Logger()

    func addToLog(event: String) {
      // use private functions to find log file URL
      // append event text with time stamp


Any object in my app could use the Logger like this:

Logger.sharedLogger.addToLog(event: newLogEvent)

When I got to think about how I was using this, I realised that instead of a Logger object that everything could use, what I really needed was a Loggable behaviour that I could apply & restrict to the few classes that actually needed to log events. For me, this was the break-through:

Create a behaviour, not an object.

As soon as I started thinking about this as a behaviour, a protocol became the obvious solution, so this is what I created:

protocol Loggable {
  // not declaring functions here
  // as they should NOT be over-written

extension Loggable {

    func addToLog(event: String) {
      // use private functions to find log file URL
      // append event text with time stamp


We run immediately into one of the peculiarities of Swift protocol extensions which has been very well explained by Caesar Wirth. If I had declared addToLog(_:) in the protocol, then any class or struct conforming to this protocol would have been free to over-write this function and provide its own version. This is not what I wanted here - I wanted every object to use the same version. So I left the function declaration out of the protocol definition and only included it in the protocol extension.

To use this behaviour, a class or struct just has to be declared as conforming to the Loggable protocol:

class MyClass: Loggable {
  func doSomething() {
    addToLog(event: "I did something!")

For my app, I knew that I would want all my NSViewControllers to be able to add log events, so instead of setting them all individually as conforming to the protocol, I used this shortcut which extends all NSViewControllers to conform to the protocol.

extension NSViewController: Loggable {}

I added this line to the Loggable.swift file where I declared the protocol and its extension, but outside both of them.

Protocol-oriented programming is a new technique to me, so it really helps when I can find a practical example of where it solves a problem.

If you are new to POP, I highly recommend the Crusty talk from WWDC 2015. And this article by Matthijs Hollemans was invaluable to me in demonstrating the problems with object inheritance that are solved by protocols.

Three Rules for Writing Better Swift

Permalink - Posted on 2016-02-24 00:00

  1. Do not use !.
  2. Use let, not var.
  3. Allow the compiler to infer types.

Read on for more details…

1. Do not use !

Swift uses optionals for values that can be nil. To use an optional value, you need to “un-wrap” it first, which means getting the actual value out, assuming that the value exists and the optional is not actually nil.

Optionals are the subject of a complete post by themselves, but for now, I will just say this: When you use ! you are promising the compiler that you will make sure there is a real value in that optional by the time it is needed.

If this is not the case, your app will crash as shown in this playground:

Playground crash

Instead of using ! you should use optional chaining with ? or check the value with guard or if let before use.

One trap to beware of is with Xcode’s attempts to be helpful and suggest fixes to problems. If you use an optional where it cannot work, Xcode will warn you that it is incorrect, but the suggested fix will be to insert !

Optional fix

When you see this, do not accept the suggested fix, but use it as a warning to show that you need to fix the problem properly.

2. Use let, not var

Using constants in C-based languages is a pain. I could never remember the Objective-C syntax for declaring a static constant, so used to fall back to using #define for global constants. Inside my objects, all instance properties were variables, not constants. Inside functions, it was the same.

It doesn’t take much imagination to work out that your apps will perform better and more securely if values that do not need to change are allocated as constants instead of variables.

With Swift, this is easy as you just declare a constant using the let keyword and declare variables using var. The Swift compiler will now warn you if you have used var where let would do, but I prefer to declare everything using let and only change to var when this causes an error as shown in this playground example:

Playground let error

3. Allow the compiler to infer types

With Objective-C and many other languages, you have to tell the compiler exactly what each variable is going to be: a string, an integer, an object of a certain type.

With Swift, the compiler is clever enough to work this out for you, which can make your code much cleaner looking and easy to read.

There are a few exceptions to this rule which are shown in the playground below:

Lines 3 - 6 are allowing the Swift compiler to decide what the type is and it is choosing valid types: Int, Double, String and UIView.

Line 8 is a case where we do not want the default type, which would be Double so we need to tell the compiler that this one really should be a CGFloat.

Lines 10 & 11 both deal with an array of Ints. In line 10, the values are supplied so the type of the array can be inferred. In the second case, the array is initially empty, so the type needs to be specified in the declaration.

Lines 13 and 14 are the same but with dictionaries instead of arrays.

In each case, it would have been valid Swift to specify the type but why bother? The more text you enter , the more change of mistake and it leaves your code looking cluttered.

If you ever need to check what type has been assigned to a constant or variable, Option-click on it in Xcode and you willl get a popup telling you what it is.

Playground types

This was going to be five rules, but then I got a bit too verbose so will add more rules in a separate post.

Configuring Xcode

Permalink - Posted on 2016-02-17 00:00

While not strictly a part of my Learning Swift series, today I thought I would discuss some of the ways to configure and use Xcode to be a more productive and comfortable programmer.

1. Editor color themes and fonts:


Step through the supplied themes and find the best one for you. Then click the ‘+’ button at the bottom of the list and duplicate the selected theme. Now you can tweak it to suit you. Each text category can have its own font and size, but you can make multiple selections in order to do a bulk change. don’t forget to check out the Console section too - I dislike the default bold text for many of the console reports, so always change that.

An editing font should be mono-spaced i.e. every character should take up exactly the same width on the screen. This makes your code look neater and neater code is easier to read when you come back to it. I also much prefer a sans-serif font, but that is a matter of preference.

Menlo is the font used by Xcode as a default, but there are many other options either in the default installation of OS X or as free downloads. I change every now and then just to keep things interesting, but my current selection is Fira Code. I love the way it merges two character symbols into a single character for faster comprehension.

My other favourites are:

Look for a font that makes it easy to distinguish the digit ‘1’ from a lowercase ’l’ and where the digit ‘0’ is different to the ‘O’.

To install and use a new font, download the files and then double-click a TTF or OTF font file to install it in FontBook. Once the font is installed, you may need to restart Xcode in order to make it available.

2. Add-ons:

Update: Xcode 8 has removed the ability to run any plugins or to use Alcatraz, so this sectrion is no longer valid. Instead Apple is offering offical support for Xcode Source Editor Extensions, so they are the way of the future.

3. Documentation:

Xcode has excellent documentation, but unless you specifically download it, this will all be accessed online. If you have a bad or non-existent connection, this can be annoying. Go to Xcode’s Preferences -> Downloads and download all the document sets you are interested in. They are quite large, but having them local will be a big bonus.

The other tool I use for documentation is Dash. It supports many languages and is not just for use in Xcode. I found the Xcode integration plugin was not very useful as it conflicted with other useful behaviours. So I set up a global shortcut in System Preferences to search Dash for the selected text. This is much faster than Xcode’s built-in documentation.


4. Other preferences:

Go through the preference panes in Xcode’s preferences and tweak to suit your style or your group’s preferred style.

General and Text Editing are important. Text Editing has a second tab for Indentation which is easy to miss. Indentation styles seem to cause a lot of heated debate, so make sure you check this out.

Accounts is vital if you are publishing to the App Stores and also makes it easy to transfer all your develop information from one computer to another.

Fonts & Colors and Downloads are discussed above.

I tend to leave the others set to the defaults.

How do I start to learn Swift?

Permalink - Posted on 2016-02-16 00:00

The first thing to do is to download the latest version of Apple’s Swift Programming Language book from the iBooks Store.

You can just read this book, especially the first section: “A Swift Tour”, but you will get more out of it if you follow along with the playground. There is a link to download the playground from the book which you can use directly if you are reading using iBooks on the Mac. If you are not, here is the download link.

You will also need to install Xcode from the Mac App Store. Xcode is Apple’s IDE and is used for programming Mac, iPhones, iPads, Apple Watches and Apple TVs.

Swift introduced the playground to Xcode. A playground is a fantastic way to learn and experiment. You do not need to create a project, build, run a separate app, install on a device. Code typed into a playground is run immediately and you can see the results instantly, line by line.

Here is an example of a playground showing the code on the left and the result of each line appearing on the right.


Once you have gone through the Swift Tour, Apple’s book becomes more of a reference guide to return to whenever you get stuck. The other way I use it is to check up on changes made when a new version of Swift is released. As the language is still rapidly evolving, these can be quite extensive. Once I have the latest version of the book, I go to the Revision History at the back and click the links to read about the features that have been added or changed.

Apart from Apple’s documentation, there are a lot of great web sites, blogs and Twitter accounts out there. There are also useful newsletters that give a weekly summary of exciting developments.

Here are some of my favourites:

  • Natasha the Robot - my favourite Swift blogger - sign up for her newsletter and follow her on Twitter.
  • Apple’s Swift Blog - not many posts, but good for learning about new features.
  • Erica Sadun - sometimes a bit too technical for me, but often contains some really useful snippets. Erica has the distinction of being the first person outside Apple to have had a Swift language proposal accepted as part of the open source development process.
  • Andy Bargh - detailed articles on various aspects of Swift, plus a weekly newsletter.
  • Ray Wenderlich tutorials - search for Swift and find heaps of tutorials covering many different aspects.
  • Swift Sandbox - weekly newsletter filled with interesting articles.
  • SwiftMonthly - useful newsletter with links to tutorials, videos and projects.
  • SwiftDoc.org - the documentation in Xcode is still heavily skewed towards Objective-C programmers and it can be difficult to find Swift-specific entries. This site makes it easy.

And I hope you will keep coming back to this site to see what new Swift-related articles are available.

Icon Builder 3.2 Released

Permalink - Posted on 2016-02-10 00:00

Icon Builder 3.2 is now available from the Mac App Store.

  • Icons for Apple Watch apps now have their alpha channel removed.
  • Tidier folder structure for related files (iTunes Artwork files and Read Me).
  • Updated to work with Xcode 7’s Assets.xcassets folders.
  • Creates iPad Pro icons for Xcode 7.2 or later.
  • Fix for Retina Macs creating double-sized images.

Why is Swift so great?

Permalink - Posted on 2016-02-10 00:00

Firstly, I can give you the technical answer, as published by Apple:

Swift is a new programming language for iOS, OS X, watchOS, and tvOS apps that builds on the best of C and Objective-C, without the constraints of C compatibility. Swift adopts safe programming patterns and adds modern features to make programming easier, more flexible, and more fun. Swift’s clean slate, backed by the mature and much-loved Cocoa and Cocoa Touch frameworks, is an opportunity to reimagine how software development works. Swift has been years in the making. Apple laid the foundation for Swift by advancing our existing compiler, debugger, and framework infrastructure. We simplified memory management with Automatic Reference Counting (ARC). Our framework stack, built on the solid base of Foundation and Cocoa, has been modernized and standardized throughout. Objective-C itself has evolved to support blocks, collection literals, and modules, enabling framework adoption of modern language technologies without disruption. Thanks to this groundwork, we can now introduce a new language for the future of Apple software development.”

Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2.1).”

Now I can give you my opinion:

  • Swift makes for code that is easier & faster to write.
  • Swift makes for code that is easier & cleaner to read (much more important than ease of writing).
  • Swift code is safer code.
  • Swift breaks free from the out-dated conventions of C-based languages.

When Apple announced Swift at WWDC 2105, I was astounded. That such a major event could have been kept completely secret was amazing. Then I watched every video from WWDC 2015 that discussed Swift. Some were beyond me and others I absorbed. Looking back, I can see that the development of Objective-C over the past few years was all aimed at getting to this point, especially with the introduction of ARC and blocks.

At that time, I was deeply involved in an existing Objective-C project and not able to do much in Swift. But I went through the introduction at the start of the Swift Programming Language book in iBooks and was able to get some ideas about how the language worked.

Some months later, I was able to spend time on Swift. As a learning exercise, I converted an existing Objective-C iOS app to Swift. As might be expected, I really just wrote Objective-C code using Swift syntax. It took a lot more learning before I was able to write Swift-y code instead of just translated Objective-C. In future posts of this series, I hope to enable others to cross that divide faster than I did.

Now when I go back to an Objective-C app, I feel like I am walking a tight-rope. When I use an NSArray, NSSet or NSDictionary, I think “How can I tell what sort of objects are in that array?”. When I use an object, I think “What if that object is nil?”. All of a sudden, code that appeared stable now feels random.

One of the big things that people have latched onto with Swift is that it allows functional programming. I plan several detailed posts on functional programming in this series. But for now I would just recommend that you not worry about the distinction between procedural & functional programming. Both have their advocates and their detractors. Both have their advantages and disadvantages. Just do what ever works for you and we can worry about this later.

Learning Swift - An Introduction

Permalink - Posted on 2016-02-09 00:00

Welcome to Learning Swift.

This is the first post in what I hope will be an extensive series dealing with the Swift language. Here are some of the questions I hope to answer:

  • Should I learn Swift? Why?
  • Why is Swift so great?
  • How should I start learning Swift?
  • I already know Objective-C - how do I convert?

After that, I am planning a series of posts discussing the major differences of Swift from the view point of an Objective-C programmer and the aspects of Swift that I found difficult to grasp. Topics covered will include such things:

  • optionals
  • closures
  • functional programming
  • protocols
  • generics

I am coming from a background of Objective-C, so many of my posts will be dealing with aspects of Swift that are not familiar to Objective-C programmers. I will not assume any Objective-C programming experience, but some features of Swift that are new to me, will be familiar to people accustomed to other languages.

So let’s start by answering the first question:

Should I learn Swift?

If you are writing or planning apps for any Apple platform - YES. If not, wait until Swift is available for the platforms you need to support.


If you are already an iOS or Mac developer: YES

This is the new language and Apple is very committed to it. Objective-C is not going away any time soon, but Swift is where it is going to end up, so why not make the jump now while the language is still in development? You have to accept that fact that every release of Xcode is going to break your code, but the automatic re-factoring works very well. And by moving to Swift now, you get the chance to influence the direction of a new language. How often does that happen?

If you are starting to learn iOS or Mac development: YES

If you have no history with Objective-C, then do not waste your time learning it. There is still a lot of sample code out there in Objective-C, but increasing numbers of tutorial sites are using Swift and converting their existing tutorials to Swift. It will help if you know just enough Objective-C to read it, but you do not need to know enough to write it.

If you do NOT program for Mac or iOS: NOT YET

Swift went open source in late 2015. This is a big deal and Apple’s plans for Swift are quite clear. They want Swift to be such a main-stream language that it is used instead of Java for basic computer science courses in universities. This was never going to happen unless the language was open-source and cross-platform. It is now open-source and available for Linux as well as Mac/iOS. While Apple has not yet released any further ports, I think there are more on the way for Raspberry Pi, Arduino and other embedded systems as well as server-side Swift libraries like Perfect. I expect that a version for Windows will not be far behind.

New Twitter account

Permalink - Posted on 2016-02-09 00:00

I have started a new Twitter account so that I can provide rapid support to users of my apps. Please contact me @trozware if you have any questions, suggestions, bug reports or would just like to chat.

I will also be using this account to promote my new Learning Swift series.

Possible issues with Icon Builder & Watch icons

Permalink - Posted on 2016-02-06 00:00

It has come to my attention that there are two possible issues with Icon Builder 3.0.1 when using icons created for an Apple Watch app. Once of them is something I can fix and the other appears to be a bug in Xcode 7.2

Update: Version 3.2 of Icon Builder is now available in the Mac App Store. This removes the alpha channel from icons for a watch app.

The first problem is that iTines Connect now requires that the icons for an Apple Watch app include no alpha channel. This is becoming an increasing trend with it first having applied to the large icon file you upload directly to iTunes Connect, then to screen shots. I expect it to extend to iOS app icons soon, but hopefully Mac app icons can continue to include transparency.

With Apple Watch icons, you are supposed to create a set of square icons and watchOS or iTunesConnect applies the rounding mask. Presumably this is more complicated if the icon contains an alpha channel even if there are no transparent pixels. If your Watch app icons contain an alpha channel, you will see errors like this after uploading your app to iTunes Connect:

Invalid Icon - The watch application ‘AppName.app/Watch/AppName WatchKit App.app’ contains an icon file ‘AppName.app/Watch/AppName WatchKit App.app/AppIcon-Watch24x24@2x.png’ with an alpha channel. Icons should not have an alpha channel.

You will probably get this error message for every icon size in the Watch app (8 in total). Until I release a new version of Icon Builder that allows for this this, I suggest you use this Alpha Channel Remover app.

In your Xcode project, go to WatchKit App Assets.xcassets, select the AppIcon set, right-click and choose “Show in Finder”. A folder will open containing eight .png files and one .json file. Drag & drop the .png files into the Alpha Channel Remover window and click the “Remove Alpha Channel” button. This will replace all those image files with new versions without alpha channels. To confirm this, select any of the images and press Command-I to get info. In the More Info section, you will see “Alpha channel: No”.

You can now submit your app again, but that only solves one of the issues.

The other problem is that you will get a warning about the 44x44@2x.png icon file.

Invalid Icon Name - The watch application ‘AppName.app/Watch/AppName WatchKit App.app’ contains an invalid icon file name ‘AppName.app/Watch/AppName WatchKit App.app/AppIcon-Watch44x44@2x.png’. Make sure that icon file names follow the pattern*<dimension>@<scale>x.png” and they match the required dimensions. Please visit https://developer.apple.com/watchkit/ for more information.

As you can see in the error message, the icon name (which is set by Xcode) does conform to the required pattern, and the image is the correct size. This appears to be a bug in Xcode 7.2 but does not stop you from submitting your app as it is only a warning and not an error. Presumably this will be fixed in later version of Xcode. I am running Xcode 7.2.1 and still see this warning.

Man Reader 1.5

Permalink - Posted on 2016-01-31 00:00

Man Reader has been updated to version 1.5 with a major improvement in the way it looks for available man pages.

Man Reader 1.5 is now available through the Mac App Store.

Change Log:

  • Much improved searching for available man pages.
  • Sand-boxed version now works just as well as the non-sand-boxed.

The main feature of this version is that it solves the previous problems with the App Store version and sand-boxing. This was restricting the number of man pages listed in Man Reader so I had to release a non-sand-boxed version of the app to allow for full functionality.

However I discovered that although this gave better results, it was still missing a lot of man pages. Version 1.5 now queries the man page files in a completely different way which is listing many more man pages.

If you previously had downloaded the Man Reader (no SB) version of the app from this site, please revert to the App Store version which you would have needed to have bought in order to use the downloaded app. If you bought the app from Paddle, contact me and I will transfer you to the App Store version. Neither of these other versions will be supported or updated any more.

Using 19th Hole on the Apple Watch

Permalink - Posted on 2015-12-12 00:00

19th Hole for iPhone and Apple Watch version 3 is now available through the iTunes App Store. This version is a complete re-write to accommodate the changes in iOS 9 and watchOS2.

The major changes are to do with the way the iPhone and the Watch communicate. In watchOS1, all the brains of the app had to live in the iPhone, meaning that every single interaction on the Watch had to be referred back to the iPhone for processing and the result sent back to the Watch for display. This lead to communications delays and breakdowns which caused third-party apps to work sluggishly or not at all. In watchOS2, the brains of the watch part of the app can now operate inside the watch, greatly reducing the number of communications needed. As well as that, Apple has now provided us with multiple ways of getting data to and from the Watch which again improves performance and reliability.

With the 19th Hole, I made the decision to change the method of inputting scores. The previous version used a slider with plus and minus buttons to adjust scores. The problems with this were the small target area of the plus & minus buttons as well as the fact that a slider with more than about 3 divisions was not useful as a visual indicator.

When watchOS2 allowed developers access to the digital crown, I decided to switch to using that instead. Now you tap the score box of the player you wish to adjust and use the digital crown to select a number. I think this will be easier to use while wearing a glove and hope that it is still easy to read out doors.

The other suggestion is not to do with watchOS2 but is a general tip for using apps of this kind. By default, the Apple Watch will always show the watch face when you raise your wrist. Normally this is the most useful thing, but when scoring a round of golf, it would be easier if The 19th Hole app stayed at the front. To make this happen, you need to set to watch to show the last used app instead of the watch face. This can be set using the Apple Watch app on the phone or on the watch itself.

On the phone:

  • Open the Apple Watch app.
  • Select My Watch from the tabs at the bottom.
  • Tap “General” and then scroll down to tap “Wake Screen”.
  • Make sure “Resume Last Activity” is checked.

On the watch:

  • Press the digital crown to see the app icons.
  • Find and tap the Settings icon.
  • Scroll down and tap “General”.
  • Tap “Wake Screen” and scroll down to make sure that “Previous Activity” is checked in the “Resume To” section.

Dice Pass for Mac

Permalink - Posted on 2015-05-30 00:00

We live in a world of passwords and passphrases and there is a constant struggle between having a secure and a memorable password. As a result, many of us re-use passwords even though we know this is a bad idea.

XKCD had a wonderful comic that illustrated the theory of using a passphrase composed of words that are easy to remember but with a combination that made the passphrase very hard to guess. However even when deciding to use a passphrase like this, it is not easy for us humans to avoid using words that have meaning for us, particularly when it is something we really need to remember.

Diceware was developed to solve this problem. You have a set of 5 dice and a list of words assigned to each possible dice roll for 11111 to 66666. You roll the five dice and get the matching word from the list. Repeat this for the number of words you want to use in your passphrase and you have a random phrase that is hopefully still memorable.

But this sounds like a lot of effort and not something you are likely to do when faced by a password entry field on a web page. So Dice Pass was written to do the work for you quickly and easily.

Dice Pass for Mac

Select the number of words you want in your passphrase and see the phrase immediately. Keep clicking the “Generate New Phrase” button until you get a phrase you like. If you feel that the computer is not to be trusted when generating a random number for the dice rolls, use your real dice and click the dice to change them to the roll you got. If you get a passphrase that is good except for one or two words, use the Re-Roll button beside those words to get a new roll for just that word.

Dice Pass is available from the Mac App Store now.

Apple Watch First Impressions

Permalink - Posted on 2015-04-29 00:00

I realise that every one has written one of these posts, but given that everyone looks for and notices different things, I think it is still valid.

My first impression was “Why does it come in such a large box?”. The courier delivered two boxes - my 38mm Apple Watch Sport and Tim’s 42mm Apple Watch Sport. They both came in long boxes, with the 42mm box significantly longer. And both boxes were heavy!


Opening them was a typical Apple experience: pull the tag to open the external cardboard box, lift out the white internal box. This opens to reveal the watch with the default strap attached (short for 38mm, long for 42mm). Lift the watch out and pull the tags to remove the plastic protective coating. (On a side note, it drives me crazy when people leave this coating on devices, but I can’t see this happening on the watch.) Underneath there is a sleeve containing the other half watch strap so you can swap from long to short. My family tells me that this also includes a user guide, but I didn’t read that - typical Apple user… Under the sleeve is the power block and charging cable. The charging puck is larger than I expected and the cable is very long. Having removed all the components, the packaging is still quite heavy, so I guess Apple just wanted to make sure that no watches were damaged in transit and that it felt like a quality product.


Pairing my watch to my iPhone was amazingly slick. After selecting my language, the watch displayed a sort of nebula pattern. On the iPhone, I launched the Apple Watch app, selected the pairing option and pointed the phone camera at the watch display. This did the pairing. Then I waited while all the relevant apps transferred their Apple Watch components to the watch and I was ready to start using it.

The Watch:

The watch comes with the modular watch face showing by default. This is a digital time read-out with various ‘complications’. Force-touch the watch face to change it - this takes a surprisingly strong touch. Then you can swipe sideways to select a watch style. Once you have a style selected, some of them offer further customisations: select how much detail is shown, choose what extra information to display, adjust colors.

This is a lot of fun and I am still changing mine very frequently. The good thing is that your customisations are stored, so if you set up the utility watch face in a particular way, then swap to the modular and configure it, when you go back to utility, your previous settings are all still there.

The screen is gorgeous - very crisp and easy to read.

Twisting your wrist to show the time works well most of the time. There is a delay that I would estimate at about half a second, presumably to avoid false positives triggering unnecessary displays. If you are holding your wrist at an unusual angle e.g. showing the watch to someone, this twist will not always work, but tapping the screen will display the watch face instantly.

Tapping on a complication will take you to the relevant parent app e.g. tapping the current temperature will open the Weather app.

A minor quibble is that the phases of the moon are displayed from a northern hemisphere point of view and do not match what we actually see here in Australia.

Battery Life:

This is a complete non-issue. On my first day with the watch, the battery was at 70% when I first turned it on. As you can imagine, usage was very intense that first day and I got to 8%. Since then, the battery level has only got down to 40 -50% over a day and it recharges to 100% within 2 hours. Tim’s 42mm model gets slightly better battery life as expected.

I started off having the battery indicator as one of the ‘complications’ on my watch face, but now I just ignore it.

And the battery life of my iPhone has improved remarkably due to so many quick transactions being done through the watch instead.

I did have a charging problem one night. I woke up and checked the time and realised that the watch was quite warm to the touch. I checked the battery level which was actually lower than when I had put it on the charger. I took it off the charger for a few hours, then put it back and all was well.


Here is where you need to be careful. I had turned off most notifications on my phone before getting the watch, so I have not been inconvenienced, in fact I have been able to re-enable many notifications as they are no longer so intrusive.

At first we thought some notifications were not getting through to the watch, then we found out that if your iPhone is awake and un-locked, notifications are not passed on to the watch. So drop the time until sleep on your phone to the minimum which saves your phone battery and makes sure you receive most notifications on the watch.

If you want to stop any apps sending notifications through to the watch, this is easily set in the iPhone’s Apple Watch app.

I have noticed there is a bit of a delay. I hear an email or message arriving on my phone and it can be half a minute before it gets to my watch.

Once you get a notification, you can tap it to go to the parent app, swipe up to process it in some way depending on the type of notification, or swipe to the left to see a button that will clear the notification. If you want to get rid of all your notifications at once, do a force-touch on the notifications screen to get the option to clear them all.


Glances are designed to be one screen indicators giving you important information as quickly as possible. From there, you can decide whether to go to the parent app or not. These are accessed by swiping up from the bottom of the screen when looking at the watch face.

I found that the most important thing here was to reduce the number of glances shown, since they are displayed sequentially. If you have 20 glances installed, you have to swipe at least 20 times to see them all. So go to the Apple Watch app on your iPhone and turn off the glances you do not find essential.

The first glance in the sequence is essential though as it allows you to toggle airplane mode, do not disturb and silent mode. It also has a button that can make your iPhone make a sound to help you locate it. Hold this button down to make the iPhone flash come on as well.


Here I have to confess to my first disappointment. The activity app tracks three things: Move, Exercise and Stand. When you first start the watch, you tell it your age, sex, weight and height. It computes a suggested daily move goal for you which you can adjust at any time. Then it tracks your daily activities and shows how well you are doing in relation to your goal. For exercise and standing the goals are 30 minutes exercise and standing for at least one minute in an hour 12 times though the day.

The move tracking seems to be fine. I am not sure what metrics it uses, but on more active days, the numbers go up.

The exercise one doesn’t work for me. We went for a walk and when we returned, Tim’s watch showed 25 minutes exercise and mine showed 1 minute. We had walked the same distance at the same speed, as confirmed by the pedometer. Subsequent tests revealed that I don’t swing my arms enough when walking to trigger what ever sensor this is using. I can’t quite see why it ignores the pedometer completely, but hopefully this can be fixed by a software update. For now, I just ignore this circle.

Standing is another issue since I use a standing desk, so I stand for many hours each day. Even when standing, I get my hourly reminders to stand. However I use this as a trigger to make me to move about for a minute, so I suppose that is still useful.


The various forms of communication are a real strength of the watch. With Tim & I both having watches, we can phone, message (audio or text) and use the new Digital Touch to send sketches, taps or heart beats. While it feels a bit weird to be talking to your wrist, this works really well and the sound quality is amazing for such a small device. If you need more privacy, it is very easy to transfer a phone call back to your phone.

Oddly, the watch does not appear to offer FaceTime but always uses standard phone calls.

Messages are where the watch excels. If you get a message with a question, the watch can suggest possible answers so you just have to tap a button. Even without this, there is a set of pre-defined answers which you can edit in the Apple Watch app on your iPhone. And you can also use dictation or the new animated emojis. Dictation seems a lot better on the watch than it ever was before on the phone. And even if dictation is not transcribed perfectly, you can send the message as an audio recording instead of text.

When recording, tap the Done button as soon as you have finished speaking. The inclination is to wait for the text to be processed, but the recording carries on, so stop the recording and let the text processing finish in its own time.

The animated emojis work when you send them to other devices as they appear as GIFs. You can choose from 3 sets: faces, hands and hearts. Once you have swiped to select a set, use the crown to scroll between the options. You can also swipe further to get to the standard emojis.

Digital Touch works between watches only. It is a fun gimmick and I can imagine us developing a set of key codes or sketches, but neither of us can draw very well, so the sketches are very rough. The heart beat is amusing, but the tapping is surprisingly effective as an attention-getter.


I think this is the start of a new way of interacting with our technology in a way that is both closer to us and less intrusive. I am loving the watch so far and can’t wait to see where it goes from here.

Time In Words 4.0

Permalink - Posted on 2015-04-15 00:00

Time In Words for iOS started off as a fun gimmick, emulating the Qlocktwo type of time display where the relevant words are highlighted in some way to spell out the time as a sentence. This very quickly evolved into what I hoped would be more useful app, still showing the original display, but also providing the current time & date as complete sentences. Then I added time conversions and discovered the real power and utility of writing out times as words.

When it comes to converting times, I doubt there are many people in the world who haven’t had problems.

  • Is that morning or afternoon for them?
  • Are they in tomorrow, today or yesterday?
  • What if they are using daylight-savings?

Having the time written out removes all ambiguity. As an example, Time In Words currently reports very clearly:

In Los Angeles, it is nine minutes to ten on Tuesday evening (daylight-savings time).

When writing Time In Words for Mac, I focussed immediately on the time zone conversion facilities, and provided a menu bar app that can display as many time zones as you like (although more than will show on a single screen would probably get annoying).

So when I decided to do a complete re-write of Time In Words for iOS, the obvious move was to emulate the Mac version and allow for as many time zones as the user wants, instead of the current 2 or 4 (iPhone or iPad). So I discarded the Qlocktwo display and the separate date display which used a similar mechanic. I kept the display that shows the current date and time, but every display after that shows the time in a different time zone. The time zones can be changed and re-ordered, so the ones you need most are the fastest to get to once the app opens.

One new feature (again taken from the Mac version), is the ability to calculate “What time will it be…”

What time

You dial in your local date and time to see what time that will be in your selected zone. And if you want to calculate the other way around, tap the “Swap time zones” button.

The main impetus for a re-write was the Apple Watch. I thought this would be a perfect app for the watch as it could use the Apple Watch’s superb time-keeping in conjunction with my text generation, to add a significant level of usability to the Apple Watch as regards time zone conversions.

Sadly, Apple disagrees…

I completed the app and submitted it to the App Store for review. The review process seems to be very fast at the moment and the app moved into review only one day later. And there it stuck for 3 days. This was very odd. My experience is that once an app gets into review, it only takes a few hours, if that. For 19th Hole - my other app with an Apple Watch component, the review process took 30 hours. But 3 days!

Then I got a phone call from Apple where a very polite person explained to me that although this was not mentioned in any of the documentation, the marketing people had decided that no apps were to be allowed on the watch if they told the time.

I offered to remove the initial screen telling the local time, so the app would not actually supply the current time but only the time conversions, but that was not acceptable either.

Then I tried appealing the rejection. My hopes were not high, but I didn’t see any harm in asking. I again offered to remove the local time display and emphasised the accessibility advantages of displaying times in this manner. Another day, another phone call, another polite Apple person saying no.

So now I have re-submitted the app for review without the Apple Watch component, which is a shame. I am hoping that after some months they will review this policy and allow me to try again, but who knows.

So you can see what you are missing, here are a couple of screen shots from the watch app showing my local time, plus one time zone:

Local time Converted time

One more minor point. People who actually look at version numbers may wonder why I have gone from version 2.5 to version 4.0. When I was working on version 2.5, I considered making it version 3.0 and then changed my mind. However by that time I had already created a version 3.0 in iTunesConnect, so I was not able to use 3.0 again this time. This version was such a big change that I wanted it to be a .0 release, so that meant going to version 4.0

Apple Watch App - Rejected, then Accepted

Permalink - Posted on 2015-04-11 00:00

As described in a previous post, about 9 days ago I submitted my first Apple Watch app for review. The app was an extension of my golf scoring app: The 19th Hole.

I expected that App Store review times would go up dramatically once Apple had allowed developers to submit watch apps, but this proved to be incorrect. Three days after submission, the app was marked as “In Review”. This seemed to happen last thing on a Saturday, so there was no further action for two days, at which point the app was rejected, with the following details (sic):

We noticed an issue in your app that contributes to a lower quality user experience than Apple users expect. Specifically,

  • while using the Apple Watch app with the phone app is in the background mode (display off), the new data entry on the Watch App does not refresh accordingly until the phone app is turn back on.

So it appeared that the communication between the watch and the phone, which worked perfectly on the simulators, did not work at all on the actual devices. This is the problem with developing for a device that you do not have.

After some research, it appears that the problem is with the phone not operating correctly in background mode. Apple provides for communications from the watch to the phone. The phone can respond, but only the watch can initiate a connection. I guess this makes sense since every watch will be paired with a phone but the reverse will not always be true.

To talk to the phone, the watch uses this function:

func openParentApplication(_ userInfo: [NSObject : AnyObject],
  reply reply: (([NSObject : AnyObject]!, NSError!) -> Void)?) -> Bool

The phone listens for messages in this event handler:

func application(_ application: UIApplication,
  handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]?,
  reply reply: (([NSObject : AnyObject]!) -> Void)!)

The name of the WatchKit function is slightly misleading as it does open the parent application, but only in the background. Then the parent app is supposed to do whatever tasks are called for in the handleWatchKitExtensionRequest function, and return any required data using the supplied reply() function.

So far, so good, and it all worked perfectly in the simulator. But it appears that although this call wakes the iPhone app, it does not stay awake long enough to do anything. Many thanks to Brian at Five Minute WatchKit who pointed out the way to make this work. Firstly, you create a dummy background task guaranteed to keep the iPhone app awake for 2 seconds. Then you perform your own work, using another background task. When that is finished, the phone can send the response and end the real background task. The dummy task will time out by itself after 2 seconds.

For my needs, I could probably reduce the 2 seconds considerably, but since this is a problem I am unable to test, I decided just to go with Brian’s suggestion as it is.

I re-submitted the app the same day it was rejected, and two days later it was back in review. The review process took longer than usual, but about 30 hours later, the app was marked “Pending an Apple Release”. I assumed this meant that Apple would release all WatchKit apps on 24th April when the watches shipped, but the following day the app was reported as “Pending Developer Release” (I had set it to release manually). Now I have told iTunesConnect to release the app and it is “Processing for App Store”.

On a related note, the start of pre-ordering for the Apple Watch was scheduled for a very civilised 5:01 pm here in eastern Australia. I had three watches all lined up in my Favorites in the Apple Store app, ready for ordering. When the store became live (at about 5:03 pm), I could not work out how to order all three in a single operation, so had to place these orders one at a time. I got the first two ordered for the soonest possible delivery, but by the time I got to the third (about 3 minutes later), I had missed out and it will ship in 4 to 6 weeks!

My First Apple Watch App

Permalink - Posted on 2015-04-02 00:00

I have just submitted my first Apple Watch app to the iTunes App Store. This is a scary thing to do, since I have never seen, touched or used an Apple Watch and all I had to go on was the Simulator that Apple supplies with Xcode.

At the moment, Apple has only made a limited set of Apple Watch features available to developers, and all Apple Watch apps come tethered to an iOS app - presumably this will mainly be iPhone apps, but I wonder will we be able to connect Apple Watches to iPads? Anyway, it made sense to extend one of my existing apps to use the Apple Watch instead of starting from scratch.

Of my iOS apps, I decided that The 19th Hole, my golf scoring app, would be well suited to the Apple Watch. The problem with using the iPhone version to score is that you have to keep pulling your iPhone in and out of your golf bag, sometimes in the rain, sometimes in bright sunlight. Being able to enter the scores on your wrist sounds like a big improvement. We know that the Apple Watch is at least somewhat water-resistant, but we are yet to see how well it performs in bright sunlight, however I would expect that Apple has put considerable effort into this.

Once I decided to write an Apple Watch app, the first step was to learn how. I read all Apple’s published documents to get a feel for what was possible and what user-interface objects would be available. I find online courses very helpful and by far the best Apple Watch course that I found was Ray Wenderlich’s WatchKit video tutorial series. The instructors were very clear and explained how the layout and sizing of objects works on the Apple Watch, as well as how to set up and move between views and how to communicate from the Watch back to the iPhone. The layout section of the course was particularly valuable as no other course I found even mentioned this, although it is crucial to the interface design and allowing for the two sizes of watch.

I had released an update to The 19th Hole recently in preparation for this. I wanted to have squashed the bugs and updated the interface, so the only changes needed would be the WatchKit ones.

The first step in adding a WatchKit app to your existing app is to create a new target in the Xcode project. Choosing WatchKit actually adds two new targets: the WatchKit Extension which lives on the iPhone and supplies the code for the Watch, and the WatchKit App which lives on the Watch and provides the interface.

I decided to use a paged interface with one page per hole. Each of these pages has a table, with one row per player. A slider with plus & minus buttons lets you enter the score for each player and the total score for each player is also displayed.

Data entry

Apart from this data entry view, I have a splash screen which shows you the current round as set up on the iPhone and a final summary screen showing everyone’s totals.

Splash screen Summary

These images are taken from the Apple Watch simulator running in 42mm mode.

The biggest programming problem was getting the communications working beween the two devices. The 19th Hole uses Core Data for all data storage. My first attempt shared this data between the two apps, allowing both to read and update the database. This almost worked, but if both apps were open, then changes in one device did not get across to the other. It seemed that the data was cached and I was unable to find a way to force either app to update every time.

My next attempt kept all the data in the iPhone app and had the WatchKit extension ask for whatever data it needed and send changes to the iPhone app. This worked much better and I was able to get live updates between the two devices.

The other issue is the fact that I have never seen, touched or used an Apple Watch. This means that I had to guess a lot of things:

  • how well will it perform?
  • will the icon look OK?
  • are the controls large enough to use?
  • will the text be large enough to read?

My main philosophy was to keep the Watch app as simple as possible and use the standard interface elements, font sizes etc. Hopefully that will work.

The final step was submitting the app to iTunes Connect for review. It was not clear to me how to do this, so I logged into iTunes Connect, created a new version and entered the meta-data. I couldn’t see anywhere to say anything about the Watch. I archived the main iOS app as usual and validated it with the Store. I had a few things to fix up, but I got the build submitted.

Back to iTunes Connect and once the uploaded build had been processed, I was able to select it and click “Submit for Review”. At this point, the page reported an error and showed me a new section where I could upload the Apple Watch icon and screen shots.

I had been unsure how the icon would look when made round, but it looks OK on the iTunes Connect page. How it will look on a tiny watch screen remains to be seen. Anyway, once I had my icon and screen shots uploaded, I was able to proceed to the next step. But then I got a message saying that the app could not be processed - no explanation. Thankfully, I had seen some developers on Twitter reporting this, and somebody said that the solution was to remove the alpha channel from your screen shots. Sorry for not giving credit here - I forget who said this, but it worked, so thank you whoever you are.

So now my app is waiting for review and who knows how long that will take. According to App Review Times, the current estimate is 8 days, but the trend is heading upwards. I would expect that to blow out in the next few weeks as developers try to get their apps ready for the Apple Watch release date of April 24th.

LiveCode stacks

Permalink - Posted on 2015-03-18 00:00

When I converted my site to Jekyll & GitHub, one of the things I left behind was a collection of LiveCode (Revolution) stacks. For many years I was active in the Revolution community before going in other directions and over that time, I built up a small library of stacks that I released into the public domain.

LiveCode is a cross-platform rapid development environment. There is an open source community edition available for anyone wishing to get started.

I had assumed that since I had not been an active LiveCode user for many years, these stacks would have become worthless. But in the last couple of days, I have received a couple of queries from people looking for them.

So I created a new GitHub repository and uploaded them all to here: LiveCode stacks

None of these stacks have been updated recently, but feel free to use or adapt as you see fit. They have not been tested using recent versions of LiveCode, so may not work as expected. As stacks are provided as is. Use at your own risk.

Icon Builder 3.0.1

Permalink - Posted on 2015-03-17 00:00

So why an announcement for such a minor upgrade?

Version 3.0 got no announcement because it was not the release I wanted.

Having downloaded the Xcode 6.2 & 6.3 betas, I had worked out what icons were needed to a WatchKit app. This, combined with several other changes, made me bump the version number to 3.0.

Sadly, Apple rejected the update because it referred to pre-release products. So I pulled all mentions of WatchKit out of the interface and meta data and got 3.0 released.

After the Apple keynote on March 9th, I re-enabled the WatchKit portions of the app and re-submitted to the App Store, hoping that with the WatchKit SDK now part of the official Xcode release, Apple’s reviewers would allow it to get through this time.

This worked - in fact the app was reviewed and accepted within 6 days - so now Icon Builder adds WatchKit to its list of supported platforms.

Actually, Apple may have done me a favour in rejecting the first one as they changed the specifications for the icons slightly between Xcode 6.2 beta and Xcode 6.2 release.

What’s New in version 3?

  • Support for WatchKit app icons (version 3.0.1)
  • Simplified interface: removed display of smaller icons.
  • Fix for @3x images not being saved when you selected iOS 6 support.
  • iTunesArtwork@2x file now saved as a JPG to avoid iTunes Connect errors.
  • Removed CarPlay icon - Xcode sometimes gave errors when this was included.

App Store Preview Videos

Permalink - Posted on 2015-03-16 00:00

Apple now allows app developers to add a video preview of their app when uploading to iTunes Connect. This video is shown to potential purchasers when they are looking at an app in the iTunes App Store, just like the screen shots.

I have been working on an update to 19th Hole and since it uses a custom method for data input, I decided that a video would be really useful in this case.

The first step was to work out how to record video from my iPhone. In OS X Yosemite (10.10), this can be done using QuickTime Player. Connect your device to your Mac using a Lightning cable (I think it has to be a Lightning cable - the old cables will not work). Open up QuickTime Player and choose “New Movie Recording” from the File menu. By default this shows input from the Mac’s FaceTime camera, but just to the right of the red Record button, there is a down arrow that shows a popup menu. Click this and you can select your iPhone as the Camera. Since I wanted the sound effects included, I also selected my iPhone as the Microphone, but if you want to provide a voice-over or sound-track, you might want to change this.

That handles the technical side of recording, but I needed a way to show where I was tapping and pressing on the iPhone screen. After some searching, I found Touchpose which was exactly what I wanted. Since it requires changing the main.m file, as well as changes to the app delegate, I created a branch in my app’s git repository so that I could apply these changes temporarily, but save them for next time. The only alternation I made to the default settings was to change the color of the cursor indicator to suit the color scheme of my app. And since this was a temporary change, I set it to show the cursor indicator all the time, not just when the screen was mirrored. All the details are shown in the sample project.

Next step was to actually record a session. After my first attempt (which lasted about 67 seconds), I checked the Apple specs and found that the video could not be longer than 30 seconds. So I re-thought what I wanted to include and tried again. It took a few tries to get what I wanted, but finally I ended up with a .mov file that was 26 seconds long.

On to iTunes Connect where I had the new version of the app set up already with its screen shots. Since I have an iPhone 6, the video was only suited for the 4.7 inch section. So I dragged it into the drop zone and waited. No good - the video frame rate was too high. It has to be 30 fps or less. QuickTime Player had made a video that was 50 fps.

The app I usually turn to for any video conversion needs is Handbrake. So I ran the app through Handbrake, specifying a frame rate of 30. This converted the video to .mp4 instead of .mov, but it was 30 fps. It wasn’t until I tried to upload it to iTunes Connect that I realised Handbrake had cropped the video from 750 x 1334 to 750 x 1330. After searching through the settings, I found where I needed to turn on custom clipping and set it to 0 so that the original dimensions were preserved. But iTunes Connect still didn’t like it, although this time the error message was un-informative.

Eventually, the brains trust on the other side of the room suggested iMovie. Not only that, but he found that once the original had been dragged into iMovie, the share options included an “App Preview” setting. This gave us a .mov file of the correct dimensions and the correct frame rate which iTunes Connect accepted.

iTunes Connect that allowed me to select the poster frame for the video and save the changes to the app meta data. At that point, it showed a notice saying that the app preview was being processed which could take up to 24 hours. It appears that the processing has been finished, as that notice has disappeared.

For the next stage, I ned to wait until the app gets reviewed and hopefully approved. Then it will be interesting to see how the video looks in the iTunes App Store.

As a reward for reading this post, here is a pre-release of the video, showing how to enter the score data for a hole of golf using 19th Hole:

Testing automation

Permalink - Posted on 2015-03-12 00:00

Today I am experimenting with automating post generation.

Firstly, there is the structure of the post Markdown document, which really boils down to the file name and the header.

I have set up a macro in Typinator so that I just type the title of the post in a text document. I copy that title to the clipboard and type the shortcut. The header is then created with the title and the formatted permalink.

To save the document, I use another Typinator snippet to convert the title (still in the clipboard) to lower case and to replace the spaces in the title with dashes.

For starting the local Jekyll server, I have turned to an Alfred workflow. I have two actions in the workflow. One opens Terminal, cd’s to my site folder and runs the command to start the local Jekyll server. The second opens my default browser to the local Jekyll test address.

Both these actions happen simultaneously so the browser usually fails until refreshed. The server is left running in Terminal so I can shut it down when finished testing.

After writing the post, the final stage is to publish, so I need to work out the commands for doing a git commit and push. Then I should be able to automate those tasks.

Testing the git commands using Terminal, I have come up with the following sequence:

git add .
git commit -a -m "Commit message here"
git push

The commit message could be the title of the post, so I need a way to construct the command and then execute it. Typinator is good at text manipulation, so I constructed another macro that takes the clipboard, uses it as the commit message and performs the git commands. This gave a good commit message, but the actual commit failed, so that was no use.

So then I went back to Alfred and created a workflow there with a series of Terminal commands to perform the actions above. This only allows a generic commit message, but it works as expected.

So there is still room for improvement, but with a set of macros, I can automate a lot of the standard text entry, which is always good for reducing errors.

The sequence now is:

  1. Open the text editor and type the title of the post.
  2. Cut this into the clipboard.
  3. Run the Typinator macro to fill in the post header.
  4. Save the post file, using the Typinator macro to construct the file name.
  5. Write the post, then use an Alfred workflow to test it locally.
  6. When ready, use an Alfred workflow to publish.

Workflow for writing a post

Permalink - Posted on 2015-03-10 00:00

So here is where I need to get used to Jekyll and how things are done. I will end up automating this when I am sure of the process, but for now, I am just going to work my way through it.

  1. Start up the local Jekyll server:

    • I opened Terminal and used cd to get to the folder containing my site.
    • Next I started the Jekyll server locally using jekyll serve.
    • This gave me the address of the local server - in my case - so I went there in my browser to see the default page.
  2. My goal is to write a new blog post (this one in fact).

    • For advice on creating a new post, I went to the Jekyll docs.
    • Jekyll needs the file name to be a specific format which includes the date and title.
    • Looking in the _posts folder of the site folder, I see the previous post file is titled 2015-03-08-new-site-for-trozware.md.
    • As it is now 10th March 2015, I am saving this file as: 2015-03-10-workflow-for-writing-a-post.md.
    • Saving at this point shows a Jekyll error in the Terminal, but the next stage will fix that.
  3. Front matter:

    • Jekyll specifies that each file must have a front matter block in a certain format.
    • The header has certain essential parameters and then more optional ones.
    • My site was imported from WordPress, so the older posts contain several header parameters that may not be necessary any more.
    • Look at the screen shot below to see what I have in this post file:
    • After saving, I see this entry in my Terminal:
    • Regenerating: 1 file(s) changed at 2015-03-10 13:50:40 ...done in 0.421789 seconds.
    • Now I can see the title and the start of the post on my first page and when clicking on it, I can see all the text.
  4. Adding an image:

    • This is not really necessary for this post, but I wanted to document it as part of the workflow.
    • I wanted to show the front matter and start of this post, so I took a screen shot of the top of my editor window.
    • Then I renamed the image file and moved it into the images folder of my site.
    • Now to embed the image using this Markdown: ![Post header][2]
    • As you can see, I prefer to group all links (images & URLs) at the end of the document and keep the body of the text as clean as possible.
    • Post header
  5. Proofing:

    • Now that I have the text of my post, I need to proof-read it from the local Jekyll server.
    • The jekyll serve command running in Terminal keeps the pages up-to-date as you edit, but you will need to refresh your page in the browser manually to check your changes.
    • And I have found that if you make a major change to the site e.g. a CSS file or a config file, then it is best to stop the Jekyll server and start it again to make it re-build all the files.
    • To be completely sure, stop the server and run jekyll build in Terminal although this may only do what jekyll serve does on startup anyway.
  6. Publishing:

    • Now it is time to publish.
    • As I am using GitHub Pages to host, the site files are all part of a single Git repository.
    • And as I understand it, the data must be in the master branch.
    • Opening up the GitHub client, I see that my repository has a bunch of changes: - the file I am working on - the image I inserted - feed.xml - index.html files for each page
    • This is as expected, since all pages are pre-generated when using Jekyll, so pages of posts must be re-rendered when a new post is added to the top.
    • Note that several of the files appear twice: once from where they are edited and once from the _site folder which serves them.
    • Just two simple steps now, using the GitHub client: 1. Commit 2. Sync
    • And that’s it. My new post is online and ready for reading.
  7. Summary:

    • This was my first post after the one I wrote when setting up, so the first real post.
    • While there appear to be a lot of steps, none of them are difficult.
    • But I do have 4 apps running to do it: 1. TextWrangler for editing 1. Terminal to run the local Jekyll server 1. Safari to check the finished post 1. GitHub to commit and upload
    • Automating this is an obvious next step, so stay tuned…

New Site for TrozWare

Permalink - Posted on 2015-03-08 00:00

Welcome to TrozWare’s new site.

It appears that I am not alone in deciding to move away from WordPress. WordPress is great - easy to set up and with lots of cool themes to allow customisation of your site. But it is slow, especially if (like me) you are running on a low-cost shared server.

I had been reading about Jekyll, so I decide to give it a go and also host my site on GitHub, taking advantage of their faster servers.

I followed the advice given by Girlie Mac and performed the migration from my self-hosted WordPress site. I am using the Pixyll theme by John Otander with a few tweaks of my own. The site is much faster to load, and I am hoping that the easier editing will inspire me to write more posts.

Of course it wasn’t all positive. WordPress did give me some features I liked, but I think overall the result is better.


  • WordPress gave me a full LAMP stack, so I could run my own PHP scripts.
  • WordPress gave me a search function.
  • Commenting was built-in.


  • Jekyll builds the pages out as static HTML, so all pages are pre-generated for fast loading.
  • Writing for Jekyll is pure Markdown so it is easier to write and preview locally.
  • Some of the things I needed a plugin for in WordPress can be done natively in Jekyll: - tables - syntax-highlighting

For comments, I have switched to Disqus, but I am not sure about it yet. I will evaluate over the next few weeks. In WordPress, I used a plugin to handle the spam that inevitably arrived. I am hoping that Disqus will protect me from that, but I have to see how good a job it does and whether the few real comments are worth it. A better option might be to turn off comments completely and just have a contact form (which I have added using Formspree). Working in Markdown is great. I love how I can have a really clean look in my editor and still end up with well formatted HTML. I use Coda 2 on my Mac as my standard web editor, so that is what I am writing in now. I will probably experiment with other Markdown editors as I go. And for any Mac users out there working in Markdown, I highly recommend Brett Terpstra’s Markdown Service Tools.

Man Reader 1.4 Now Available

Permalink - Posted on 2014-04-03 00:00

Man Reader 1.4 is now available through the Mac App Store.

The new features and fixes are:

  • Fix for plain text view not wrapping correctly for odd-sized fonts.
  • Fix for HTML text view over-riding font colors that may be invisible.
  • Search for missing entry (e.g. g++) no longer requires Enter or Return.
  • Better automatic selection of matching entries while searching.
  • Fix for animation warning message appearing in Console.
  • Status display shows when man page list is being updated.
  • Searching inside a page now allows a minimum of 2 characters (was 3), so flags
    e.g. ‘-b’ do not need to be escaped.
  • Fixed path for Network Utility in tool bar (moved in OS X 10.9).
  • More information available about the effects of sand-boxing for this app.

Email clients for Mac and iOS

Permalink - Posted on 2014-03-25 00:00

Some people are moving away from email, but for me, it remains the best way to communicate online. I get to keep a record of conversations and the attached files are with the text so I can always see the context.

But I think everyone would agree that Apple have dropped the ball with Mail in OS X Mavericks, and to a lesser extent, in iOS 7.

So I have been on a campaign lately to find an email client that suits my needs. I don’t feel that I have found the perfect answer yet, but I am getting there.

The first step was to work out what I really needed in an email client:

  • support for IMAP accounts and Gmail accounts
  • unified inbox - all accounts shown together
  • conversation threading
  • support for POP accounts (optional)


On the Mac, I have narrowed it down to two clients that I am swapping between every few days: Unibox and Airmail.

Unibox is different in the way it displays your emails. It is much more focussed on people and conversations, so the side bar shows all the people who you have sent emails to or received emails from, grouped by date. I really like the merging of incoming & outgoing emails, but it can be a bit weird if you delete the latest email from someone who then disappears from sight.

Emails are grouped by a single person, not by conversation. There is a button on appropriate emails to toggle conversation view for that particular thread, but it doesn’t stick.

In order to show a conversation, they truncate emails in the main part of the window and show a “More” button at the bottom of the email to expand it. This was annoying, but in the latest beta, it performs much better, so you are not continually tapping this to see a long email.

Airmail has a more conventional display. Threading and the layout of threaded emails are both very nice. There are multiple view options, which I find can get a bit messy looking, so I prefer the “Minimized View” setting. Airmail also does POP accounts which is a plus.

The main reason I keep going back to Unibox is the unification. I have grown to like having sent and received messages all in the same window without having to go and find them somewhere else.


On the iPad, I am currently using Boxer and have tried numerous others. Molto was quite good and the interface was fun, but it would only use landscape mode and like to be able to swap. Boxer is not great in portrait mode, but it does work.

So the jury is still out for iPad email clients, but on the Mac, I am leaning towards Unibox.

Berio Sequenza VII

Permalink - Posted on 2013-11-07 00:00

So my latest app is way outside my usual sphere but that’s what happens when family decide that what you do might actually be useful!

My son is an oboist and he is currently learning Berio’s Sequenza VII for Oboe. This is a weird piece without a standard time signature. Instead each line has 13 bars with each bar being allocated a certain time span in actual seconds. As can easily be imagined, this makes learning and practicing this piece more of a mathematical exercise than a musical one.

So I wrote him an app to sound out the end of each bar. Once he and his teacher used it, a few more features crept in and now I think it will be of great assistance to any student or teacher trying to work on this piece.

While I doubt that many oboists frequent this web site, it anyone who does can pass this on to any oboist, I would be very grateful, and I think the oboist would be too!

The app is available through the iTunes App Store.
More details are on this page.

Icon Builder & iOS 7

Permalink - Posted on 2013-09-23 00:00

Icon Builder 1.2 was released on 18 September 2013.
It was an update with 2 new functions:

  • The ability to create images to suit an Xcode 5 assets library
  • The ability to create icons with the required sizes for IOS 7 apps.

Knowing that iOS 7 apps can only be built using Xcode 5, I linked the switch for these 2 abilities in a single check box.
The problem was not really that they were in a single checkbox but that I had labelled it badly, so it was not obvious that this was what needed to be checked to create iOS 7 sized icon files.

After some feedback from early users, it became clear to me that this was not enough. So 1.2.1 is now waiting for Apple’s approval.
The changes in this version are:

  • More informative labelling of the checkbox.
  • The checkbox is checked by default is Xcode 5 is installed

While waiting for the new version to be approved, please be aware that iOS 7 icon sizes will only be generated if you select “Check Assets (for Xcode 5.x or later)”

Icon apps updated

Permalink - Posted on 2013-09-19 00:00

Icns Maker and Icon Builder have both just been updated to support Xcode 5.

Icon Builder is a Mac app that takes your images and creates all the required icon files for use in your iOS apps.
It now supports Xcode 5’s image assets folders and if you are using Xcode 5, it will create the icon sizes required for iOS 7 app.

Icns Maker is a Mac app that takes your images and creates icons for use in your Mac apps.
For Xcode 4 or earlier, it creates a .icns file.
For Xcode 5, it creates a folder of images for use in your project’s image assets folder.


Permalink - Posted on 2013-04-01 00:00

For some time now, I have been aware of the increasing trend towards using Markdown for text editing and for creating HTML. Markdown has been on my list of “things I should learn some day” so I was interested last week to read about a new iBooks book called The MacSparky Markdown Field Guide. This was sufficient inspiration so I got the book and read through it this weekend.

The MacSparky Markdown Field Guide

Actually, to say that I read through the book is a mis-representation. The book was written using iBooks Author specially for the iPad and contains screen casts and interviews as well as text. But by the end of it, I now feel I have a basic understanding on Markdown and the ways in which I can use it.

I guess the really big thing about using Markdown is that is creates plain text files that are human-readable even without being converted to HTML. This makes them future-proof since they are not tied to a proprietary file format that may cease to exist at any time.

Using Markdown:

Since this web site is a self-hosted WordPress site, my next step was to look for a WordPress plugin that would allow me to use Markdown to create my posts. I could have used a Markdown editor that had HTML export, but I wanted to try something that would eliminate the extra step. The first one I decide to try was Markdown on Save Improved.

One of the main reasons for choosing this one was that it stores the posts as both Markdown and as HTML. This saves time when going back to edit a post, avoids the constant changes that creep in when converting between formats all the time, and makes it so that the post will still display correctly even if Markdown is no longer supported. The only problem I have found so far is that it doesn’t automatically create links & image links using the Markdown format, but uses standard <a> and <img> links instead.

My next stop, since I always use a Mac, was to get Brett Terpstra’s collection of Services for Markdown. These add a lot on convenient shortcuts: one of my favourites is the ability to convert inline links to references links for increased readability while editing.

First Impressions:

So having written this first post in Markdown, how do I feel about it? I haven’t really tried anything too weird this time, but there are a few things that were very easy to do. Particularly in the paragraph where I was talking about links & images and wanted to include the tags as text without having it interpreted as HTML. All I had to do was surround the text with back-ticks.

Links are vastly easier to manage and edit in Markdown. I miss the ability to specify that links should open in a new tab - I prefer to have that setting for links that take you outside my web site, but the modern theories on usability seem to be heading towards deprecation of this feature, so I may just stop using it.

With the standard WordPress editor, I always felt that I was fighting it. I had to swap between the visual & HTML editor tabs and when I swapped tabs, things would sometimes change without me doing anything. So far, I feel more in control using Markdown and although I have lost the WYSIWYG visual editor, I no longer have to wade through the HTML editor to get the effect I want or to remove the results of a few careless clicks.

What next?

Some of the things on my wish list would be solved by a better editor and some by more powerful syntax.


  • Adding links & images using Markdown style instead of HTML
  • Being able to create lists
    • Markdown makes this very easy but this WP plugin does not support lists as far as I can tell
    • So these lists are in HTML


  • Alignment of text & images

Using a stand-alone Markdown editor would solve the editor questions, but I wanted to try writing this post completely in WordPress.
And with the alignment, there is nothing to stop me adding CSS to the Markdown.

Next time, I will test out a different WordPress Markdown editor and see how that goes. I will also test using a standalone editor and exporting its HTML to create a post.

A Knight's Move 1.3

Permalink - Posted on 2013-02-27 00:00

UPDATE: September 2016 - A Knight’s Move for iOS is no longer available. A Knight’s Move for Mac is still supported.

A Knight’s Move has been updated to version 1.3. The Mac version is available through the Mac App Store.

Three new level packs:

  • Eight by Eight
  • Bishops Rule
  • Castles

Eight by Eight has every puzzle set in a chessboard sized grid with more conventional placing of pieces.
Bishops Rule has at least one Bishop in every puzzle.
Castles has a Castle or Rook in every puzzle and is suited to players who would like more of a challenge.

New feature:

When your knight has been taken, you have the option to undo the last move so you can try again without losing the moves you have already made.

Man Reader (no SB)

Permalink - Posted on 2013-02-06 00:00

These instructions are no longer valid. As of version 1.5, the App Store version of Man Reader has solved the sand-boxing issues and is now as powerful as the non-sand-boxed version.

The non-sand-boxed version will no longer be supported or updated, so please revert to the App Store version.

If you find that Man Reader is not working well for you due to Apple’s sandboxing restrictions, then you can download a non-sandboxed version here. To find out more about this, including how to test if you are affected, read the Sand-Boxing Man Reader page.

The non-sandboxed version will only work if you have the App Store version of Man Reader already installed.

When you run ‘Man Reader (no SB)’ for the first time, it will check to see if you have a valid installation of ‘Man Reader’ that you have purchased from the App Store.
If you do not, ‘Man Reader (no SB)’ will offer to take you to the App Store and then quit.

If you already own the App Store version of Man Reader and ‘Man Reader (no SB)’ has started once, you can delete the App Store version and ‘Man Reader (no SB)’ will keep working.

To install ‘Man Reader (no SB)’, click the download link below. This will download ‘ManReader-noSB.zip’. Double-click on this file to un-zip it, and then move the ‘Man Reader (no SB).app’ into your Applications folder and use as normal. Do not delete the App Store version of Man Reader until ‘Man Reader (no SB)’ has been run at least once.

Download Man Reader (no SB)

I found out today (thanks Ron) that under OS X 10.10.3 the security settings no longer allow the downloaded version of Man Reader (no SB) to run, despite the fact that I have signed it with my Apple Developer ID. OS X gives a very un-helpful dialog reporting that the app is damaged. In fact the app is fine, but being blocked by the security settings. The solution as shown at TechRecipes is to change your security system preferences to allow downloaded apps from anywhere. You only need to do this temporarily as after you have run the app once you can set this setting back to whatever you had before.

Sand-Boxing Man Reader

Permalink - Posted on 2013-02-06 00:00

These instructions are no longer valid. As of version 1.5, the App Store version of Man Reader has solved the sand-boxing issues and is now as powerful as the non-sand-boxed version.

The non-sand-boxed version will no longer be supported or updated, so please revert to the App Store version.

As with all apps in the App Store, Man Reader is restricted by Apple’s sand-boxing policy. Sand-boxing is a great thing. It isolates apps from each other and from the system, making it far less likely that a problem app will cause wide-spread havoc. However for an app like Man Reader, this can lead to a drop in functionality.

Due to the permissions limitations of sand-boxing, Man Reader can only search defined paths on your system drive e.g. /usr/, /opt/
This is where the default man pages are all stored, but if you install other software (Xcode is a good example), then Man Reader may not be able to list all the available man pages on your system.

To tell if Man Reader is missing man pages, copy & paste the following command into the Terminal app:

whatis . >> ~/Desktop/whatis.txt

Man Reader runs this command internally when it starts, but the Terminal app is not sand-boxed and so can access everything.
Running this command will create a text file on your desktop with a list of all available man pages on your system. Open it in a text editor that can show the number of lines in a file. TextWrangler from Bare Bones Software is a good free editor that will do this.

To check what man pages ManReader can read, go to Finder and select ‘Go to Folder…" from the Go menu. Paste in the following path:

~/Library/Containers/net.troz.Man-Reader/Data/Library/Application Support/Man Reader/

You will see two files: open the one called ‘ManReader.raw’ in your text editor. This is the result of Man Reader running the whatis command. Compare the number of lines in the two files. Don’t worry about the order of the items in the file as that may vary, you are only concerned with the total number of lines in each.

There may be one or two lines more in the whatis.txt file but if there is a big difference, then you are being sand-boxed…
As an example, on my system, the whatis.txt file contains 8954 lines and the ManReader.raw file contains 2320 lines!

If you are affected by this or think that you might be, I now have a solution - actually two possible solutions:

If you have already bought Man Reader from the App Store, then you can download a non-sandboxed version. This will only work if you have the App Store version of the app installed.

If you do not already own a copy of Man Reader, and want to buy it un-sandboxed, then you can now buy it directly.

Please contact me if you have any issues with this.

Icns Maker & Icon Builder updated

Permalink - Posted on 2013-01-19 00:00

January 18th 2013:

Both of the icon building apps have now been updated to fix a but that made incorrect icon sizes when running on a Retina MacBook Pro.

Icns Maker uses your image to create an icns file for Mac apps.

Icon Builder uses your image to create the suite of icon files needed for iOS apps.

Icon Makers & Retina Macs

Permalink - Posted on 2013-01-14 00:00

Icns Maker which makes an icns icon file for Mac apps, and Icon Builder which makes the suite of png files needed for iOS apps, are both compatible with the Retina MacBook Pro.

However it was recently brought to my attention (thanks Cameron), that when running on a Retina MBP, all the icon files were exactly twice as large as they should be. The Icon.png file which supplies the main app icon for iPhone apps should be 57 pixels by 57 pixels. Using Icon Builder on a Retina MBP produced an Icon.png file that was 114 x 114 pixels.

I have now worked out how to persuade the Retina Mac that when I ask for an image size, I actually want that size, not the size that OS X thinks would look better. Updates to these 2 apps will be submitted to the App Store for approval later today which will solve the problem.

In the meantime, there is a work-around for Retina MBP users: force the app to run in low resolution mode.

In Finder, open your Applications folder and select the app (this works for both Icns Maker and Icon Builder). Press Command-I or choose Get Info from the File menu which will open a window like this:

Check the checkbox labelled “Open in Low Resolution”. Next time the app is opened, it will ignore the Retina options and use standard resolution only. This will create icon files with the correct sizes. However text may look slightly fuzzy.

When the updates to these apps become available, make sure you go back and un-check this setting to return to Retina mode.

A Knight's Move updates

Permalink - Posted on 2012-10-15 00:00

UPDATE: September 2016 - A Knight’s Move for iOS is no longer available. A Knight’s Move for Mac is still supported.

A Knight’s Move for iOS has been updated to take advantage of the taller iPhone 5 screen.

In-app purchasing of packs has been removed from both Mac & iOS versions.
For iOS, the app is now free but supported by iAds (please click through if you would like to show your support).
Apple does not have an ad system for Mac, so the Mac version is now a paid app that includes all the puzzle packs.

The in-app purchasing was an interesting experiment, but the ratio of purchases to downloads was too low to sustain the development.

App Store Review Times

Permalink - Posted on 2012-10-15 00:00

There are been a lots of stories going around about lengthening Mac App Store review times. Shiny Developments crowd-sourced data certainly backs this up although they have much more data for iOS apps than for Mac apps.

Some people, including Lex Friedman of MacWorld and John Gruber of Daring Fireball, are suggesting that the delays are due to the rush of new apps to support the iPhone 5 and iOS 6. This implies that there is only one set of review staff and that a large proportion of them have been moved from Mac to iOS apps.

I think this is an incorrect analysis. The slowdown started before iOS 6 and before the iPhone 5. I think it started in June when Apple started to enforce Mac sandboxing.

As discussed in a previous post, I have had a lot of trouble getting Man Reader to be sandbox-compatible leading to many rejections. One problem was that I had implemented sand-boxing before the deadline, but with some temporary entitlements to allow read-only access to required system files. This entitlement was approved initially, but after one rejection, an Apple reviewer told me that they had been approving all requested entitlements before the deadline, but now were actually reviewing them all.

To me, this seems like a rather silly thing to have done which has now returned to haunt them. Instead of allowing developers time to get used to the restrictions, Apple reviewers allowed developers to think that their apps were sandbox-complient already. Then Apple was faced with the enormous task of re-checking all the entitlements that they had previously allowed without checking. This was unfair to developers and has only created extra work for the reviewers.

Here is a table showing the recent review times for my Mac apps:

App Process Review days Dates
Time In Words update 22 Sept 22 - Oct 14
Icns Maker new app 24 Aug 5 - Aug 29
A Knight’s Move update 26 Sept 6 - Oct 2
Icon Builder new app 33 Aug 22 - Sept 24

By comparison, when I submitted an update to A Knight’s Move for iOS in October, it was passed in only 8 days.

Icon makers for Mac & iOS apps

Permalink - Posted on 2012-10-15 00:00

Announcing two new apps for creating icons for with Mac or iOS projects:

Icns Maker helps you convert a single image into a .icns file in two steps.
Icon Builder creates all the files needed to set up your icons for any iOS project.

Creating icon files for Mac apps:

In versions of Xcode before 4.4, Apple provided an app called “Icon Composer”. It allowed you to drag images into a window and export a .icns file for use in your Mac apps. With Xcode 4.4, Apple has changed the way icons are handled for Mac apps and “Icon Composer” is no longer supplied.

The Xcode docs describe the process you need to go through to make a .icns file: create a suite of image files of the correct size and with the correct file names, bundle them into a specially named folder and then use Terminal to stitch them together.

Icns Maker does all this for you in two easy steps.

  1. Drag in an image file (preferably 1024x1024 but 512x512 will also work).
  2. Click a button.

There are more options available for fine-tuning your icons allowing you to select different images for the various sizes, but this is all that is needed for basic operation.

Icns Maker is available from the Mac App Store.

Creating icon files for iOS apps:

Icons for iOS apps are not bundled into a single file like a Mac .icns file. You add various .png images to your project. Depending on the devices supported by your app, you will need many different sizes of icon file. There are some icons for iPad only, some for iPhone / iPod Touch only and others required for any device. Additionally, you will need larger versions of each image to support Retina displays.

Icon Builder is a Mac app that does all this for you. As with Icns Maker, you just drag your image into the app and click a button. You can also select which devices your icon needs to suit and use different images for the different sizes if you want finer control.

When the app creates your icon files, it generates a ReadMe file with the information needed for installing these files in your project, including information to copy & paste directly into your Info.plist file.

Icon Builder is available from the Mac App Store.
Note that although this app builds icon files for iOS app, it runs on a Mac.


Originally these apps were named in a consistent manner: Mac Icon Builder and iOS Icon Builder. However both these names were rejected by Apple - you are not allowed to use the words “Mac” or “iOS” in any app name sold through the Mac App Store.

Then I tried Icns Maker and Icon Maker. Icns Maker was approved, but there is already an app called Icon Maker, so I went with Icon Builder. But by that time Icns Maker had already been released, so there was no way to make the names more consistent.

Updating apps for iPhone 5

Permalink - Posted on 2012-09-24 00:00

I have started work updating my iOS apps to fill the larger screen of an iPhone

  1. My iPhone 5 is on order - I missed out on the first shipment, but hopefully it won’t be too long. Meanwhile, I will just test in the iPhone Simulator and hope this is OK.

But it was a puzzle to me how to get an app to fill the longer screen. I have the latest Xcode and the latest Simulator which allows you to specify what screen size iPhone to simulate. So I re-built an app and nothing changed - it showing black strips top & bottom and left my app at the old size.

After trying many different things and reading a lot of the new sections of the Apple developer documentation, I finally found the answer online:

Apparently the system uses the presence or absence of this file this to detect whether your app supports the longer iPhone.

I read that Xcode is supposed to warn you of the consequences if this file is missing, but in my case, when I opened my project, Xcode helpfully used the old launch image in its place. It showed a warning icon that the image was the wrong size, but nothing else.

The next problem was how to create this file. I use screen shots, but until the app worked in the correct format, I wasn’t going to be able to get the screen shot. So I made it a 2 step process: first I duplicated the original launch image, renamed it and resized it. It looked wrong but this was irrelevant - it was enough to get the app working in the correct format. Once I had the app working, I was able to take a screen shot and create the final launch image.

Once you have the app working in 2 sizes, you have to do more work with the layout, either using springs & struts or using the modern auto-layout feature. I find auto-layout confusing, but it is obviously more powerful and the way of the future, so I am trying to work it out. I found a good tutorial at Ray Wenderlich’s site. While directed at iOS 6, it also applies to Mac apps.

A Knight's Move for iOS 1.1

Permalink - Posted on 2012-09-13 00:00

UPDATE: September 2016 - A Knight’s Move for iOS is no longer available. A Knight’s Move for Mac is still supported.

A Knight’s Move for iPad & iPhone has just been updated to version 1.1

There were some minor changes:

  • New puzzle pack: Majestic.
  • iPhone now shows an info button of there is more help available for a particular puzzle. (This info was already visible in the iPad version.)
  • Minor cosmetic fixes.

The big change was that all puzzles packs are now included in the free app, which is now supported by iAds. The sale of puzzle packs via in-app purchasing was disappointing, so I have decided to try using iAds instead. Hopefully they will not feel too intrusive, but if you want to support my apps, please tap on a few of the ads.

Note that iAds will not appear in all countries. You may just see a banner linking you to my other apps on the iPad. On iPhone, you will not see anything different.

Man Reader 1.1 Released

Permalink - Posted on 2012-08-14 00:00

The update of Man Reader to version 1.1 has just become available through the Mac App Store. This update has a bunch of new features - thanks to everyone who made suggestions.

As detailed in a previous post, there have been major issues getting this app approved with Apple’s new sand-boxing restrictions fully in place. But to their credit, the Apple reviewers have been unfailing helpful and polite in answering my questions and keeping me informed.

I hope everyone finds the new features useful. Please keep the suggestions coming in to make this app even better!

Sandboxing and the Mac App Store

Permalink - Posted on 2012-07-28 00:00

As of June 2012, all apps submitted to the Mac App Store have to be sandboxed i.e. they have to be able to run in a limited environment where they cannot interfere with other apps or other parts of the system. While this is generally a good thing, there are problems when apps have legitimate reasons for requiring access to other resources.

One annoyance for developers is that Apple’s apps are mostly not sandboxed. To check what apps you have installed that are sandboxed, open up Activity Monitor (in Applications/Utilities). In the View menu, check that Sandbox is checked in the Columns submenu. Then you can sort by clicking on the Sandbox title and work out which apps are already sandboxed. Mail, Preview and Text Edit are now sandboxed and so is the new Reminders app, but as far as I can tell, no other Apple apps are. This causes two problems: firstly it is not fair to other developers if Apple is enforcing a standard which only they are allowed to break. Secondly, if Apple developers had to follow the same rules as everyone else, then maybe the system would evolve to become more usable for everyone.

In the Apple developer documentation about sandboxing, there is a section headed “Determine Whether Your App Is Suitable for Sandboxing”. Here they list numerous reasons why any app might not work in the sandbox. But the Mac App Store now makes sandboxing compulsory, so what to do with apps that are not suitable?

Some resources can be requested when building the app: access to various folders (Pictures, Music, Downloads etc), access to Address Book and Calendar data, printing facilities, networking etc. Beyond the specified list of entitlements that can be requested, developers can also apply for “temporary entitlements” which, if granted, will unlock access to other parts of the operating system. However these are subject to the whims of app reviewers and will be re-assessed with every update. Apple has also made it clear that they are intended as a transition feature and will not be available for ever.

This has lead to a recent spate of popular apps leaving the App Store. Marco Arment has discussed this problem with an emphasis on the issue of lack of confidence in buying from the App Store. If you cannot be sure that an app you buy will remain in the App Store, then you are less likely to buy it there.

I have run into direct issues with sandboxing already. With Pic-a-POD, I used to have links to the Desktop and Screen Saver panes in System Preferences. These used AppleScripts which required a temporary entitlement to send an AppleEvent. The app was rejected because of this, so I had to modify this feature - it now just takes you to the relevant section of System Prefs, but not directly to either Desktop or Screen Saver. However Pic-a-POD’s help, which runs in Apple’s Help Viewer app, contains exactly the same AppleScripts and so is allowed to access these preference panes directly. Try working out the logic of that one!

I have more serious problems with Man Reader. Man Reader displays a list of the man pages on your system. Depending on the tools you have installed, these pages may be in a variety of locations. The shell command that detects them first reads a config file and then checks the folders listed in that config file. All it needs is read-only access. With the first sandboxed version, I asked for a temporary entitlement to give me read-only access to the startup disk. This was granted, but I have since been informed that all requested entitlements were granted before the App Store cut-off date. This may have been meant to be helpful, but it was not useful to allow access that would later be removed without any warning.

The current version of Man Reader waiting for approval asks for read-only access to the config file directly and then to every folder listed in that config file. If approved, this should be able to access all the man pages on a system. I have no idea whether these entitlements will be granted, but if not, then I will have to remove Man Reader from the App Store. It would be wrong to continue to sell an app that only functioned in a limited manner, even though the App Store is far and away my best form of marketing.

So what do I suggest Apple does? I think they need to allow apps that are not sand-boxed. However these apps could come with a warning before installation. In Mountain Lion, the new security feature called Gatekeeper allows you to specify the level of security you want when installing apps. Currently the options are to allow apps downloaded from:

  • Mac App Store
  • Mac App Store and identified developers
  • Anywhere

They could split the first option in two and allow

  • Mac App Store sandboxed
  • Mac App Store any

One further wrinkle is iCloud. Apple is encouraging users and developers towards iCloud data storage and sharing. But only apps in the App Store are allowed to use iCloud.

So it will be interesting to see how this plays out. Obviously Apple is not going to care if a tiny developer like me leaves the App Store, but if enough high-profile developers leave, then there will surely be some consideration given to the problem.

Update to Time In Words screen saver

Permalink - Posted on 2012-07-27 00:00

Time In Words screen saver has just been updated to version 1.1 and is now fully compatible with Mountain Lion. It is free to use and can be downloaded here.

The basic screen saver worked before, but searching for an alternative time zone would crash System Preferences. That is now fixed.

The screen saver also shows a thumbnail image when in Mountain Lion and is code-signed with my developer ID for compatibility with Mountain Lion’s Gatekeeper.

The current version is compatible with 10.8 and 10.7. It may work in 10.6 but I cannot be sure. If anyone tries it, please let me know.

A Knight's Move Released

Permalink - Posted on 2012-07-09 00:00

UPDATE: September 2016 - A Knight’s Move for iOS is no longer available. A Knight’s Move for Mac is still supported.

“A Knight’s Move” is a fun, addictive and simple puzzle game based on the movements of chess pieces. Your goal is to move your white knight across a board to a target square using the same movements as a knight in chess. Pawns may block your way, while enemy bishops, castles, knights and the queen may try to stop you.

The game is available for iPad, iPhone and iPod Touch from the iTunes Store and requires iOS 5.0 or later. The Mac version is available from the Mac App Store and requires OS X 10.7 or later.

Perfect for when you have a few minutes to relax, like on the train to work, during your lunch break or during a boring lecture or class (Kids: don’t take advice from randoms, but you can turn the sound FX off. Just sayin’), “A Knight’s Move” will keep you coming back for “Just One More Go”!

Once you have played the tutorial pack, you can move on to the other puzzle packs. Each pack comes with 25 more puzzles and there are many different packs allowing you to select easy puzzles, challenging puzzles or variety packs, some with themes.

See more about “A Knight’s Move” at the Knight’s Move web page

Get the game from the Mac App Store.

Tutorial puzzle on iPhone

Pesky Pawns - one of the more difficult puzzles on Mac.

Easy access to the Library folder

Permalink - Posted on 2012-05-16 00:00

In Mac OS X 10.7 (Lion), Apple decided to make it more difficult to access your Library folder, presumably to stop people doing stuff that made apps crash. But as a developer, I need access to my Library folder a lot. I need to check that preferences are being saved correctly. If I have an app that uses the Application Support folder, then I need to be able to check it. And for sand-boxed apps, they keep all their data in the Containers folder inside the Library.

You can easily get to the Library folder by holding down the Option key while choosing the Go menu in Finder. This adds Library to the menu and you can get to the folder that way. But this is not as convenient as single-click access from a Finder window, so here is my preferred method.

Use the Option key and the Finder’s Go menu to get the Library folder open in a Finder window. Switch this window to column view, which will display the Library folder (slightly greyed out) in the first column. Drag this Library folder to the side bar of your Finder window. Now it is there all the time, in every Finder window that is showing the side bar.

I have read about various Terminal tricks to get the Library to show up, but every system update seems to turn it off again. This technique doesn’t involve anything except the Finder’s side bar preferences and so far (I’m now up to 10.7.4), it hasn’t needed to be reset after any update.

Man Reader update coming soon

Permalink - Posted on 2012-05-11 00:00

Man Reader launched on the Mac App Store a couple of days ago and yesterday I got an email from a purchaser who reported that Man Reader was not displaying the man pages for MacPorts, even though he had the paths set up correctly.

I installed MacPorts to check this out and ran into the same problem. Running the command “man port” in Terminal worked fine, but “port” did not appear in Man Reader’s list.

Man Reader uses the “apropos” command to list all available man pages, so I tested it next. When I found that it was not listing “port” either, I thought I had discovered the problem. OS X offers two commands for searching for man pages: apropos & whatis. The database files used by these commands are updated weekly by one of the periodic system commands. I manually ran this update command using:

sudo /etc/periodic/weekly/320.whatis

This did part of the job, as the apropos command when used in Terminal now contained the MacPorts man pages. However Man Reader still did not show these man pages.

Reverting to the Console log, I found that this was a sand-boxing problem. The Mac OS X sand-box was preventing access to the man.conf file (which tells where to look for man pages), and the whatis database file containing the new data. I assume that without access to these files, the default locations for man pages were still searched, but no non-standard locations were being searched.

I have just submitted an update to the App Store that still uses sand-boxing but requests temporary read-only access to the file system to read these files. If Apple rejects this, then I will release a version without sand-boxing.

Either way, you can be assured that the matter is being dealt with and the next update, whether sand-boxed or not, will allow access to all man pages.

Pic-a-POD 2.0.4 for Mac

Permalink - Posted on 2012-05-11 00:00

The latest update for Pic-a-POD for Mac is now available through the Mac App Store.

Bug fix:

  • selecting an iPhoto pic from the Recent Desktops menu now works correctly.

New features:

  • Better indication of downloads and when large pics are not yet available
  • Direct link to App Store in Help menu - please rate or review.

Making a Mac Screen Saver

Permalink - Posted on 2012-05-09 00:00

Having just completed the my first screen saver for Mac - the Time In Words Screen Saver, I thought I would share some of the experiences. I am using OS X Lion (10.7) and Xcode 4.3.2

The first thing is to create a new project in Xcode using the Screen Saver template:

Xcode sets up a project for you with everything you need for a screen saver module. Start editing the ScreenSaverView.m file. The most important method here is animateOneFrame.

This is called every time the animation time interval elapses. This interval is set in initWithFrame:isPreview:. I have seen some debate online as to whether the drawing should be done in the animateOneFrame method or in the drawRect method. I chose to use animateOneFrame because they are both called when the screen saver starts which can lead to an unpleasant flicker.

Now it is up to you to decide what to show in the animateOneFrame method. For Time In Words, I assembled the data as a string, created a dictionary of text attributes, calculated the location where I wanted to show the text and used drawAtPoint:withAttributes: to display it.

There are a couple of important tricks when working out locations: firstly, you will need to know the bounds of the screen saver area. This will vary depending on the monitor, screen size or whether the screen saver is appearing in the preview window in System Preferences. The screen saver view has a method that does this work for you.

NSRect viewBounds = [self bounds];

The next trick is that you are most likely going to need some random numbers. Again, the screen saver framework supplies these to you in several forms. I used SSRandomFloatBetween but there are others. Check the documentation.

I ran into an oddity in System Preferences that made testing a bit tedious. I built the screen saver module and double-clicked on it to install into System Preferences. That worked fine, but when I made some changes and repeated the process, the original screen saver was still in place. I found that I had to quit System Preferences each time. Deleting the old version of the screen saver was not necessary, but quitting the System Prefs app was essential.

So that gives the basic screen saver module but with no options. Adding options is not difficult, but as always, there are a few things that are not obvious on first glance.

Add a xib file to your project: I used a window template. Then change the window’s class to NSPanel and configure it as shown:

Set the File’s Owner class to the class of your Screen Saver view. In your ScreenSaverView.h file, declare a property for this new panel. e.g.

 @property (assign) IBOutlet NSPanel *optionsPanel;

@synthesize this in the ScreenSaverView.m file. In the xib file, connect the panel to this outlet.

Now go back to ScreenSaverView.m and add the following code:

* (BOOL)hasConfigureSheet { return YES; }

* (NSWindow *)configureSheet { if (!self.optionsPanel) { [NSBundle
  loadNibNamed:@"Options" owner:self]; } return self.optionsPanel; }

- (IBAction)closeConfig:(id)sender { [[NSApplication sharedApplication]
  endSheet:self.optionsPanel]; }

The hasConfigureSheet and configureSheet stubs are already there for you, but you can replace them with these versions.

Go back to the xib file and drag in a button to close the options panel. Connect it to the closeConfig: action.

Save everything, build, install in System Preferences and test. Firstly, the “Options…” button should be enabled. Clicking it should open your panel as a sheet, and when you click your button, the panel should close.

If that doesn’t work, check the class assignments, the connections, the settings for the NSPanel and the code in that order.

Once the panel is opening and closing as required, you need to add the ability to store and retrieve the settings. Instead of using NSUserDefaults as you would in a standard Mac app, there is a special class call ScreenSaverDefaults for screen savers. It needs a unique module name, so I used the bundle identifier. For my Time In Words screen saver, this is “net.troz.Time-In-Words-Screen-Saver”. I defined a constant to hold this as a string, so I could use it anywhere I needed.

In the initWithFrame:isPreview: method, I got a reference to the screen saver defaults for my screen saver and registered the defaults. I am never very sure about the need to do this, but it is supposed to be a good practice.

ScreenSaverDefaults *defaults = [ScreenSaverDefaults defaultsForModuleWithName:kModuleName];
[defaults registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
  @"NO", @"UseAlternativeZone", @"",
  @"AlternativeZoneName", nil]

Using them is exactly the same as using NSUserDefaults:

// Reading
ScreenSaverDefaults *defaults = [ScreenSaverDefaults defaultsForModuleWithName:kModuleName];
BOOL useAlternativeZone = [defaults boolForKey:@"UseAlternativeZone"];
NSString *alternativeZoneName = [defaults objectForKey:@"AlternativeZoneName"];

// Writing
ScreenSaverDefaults *defaults = [ScreenSaverDefaults defaultsForModuleWithName:kModuleName]; [defaults setBool:useAlternative forKey:@"UseAlternativeZone"];
[defaults setObject:alternativeZoneName forKey:@"AlternativeZoneName"];
[defaults synchronize];

One last thing: if you want to distribute the screen saver, you will want to create an archive, possibly code-signing with your Apple developer ID to allow for Mountain Lion’s up-coming Gatekeeper security system. I code-signed the project and built an archive, but when I clicked “Distribute” in the Organizer, the only appropriate options was “Save Built Products”. I selected this option and ended up with a series of folders inside folders, with the screen saver module in about the fifth folder down. I don’t know why the module gets distributed like this, but I pulled it out of the folders and it worked fine.

And that’s about it. A lot of this stuff is online or in Apple’s documentation, but there are enough oddities to make it worthwhile gathering together all that I learnt while making this screen saver.

Click this icon to download the screen saver:

Support for older operating systems

Permalink - Posted on 2012-05-02 00:00

Working out what operating systems to support in your software is always a difficult decision. I only program for Mac & iOS systems for starters. This is because they are the systems I use and understand. I am not interested in expending the time & money needed to program and test my software for other systems.

Within the Mac & iOS ecosystems, there is still the decision of which versions to support. Partially, this is based on the usage statistics of each version. I found a site that segments the current Mac market: Distribution of Mac OS X versions. This tells me that OS 10.6 & OS 10.7 between them have 83% which makes 10.6 a good cut-off point.

Distribution of iOS versions is harder to discover, but I found a post that did a good job of analysing the statistics that are available:

pxldot (iOS Ebb and Flow). According to this post, by March 2012, iOS had about 75% with the remainder being almost exclusively iOS 4.

So based on statistics alone, it makes sense to support Mac OS X 10.6 or later and iOS 4 and later. However this doesn’t cover all the relevant issues. Another important factor is new techniques and APIs introduced in Apple’s developer tools.

In iOS 4, Apple gave us ARC - Automatic Reference Counting - which basically removes the tedious job of memory management. This was especially painful in iOS apps where there is no garbage collection. The Long Weekend Website has an excellent summary of ARC - what it is and how to use it. Since this only excludes iOS 3 or earlier, there is no issue using this for all iOS projects.

But now Apple has extended ARC to Mac apps as well, but only for apps built to run under 10.7 or later. Even though Mac apps could use garbage collection to remove some of the burden of memory management, this had its own inefficiencies and overheads. So in my case, I have decided that all future apps will require 10.7 to take advantage of ARC. Existing apps will stay as is - requiring 10.6 or later. With 10.8 not that far away, the usage statistics should follow this trend.

Back to iOS, there is another new feature of Xcode that is really too attractive to ignore and that is story-boarding. This is a graphical way of laying out the navigation logic for your app and providing segues between different views. Ray Wenderlich has a good introduction to storyboards. So this means that my future iOS apps will all require 10.5 or later.

One final factor is testing. You really need to have a device running each version of any supported operating system. I would rather concentrate on getting the best result for users of the latest versions that spend my time tweaking for older systems. With iOS, Apple makes it amazingly easy to update to the latest version. With Macs it costs money which is always a barrier, but technically, the App Store is making updates easier to apply.

Time In Words & the new iPad

Permalink - Posted on 2012-04-10 00:00

The new iPad has a Retina display, meaning that the pixel density is much greater. For some apps, this is a problem as their graphics are now scaled and look pixellated. However Time In Words is very simple. It uses standard fonts and interface widgets with no images or external graphics apart from the icon. The icon may not look perfect on a new iPad, but the display itself should look really great.

I had a report from one user that Time In Words will not work at all on his new iPad. Unfortunately, the email address supplied did not work, so I was unable to contact this person directly. If you are reading this, please contact me again.

The person having the problem did not specify exactly what the problem was, so I don’t know if the app will not start, or if it is not displaying correctly, or if it is showing the wrong times or what.

However I suggested two things to try, and I will list them now in case anyone else is having issues:

  1. Try deleting the app from your iPad and then re-installing from the App Store.
  2. Do a complete reboot of your iPad in case it is running low on memory.

Hopefully one or both of these ideas will solve any problems. They are both good general tricks to try with any problem app.

iPhone 4 Home Button

Permalink - Posted on 2012-03-28 00:00

My iPhone 4 is now 18 months old, and it’s Home button is starting to feel the strain. These buttons have been used much more than originally intended, with the new multitasking required double-presses, not to mention access to the camera etc. So basically , it is wearing out.

The phone is out of warranty and there is no way I am going to pay for an expensive repair when my current phone contract will expire later this year, and hopefully the iPhone 5 will be ready for me then. And a cheap repair or DIY is too risky.

I saw a post comparing the physical structure of the home buttons on iPhone 4 & 4S. Unfortunately I cannot find the link now, but it showed that the actual hardware has been made a lot more robust since the iPhone 4 was released, so this should only be a short term issue.

I read a article suggesting the use of WD-40 for a mis-behaving Home button. This is a TERRIBLE idea! Do not spray a penetrating oil into your expensive electronic device. For starters, it don’t believe it is a friction problem - I think the mechanism is just wearing out.

Some people recommend recalibrating the Home button as shown in this post from idownloadblog.com. I am a bit sceptical about this. I tried it, but I can’t see that it did anything. Maybe if your problem is software rather than hardware, then it will do some good. Anyway, unlike the WD-40 trick, it can’t do any harm.

Finally, on to the workaround. If your iPhone button is really unreliable, but you are not ready to repair or upgrade, then you can use the Accessibility tools to get a software Home button on the screen.

Go to Settings - General - Accessibility. Scroll down to “Physical & Motor”. Turn on AssistiveTouch.

When you back out of Settings, you will see a white blob somewhere on your screen. This can be dragged to any location around the edge of the screen, so you can always move it out of the way in any app.

Tapping on the white blob gives you an overlay view with four options, one of which is Home. Tapping this is exactly the same as pressing the physical Home button. So with this and the power button, you can do everything, even if the Home button stops working completely.

Thanks to Tom at our local Apple Store (Robina, Queensland, Australia) for this tip.

Time In Words for Mac now available

Permalink - Posted on 2012-03-20 00:00

Time In Words for Mac has just been approved and is now available for free from the Mac App Store.

For more details, check out the Time In Words for Mac web page.

Interface options for selecting time zones

Permalink - Posted on 2012-02-25 00:00

As part of the design for [Time In Words for Mac][1], I had to work out the interface for selecting time zones. With [Time In Word for iOS][2], I used picker wheels which are excellent for selecting hierarchical data. On the Mac, there is no such thing as the iOS picker wheel and so I had to consider what to use instead.

When you ask the system (Mac or iOS) for the available time zones, you get a list of names like this:




This seems obviously designed for a hierarchical display with the major regions as a first selection, filtering down to the cities in that region, making selection a two-step process. With the picker wheel in iOS, that is what I did. The first wheel selects the region which then populates the second wheel with the relevant city names. It makes it quick and easy to select a zone.

I always prefer to use standard user interface objects because people are familiar with them, they automatically update with the system, and there is much less chance of the App Store rejecting the app. So I scrolled through the available Mac options and came to NSBrowser. This is basically what Finder uses when in column mode.

I created an NSBrowser object, worked out a way to populate it and tested. It was incredibly slow! The list of regions appeared when the window opened, and that was no problem. Then I clicked a region and the first set of city names appeared instantly. But subsequent selections took about 3 seconds to appear.

I added some timing tests and my data gathering was taking about 20 milliseconds. The log thought the browser had updated within about 100 milliseconds, so I guess the rest of the time was some redraw issue.

Apple provides a large number of sample projects so I downloaded one that used NSBrowser. It seemed fast and responsive, so I duplicated it’s different method of assembling the data and tried again. No luck - it was as slow as before.

I am sure that if I kept at it, I would eventually work out what was causing the bottleneck and make NSBrowser work - after all, Finder is responsive enough, even if not great. But in the end, I decided that the advantages to using this form of interface didn’t justify the time spent, so I went with a simple table and a search field.

It is fast to populate, responsive to searches and didn’t take long to set up. So I am happy, although still perplexed about NSBrowser. It is on my to-do list of things I want to work out one day.

[1]: /time-in-words-for-mac/ [2]: /time-in-words/

Scroll bars in Mac OX 10.6 and 10.7

Permalink - Posted on 2012-02-25 00:00

With the introduction of OS X 10.7 (Lion), Apple removed the obvious scroll bars from windows and replaced them with a much more subtle scroll indicator, that only appears when you are actually scrolling. This was designed to match the iOS scrolling, as was the swap of scroll direction which makes much more sense if you use a trackpad.

With the upcoming Time In Words for Mac, I have a Preferences window to allow selection of time zones to display in the menu. The app will be compatible with 10.6 or later. Under 10.6, the scrollbars are always visible and this is what the Preferences display looks like:

This may change, but the basic layout is there. As you can see, I have a 3-column table listing all the available time zones, with the final column right justified.

Under 10.7, this doesn’t quite work:

I had to grab this screen shot quickly after swiping the trackpad, but you can see the problem. When not scrolling, the scroll indicator is hidden and the right column is fully visible, but when dragging the scroll indicator appears on top of the right-justified entries in that column.

So now I am not quite sure what to do. Here are the options I have considered:

  • Left or centre-justify the text in the final column.
  • Add some spacing at the end of each line so that the scroll indicator appears in blank space.
  • Put up with it.

I will have to experiment with various options and see what I can do.

Time In Words available in the App Store

Permalink - Posted on 2012-02-09 00:00

Time In Words is now available at the App Store.

Time In Words is a clock and calendar app that takes you out of the digital era and back to when saying “quarter to seven” or “five past two” was accurate enough.

Check out the Time In Words web page for more info and screen shots.