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

CURRENT FEED

TrozWare

macOS, iOS and watchOS Developer

A feed by Sarah Reichelt

JSON


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]) {
        guard
            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]) {
            guard
                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]) {
                guard
                    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]) {
            guard
                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)
        }
        users.count
        dump(users.first)
    }
}

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)

users?.count
dump(users?.first)

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:

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) {
            print(jsonString)
        }
    }
}

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)
dump(person)

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)

dump(project)

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) {
        print(jsonString)
    }
}

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)
dump(roles)

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) {
        print(jsonString)
    }
}

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) {
        print(plistString)
    }

    let plistDecoder = PropertyListDecoder()
    let project2 = try? plistDecoder.decode(Project.self, from: plist)

    dump(project2)
}

I don’t see this is being quite as useful as the JSON Encoding & Decoding, but I mention it here for completeness.

Codable:

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!

iPad:

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.

Writing:

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.

Images:

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[#]: {{ site.url }}/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.

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.

Summary:

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: http://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 {{ site.url }}/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


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.


Work

Permalink - Posted on 2016-11-16 00:00

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.

Work requires macOS 10.12 or OS X 10.11 and will be available from the Mac App Store soon.


We all know what it is like to be in the middle of a project or rushing to complete an assignment…

We have files scattered all over the place, email addresses of team members or clients, web pages with specifications or useful information, tasks scribbled on sticky notes or scraps of paper.

Wouldn’t it be better if there was one place where you could have quick and easy access to all these items, but without having to change the way you work? With the Work app, you can regain control - the app helps you get to what you want so you save time.


Here is the project document you will see when you select Work Help from the Help menu:

Work

It gathers together some useful links to information about Work and my other apps or to allow you to contact me. In Work documents for my apps, I assemble the project files I need to open, images, web page addresses etc. My most frequently used links are starred so I can focus on them whenever I want a shorter list.

Drag files or folders into the window to link them to your Work document. Copy a web address or email address and use Add Web/Email to quickly create a new link entry with the copied address.

Switching to Tasks mode allows you to focus on your tasks list. Tasks can be grouped, re-ordered and marked as complete. Use the View menu to hide completed tasks if you want a more compact list. Use the Edit menu or the toolbar buttons to edit groups - this allows you to create your own custom groupings.

Work - Tasks


Work doesn’t move or rename any of your files - it merely links all these things together for fast, convenient and searchable access. It even tracks files or folders if you move them later.

Make a Work document for every project, drag in the relevant files or folders, add web page addresses and email addresses, make your own task lists.

Create groups to gather items together, adjust the display to view only the entries you want, use quick look to get a fast glimpse of files or web pages.

Work also supports the Touch Bar on the new MacBook Pros:

Work - TouchBar


Select Work Help from the Help menu to see the special Work document pictured above. Use the links to keep in touch and step through the sequence of tasks to learn the basics of using the app.


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.


Podcasting

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”.


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…)


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.


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") {
   myArray.append("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.

mySet.insert("goldfish")  
// goldfish added: {"hamster", "cat", "dog", "goldfish"}
mySet.insert("dog")       
// 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 {
   print(animal)
}

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

TL;DR

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.

BARRRPPPP!

This app cannot be installed

What?

(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:

Error Domain=LaunchServicesError Code=0 "(null)" UserInfo={Error=ApplicationVerificationFailed, ErrorDetail=-402620393, ErrorDescription=Failed to verify code signature of /private/var/installd/Library/Caches/com.apple.mobile. 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 & Apple Watch.


Track your speed on your iPhone or Apple Watch 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 monitor your speed on your Apple Watch, you need to start the app on your iPhone, but then it does not have to remain in the foreground. However speed limit warnings will only be given when the iPhone app is active.

What Is My Speed? Apple Watch

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. You can also swipe up or down with two fingers to adjust the screen brightness for maximum visibility.

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. If you have an Apple Watch with the app installed, the app will continue to track your speed while in the background so that the data can be sent to your watch. If you do not have an Apple Watch or the app is not installed on the watch, your speed 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…


Update:

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 - 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) {
    printWithSpace(x)
}
// prints:  0 2 4 6 8 
for x in stride(from: 0, through: 10, by: 2) {
    printWithSpace(x)
}
// 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) {
    printWithSpace(x)
}
// 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) {
    printWithSpace(x)
}
// prints:  0.1  0.3  0.5  0.7  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 {
    printWithSpace(x)
}
// 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 {
    printWithSpace(name)
}
// 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.characters.count < 5 {
    printWithSpace(name)
}
// 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 3 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 = [ 	// type inferred to be Int
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10
]
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 = [ 	// type inferred to be Int
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10
]
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.

UIApplication.shared
UserDefaults.standard
NotificationCenter.default
FileManager.default
URLSession.shared

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 !

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.

Playground


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.


Learning Swift - Optionals

Permalink - Posted on 2016-02-12 00:00

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!

DO NOT DO THIS!

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 2 allows us to chain both if let and guard statements. Here is the previous example re-factored for Swift 2:

func isValidAddressBookEntry(
    firstName: String?,
    lastName: String?,
    emailAddress: String?,
    phoneNumber: String?) -> Bool {
    
        if let
            validFirstName = firstName,
            validLastName = lastName,
            validEmail = emailAddress,
            validPhone = phoneNumber {
                return true
        }
        return false
}

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 3 syntax.


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.


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.


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.


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.


Why?

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.


Possible issues with Icon Builder &amp; 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.


Dice Pass

Permalink - Posted on 2015-05-29 00:00

Dice Pass is available from the Mac App Store.

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.

Dice Pass for Mac

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.

The Diceware system was invented by Arnold Reinhold. This utility is not associated with or supported by Arnold Reinhold in any way, but uses his techniques with thanks. For more information about Diceware, have a look at the Diceware Passphrase FAQ page.

The default word list used in this app is a variation compiled by Alan Beale that removes some of the more obscure words. But you can select the original Diceware word list or the Diceware 8k word list fromt rh Word List menu if you prefer to use something different. You can also provide your own word list file if you prefer.


F.A.Q.

How many words should I use in my passphrase?

Arnold Reinhold recommends 6 words. He used to suggest that 5 was sufficient for most needs, but as of 2014 has increased this to 6. See the Diceware Passphrase FAQ page for more details. (Link above.)

How often can I re-generate the passphrase?

As often as you like. Keep clicking until you get a phrase that you can remember. If you get a phrase where most of the words are good but you would like to change one or two, you can click ‘Re-Roll’ on individual words to change them.

Is there a way to check the strength of my passphrase?

There are many password strength checkers on the internet and three of these are listed below. But always be careful when pasting your passphrase into a web page.

Online password strength checkers:

Some of the words in the phrase are not complete words.

The theory is that shorter words or abbreviations are easier to remember than long ones, without compromising security. But if you get a word you don’t like or think that you will not be able to remember, just re-roll that word.

What if I want to roll the dice myself?

Dice Pass allows you to tap on the 5 dice to set the numbers needed for each word manually. Each time you tap the number will go up be one, wrapping from 6 back to 1. The app will then look up the word table for you and show the new word.

When the phrase gets too long I can’t see all the words.

The “Copy” button will copy the complete passphrase even if it is not all visible. You can also scroll by clicking and dragging along the passphrase.

Does my passphrase get saved by the app or transmitted over the internet?

No. The app saves no data except for basic preferences (window positioning & size, preferred word list etc.). There is never any data sent over the network and the app will work perfectly if you disconnect your computer before using.

What are those 3 buttons: #, A and 1?

Some sites may require a passphrase that contains a mix of character types. These buttons will insert a special character, change the start of one word to uppercase, or insert a number. Tap the button again to undo the change. Again, these characters are chosen using the dice roll system and the special characters are selected and positioned using the method and data suggested by Arnold Reinhold.

I thought there was a version of Dice Pass for iOS!

There was, but with the need to update apps to support iOS 10, I decided to drop support for some under-performing iOS apps. If you bought the iOS version and would like to switch to the Mac, send me a screen shot of the app running on your iPhone or iPad and I will send you a free promo code for the Mac version.


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!


Un-boxing:

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:

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.


Notifications:

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:

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.


Activity:

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.


Communications:

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.


Summary:

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:


19th Hole

Permalink - Posted on 2015-03-16 00:00

19th Hole is the golf scoring app for everyone, and it is available from the iTunes App Store.

Whether you are playing for the club championship, having a weekend round with friends or playing pitch’n’putt with the kids, 19th Hole makes it easy to keep score.

Designed for fast, accurate score keeping with a color scheme chosen for optimal outdoor viewing, 19th Hole uses a simple setup process and an intuitive, gesture-based score entry system. During and after the round, you can see totals and results using various methods: total strokes, total putts, match play (Irish match play for more than 2 players) & Stableford.

19th Hole now includes an Apple Watch app so strokes can be entered quickly and easily using the watch to avoid having to pull your iPhone out of your bag.

When you have finished, you can archive the score card for future reference and email the completed card to your fellow players.

Scoring a round is very simple:

  1. Select a course – the last played course is pre-selected.
  2. Select the players – the last set of players is pre-selected.
  3. Tap ‘Start Round’
  4. Optionally enter the players’ handicaps – the last used handicaps are pre-selected.
  5. After each hole, enter the strokes played by each person, on your iPhone or Apple Watch.
  6. You can also record putts and various other statistics (iPhone only).

Scoring
iPhone

Watch Scoring
Apple Watch

Courses only need to be entered once and are then saved for future use.
Enter the course name, number of holes and select the tees in use. For each hole, enter the par, index/handicap, and the distance from each tee.

If you are in a hurry to start the round, enter the name of the course and the number of holes. The rest of the data can be entered for each hole as you play, or can be edited later.

Adding a course

Players can be selected from your Contacts or entered manually. Add email addresses so the completed cards can be emailed after the round. Choose an icon for each player. If a player was selected from Contacts, you can use the photo assigned in the Contacts app.

Adding a player

Gesture-controlled:

All scores are entered using a special number button that you tap, then drag your finger up or down the screen to raise or lower the number.

Hold your finger down on the number, then move it up or down to change the number displayed. To make it easier to see what you are doing, hold your finger down on the number, then first drag to one side before dragging up or down. Play the video below to see how this works.


To change hole, swipe left or right in the lower half of the screen, below the line. Swiping back from hole 1 allows you to change the handicaps. Swiping on from the last hole takes you to Notes where you can record any interesting events during this round.

During a round, cumulative statistics are shown at the bottom of the screen.
For a more complete score card, you can swipe downwards in the middle of the screen.

Tap on the hole details at the top of the screen to edit that data.

Gestures

After the game:

While relaxing at “The 19th Hole” after the game, you can check the scores and swipe back and forth between holes to see what happened during the round.

Once you are sure the scores are correct, tap the “Action” button in the top right. You can add some notes to the round at this point or archive the round so that the completed score card is saved on your iPhone. After this, you will not be able to make any further changes.

Completed rounds are listed when you tap “See Old Cards” with the most recent at the top. Tap one to see the complete score card for that round. Tap “Strokes”, “Putts” or “Stableford” to change what is shown for each hole. The summary is shown at the bottom.

Final Score Card


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 http://127.0.0.1:4000/ - 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
      2. Terminal to run the local Jekyll server
      3. Safari to check the finished post
      4. 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:

  • 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:

  • 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.


World Time In Words

Permalink - Posted on 2015-02-10 00:00

World Time In Words version 3.0 is now available in the Mac App Store.

With version 3.0 of this app, I have changed the name to “World Time In Words”. This is to reflect what I feel to be the most useful feature of this app: the ability to convert between time zones.

It has two other new features:

  1. The time shown in the menu bar can now be set to use 24-hour time. Go to Preferences to change this.
  2. If you temporarily need to see the time in digital format, hold down Option when opening the menu.

And there is one other thing in this version that I am almost too embarrassed to mention: after using this app for about two years, it was finally pointed out to me that the 3rd of every month was being shown as the “3th”. Oh dear – it was a copy-paste error but I should I found it a long time ago.

As always, please let me know if you have any suggestions for future versions.


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 &#038; 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.


Berio’s Sequenza VII

Permalink - Posted on 2013-11-06 00:00

Luciano Berio wrote a series of Sequenzas for various instruments with Sequenza VII being the one for oboe.
Sequenza VII icon

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.

Berio's Sequenza VII

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!

Settings

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.

Bars & Sounds

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.


Icon Builder &#038; 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.


Markdown

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.

Editor:

  • 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

Syntax:

  • 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.

Undo Last Move


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.


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.


Icns Maker &#038; 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.

Icns Maker - TrozWare

Icon Builder uses your image to create the suite of icon files needed for iOS apps.

Icon Builder - TrozWare


Icon Makers &#038; 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:

Selecting low resolution mode

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.


Icon makers for Mac &#038; 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 1024×1024 but 512×512 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.


Naming:

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.


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


I have not included Man Reader as it was rejected too many times to be a valid data point.

By comparison, when I submitted an update to A Knight’s Move for iOS in October, it was passed in only 8 days.


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.


Icon Builder

Permalink - Posted on 2012-10-01 00:00

Icon Builder 3.2 is available from the Mac App Store.

Make and install a set of icons for an iOS, Mac or Apple Watch app in 3 steps:

1: Drag an image into the window.

Make an icon set in 3 steps

2: Choose the device family you are building for: iOS Universal, iPhone, iPad, Mac or Apple Watch.

If you are building for iOS and your app still supports iOS 6, then you need to change the setting in the iOS popup menu.

3: Click “Create icon assets” and select the folder containing your Xcode project.

Icon Builder will create an AppIcon set inside the “Images.xcassets” folder for that project.
The icons are immediately ready for use in your project with no installation necessary.

You will get the best results if you start with a 1024 x 1024 image.


Why is this necessary?

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 iOS device. Mac apps use completely different icon sizes. And now we have Apple Watch with a different set of icons again. Additionally, you will need larger versions of each image to support Retina displays and iOS 7 & 8 use different icon sizes from the previous versions of iOS. The iPhone 6 Plus uses @3x images in some cases.

With Xcode 5 and later, Apple has changed the way a project stores image files, including the various sizes of app icon. Now your project contains a special folder called “Images.xcassets” which contains all the image files used in your project, including the app icons. Icon Builder will install the icon files into your “Images.xcassets” folder automatically.


Using the icon images:

Using the icons

Icon Builder creates all the required image files in a folder called “AppIcon.appiconset” inside the “Images.xcassets” folder for your project. If you already have images stored in an appiconset folder, Icon Builder will not over-write them, but will add a new folder e.g. “AppIcon-1.appiconset”. You can then switch between AppIcon sets in the project settings for your target app.

For submitting apps to the iTunes App Store, you will need a 1024x1024 image. For convenience, this file (iTunesArtwork@2x.jpg) is saved for you in a folder called iTunes Artwork images in the same folder as your xcodeproj file. For iOS, this folder will also include a 512x512 file called iTunesArtwork with no file extension. You will need to include this in your project (but not in “Images.xcassets”) if you are distributing an AdHoc version of your iOS app through iTunes.

The ReadMe-IconBuilder.rtf file (saved in the same folder as your xcodeproj file) has more information about the image files created.


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.

In previous versions of Icon Builder, the app saved all the icon files and you had to install them into your app project manually. Now Icon Builder creates an appiconset and installs it automatically in your project.

The other big change is that Icon Builder now creates icons for Mac apps. Mac apps used to use a different file format, but now they use appiconsets too, so it made sense to merge both my icon apps into one.

This app will NOT create the icns files that were used for Mac apps before Xcode 5 or 6. If you need icns files for another environment, use Icns Maker instead.


FAQ:

I thought there were only 2 steps before - why are there 3 now?

  • The 2 step process gave you a folder of image files. You then had to install them manually. So really, there were always three steps, but the app was not helping you with step 3. By adding a third step asking you to locate your project folder, I was able to make the app install the icons for you automatically. So the app is doing step 3 for you.

What if I want to install the icon files myself?

  • When asked to select a folder to save the icons, select a folder that does not contain a .xcodeproj file. Icon Builder will save all the files, but not install them into an Images.xcassets folder automatically.

What image types can I use?

  • Any image type compatible with QuickTime, including JPEG, PNG, TIFF, GIF, PDF, PSD, BMP.

Does this app make icons for iOS 8 apps?

  • Yes, the default is to make icons for iOS 7 & 8 only. If your app supports iOS 6 as well, select “Include iOS 6” from the iOS popup and the icon sizes will be altered to suit. iOS 8 does require some larger icons to support the higher resolution display in the iPhone 6 Plus. Icon Builder now also creates those files.

Does Icon Builder create icons for use in Mac apps?

  • Yes. When Mac apps used a different file format, I had a separate app to create Mac icns files. Now Mac apps use image assets just like iOS apps, but with different image sizes. Select Mac in the Device popup to create icons for a Mac app.

What version of Xcode do I need?

  • This app requires Xcode 5.x or later.

I don’t use Xcode, I use an alternative IDE. Can I still use the icons created by this app?

  • Yes, you can save the icon set to a folder and install the icons manually in the IDE of your choice.

What if my starting image is the wrong size?

  • If your image is not square, it will be cropped when you drag it in.
  • It will then be resized to create all the required image sizes.

How do I start again with a blank slate?

  • Choose “New” from the File menu, or press Command-N.

Do I have to drag images into the app?

  • No, you can copy & paste an image file, or an image.
  • Or choose “Open Image…” from the File menu, or press Command-O.

How can I delete the icons from my project?

  • Select “Images.xcassets” in the project navigator.
  • In the next sidebar, you will see a list of the asset sets in your project.
  • Select the one you want to delete (e.g. AppIcon, AppIcon-1) and press the Delete key.

I have an old project with no “Images.xcassets” - how do I add that?

  • Select the project at the top of the Project Navigator.
  • Make sure you are editing the target and go to the General tab.
  • In the “App Icons” section, click the “Use Asset Catalog” button.
  • The “Images.xcassets” folder will be created and any existing icons will be migrated to the new structure.

Why has the app made more icons than I need?

  • If your app only supports iOS 7/8 or only works with one family of iOS devices, then it does not need all the icons.
  • Select your options from the Device & iOS popups to adjust the number of icons created.

What if I want to use the images from a Mac .icns file?

  • Drag it in just like any image file. However the largest image in an .icns bundle is 512 x 512, so you may want to create a larger version.

Why are there files with @2x and @3x in the names?

  • These are for Retina displays and for iOS 7 or 8. iOS knows it needs a certain image size, but if the device has a Retina display, the system will look for an @2x file so it can squeeze twice as many pixels in and make it look sharp. For the iPhone 6 Plus, the system will use the @3x files if they are available.

Why is the iTunesArtwork@2x.jpg file a JPG when all the other files are PNGs?

  • iTunes Connect requires a 1024x1024 image file uploaded for each app. Recently, iTunes Connect has started rejecting some PNGs because they contained an alpha channel, even if they appeared to have no transparency. The best way to ensure there would be no alpha channel was to save the image as a JPG.

Why does the iTunesArtwork file have no file extension?

  • I don’t know. But that is what Apple specifies for AdHoc distribution through iTunes. It is actually a .png image so if you need to open it, add the .png file extension temporarily.

I use Pixelmator. Can I drag my pxm files into Icon Builder?

  • No. Pixelmator’s pxm files cannot be used directly. Export them as png files first.

I’m a programmer, not a graphic designer. How do I make icon images?

  • One easy way to create basic shapes with gradients, text, added images etc. is to use Keynote. I presume PowerPoint has the same sort of abilities.


Icns Maker

Permalink - Posted on 2012-10-01 00:00

Icns Maker is available from the Mac App Store.

Make an icns in 2 steps:

Make an icns in 2 steps

  1. Drag an image into the window.

  2. Click “Create icns” or “Create assets”.

This creates a .icns file or assets folder that can be imported directly into your Xcode project for use in your app.


Why is this necessary?

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 apps. With Xcode 4.4, Apple has changed the way icons are handled for Mac apps and “Icon Composer” is no longer supplied.

Search the Xcode documentation for “Icon Design Guidelines” and scroll down to “Provide the Correct Resources” and “Packaging Your Icon Resources” for more info.

For Xcode 4, you now create a special .iconset folder and load it up with various sized images. Then you run a shell command to stitch these specifically named files into a single .icns file that can be used in your Xcode project. None of this is rocket science, but it is tedious and repetitive – just the right sort of task for a computer.

With Xcode 5.x, Apple has changed things again. Now your project contains a special folder called “Images.xcassets” which contains all the image files used in your project, including the app icons.

If you have checked the “Create Assets (for Xcode 5.x or later)” checkbox, a folder of images will be created instead of the icns file. The images in this folder can be imported into your “Images.xcassets” folder for use as your app icon. A ReadMe file in the images folder will give the details on this.

Note that apps submitted to the Mac App Store now require a 1024×1024 version of the icon.


If you want more control:

Click the “Smaller sizes” switch to show all the other image sizes.Get More Control

When you drag an image into the 1024 x 1024 area, it is resized to supply all the required images. If you have a smaller version of your icon image that you want to use for some of the smaller sizes, just drag the image into the largest image area that you want it to be used for.

As an example, if you want to show a lower resolution image for 64×64, 32×32 and 16×16, create the lower resolution image at 64×64 pixels and drag it into the 64×64 area. It will be used for the 64×64 image and resized to make the 32×32 and 16×16 images. The larger images will still use the original 1024×1024 image scaled down.

If you want, you can specify a different image for every required size.

512×512 images will be resized to 1024×1024 if required to assist when converting older icons, but no other images will be enlarged.


FAQ:

Q. What image types can I use?
A. Any image type compatible with QuickTime, including JPEG, PNG, TIFF, GIF, PDF, PSD, BMP.

Q. Does this app make icons for OS X Mavericks (10.9) apps?
A. Yes, the required image sizes for icons have not changed in 10.9.

Q. What version of Xcode do I need?
A. This app is designed to help when using Xcode 4.4 or later.

  • For Xcode 4.x, make sure to un-check “Create Assets (for Xcode 5.x or later)”.
  • For Xcode 5.x, check the “Create Assets (for Xcode 5.x or later)” checkbox.

Q. What if my starting image is the wrong size?
A.  If your image is not square, it will be cropped when you drag it in. If it is the wrong size for the image area you are dragging it into, it will be resized to fit.

Q. How I start again with a blank slate?
A. Choose “New” from the File menu, or press Command-N.

Q. Do I have to drag images in?
A. No, you can copy & paste an image file, or an image.

Q. What if I want to update an existing .icns file?
A. Drag it in or choose “Open icns…” from the File menu. You may find that you need to make a new image for the 1024×1024 size.

Q. Does Mac Icns Maker create icons suitable for Retina displays?
A. Yes. That is why it uses a 1024×1024 version of your image.

Q. Does Icns Maker create icons for use in iPad and iPhone apps?
A. No. icns files are used in Mac apps only. For iOS apps, check out the companion product: Icon Builder.

Q. I’m a programmer, not a graphic designer. How do I make icon images?
A. One easy way to create basic shapes with gradients, text, added images etc. is to use Keynote. I presume PowerPoint has the same sort of abilities.


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 5. 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:

If you want your app to fill the 4″ screen, you must provide
a new launch image file called “Default-568h@2x.png”.
This image must be exactly 640 x 1136 pixels.

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

Tutorial puzzle on iPhone

Pesky Pawns - one of the more difficult puzzles on Mac.

Pesky Pawns - one of the more difficult puzzles on Mac.


A Knight’s Move

Permalink - Posted on 2012-07-08 00:00

A Knight’s Move is a puzzle game where you have to move your 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.

UPDATE: Version 1.3 for Mac now available.

A Knight's Move for Mac

Get from the starting position to the target in the shortest possible number of moves. Score stars based on the moves taken. If you need help, take a one star penalty to show all possible moves. If you really get stuck, after several tries the Cheat button allows you to see a solution, although that will cost you all your stars.

A Knight's Move for Mac

Choose your preferred board and chess pieces.

A Knight's Move Preferences


FAQ:

Q. Does the time I take to solve a puzzle count against me?
A. No - the number of stars you get depends solely on the number of moves taken.

Q. Are there any penalties for using Undo or Restart?
A. No - both Undo and Restart wind back the number of moves, so are not counted towards your final number of moves.

Q. What are the best techniques for solving a large puzzle?
A. Sometimes it is easier to work backwards. Work out which squares get you to the target safely and see if you can work out how to get to one of them. Another technique is to check all the possible moves and see how many can be eliminated because of danger or because they don’t lead anywhere except back to where you started. Just remember that trying and failing doesn’t count against you, so give it a go.

Q. What if I need help with a puzzle?
A. The first way to get help is to turn on “Show Moves”. This puts green circles on any square that your White Knight can reach next move. It does not indicate whether these squares are safe, but just shows you all legal moves. This option costs you a one star penalty but you can always do the puzzle again to try for three stars.

Q. What if I think a puzzle is completely impossible?
A. All the puzzles have at least one solution. If you have tried and tried, using Restart or being captured at least 5 times, the Cheat button will become available. Using the Cheat button will show you a possible solution but will mean that you can never get any stars for that puzzle.

Q. You’re kidding, right? No stars… ever… just because I cheated?
A. OK, I’m kidding, but the way out of this is deliberately hidden and inconvenient. If you go to Settings or Preferences, you can reset all the game scores which clears all records of stars won so far, allowing you to restart completely. If you reset the scores three times in a row, this will also clear all records of cheating.

Q. I think I solved a puzzle in fewer moves than the minimum moves shown.
A. Great! Please take a screen shot of the puzzle and annotate it to show your moves. Email it in to sarah@troz.net so that I can edit the puzzle for the next update.


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.


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.


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.


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 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:

NSPanel Settings

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:

Time In Words Screen Saver Download


Man Reader

Permalink - Posted on 2012-05-08 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.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.


Time In Words Screen Saver

Permalink - Posted on 2012-05-07 00:00

The latest member of the Time In Words suite of apps is a screen saver module for Macs.
Version 1.2 updated January 2013: compatible with Lion (OS X 10.7), Mountain Lion (OS X 10.8), Mavericks (OS X 10.9) & Yosemite (OS X 10.10).

Time In Words Screen Saver Download

Download Time In Words Screen Saver

Like Time In Words for iOS and World Time In Words for Mac, it displays the time and date in plain words which are easy to read and comprehend. While it only shows a single time and date, this can be configured to show your local time & date or any available time zone. Since the App Store does not have a section for screen savers, the Time In Words screen saver is available as a direct download from my site. Click the link or the icon above to download the screen saver as a zip file. If the zip file does not open automatically, double-click the file to unzip it. Then double-click the “Time In Words Screen Saver.saver” file to install the screen saver in your System Preferences. You will be asked whether you want to install it for the current user only or for all users. Selecting “All Users” will require you to enter your password, so I recommend just installing for the current user.

Scroll to the “Other” section of the list of screen savers and click “Time In Words Screen Saver” to activate it. Sometimes the installation leaves the screen saver selected but not active. If this is the case, select another screen saver and then click back on Time In Words.

Time In Words Screen Saver

By default, your local time & date will be displayed. To select a different time zone, click the “Screen Saver Options…” button to display the following:

Time In Words Screen Saver Options

Click the “Show Alternate Time” radio button to enable the time zone list. As with Time In Words for Mac, you can type part of a city name in the search field to find a zone quickly. Select the zone you want to use and click “OK”. The preview will switch to showing your newly selected time zone.

For anyone interested in the source code, here is a download link: Time In Words Screen Saver Xcode project. This was written using Xcode 4.x so is rather out-dated by now, but may prove useful to others wishing to start writing their own screen savers.


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 &#038; 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.

AssistiveTouch settings

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.

The White Blob

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.

AssistiveTouch panel open

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.


World Time In Words for Mac

Permalink - Posted on 2012-03-19 00:00

World Time In Words for Mac version 3.0 is now available through the Mac App Store. This update changes the name from “Time In Words” to “World Time In Words” as an acknowledgment that the major feature of this app is converting time between different time zones. This update adds the ability to show digital time if you need greater accuracy – just hold down Option as you open the menu. I have also added the ability to show 24-hour time in the menu bar.

World Time In Words runs as a menu bar utility app that displays your current time and date in words. Optionally, it can be set to display a number of time zones, again in plain English so it is always clear which day is being referred to. It shows the time in words in your menu bar all the time if you like, and now offers a convenient way to work out what the time will be in other zones at a specified local time.

The first time you run the World Time In Words app, it will appear in your menu bar and pop down a menu that looks like this:

World Time In Words starting menu

Selecting Preferences… will take you to a window like thisWorld Time In Words Preferences

Type in part of a city name in the search area to find that city and its time zone. Drag or double-click a line in the table on the right to move a time zone to the list on the left, which shows the time zones that will appear in the menu. Drag a line out of the list on the left to remove a zone, or double-click the unwanted line. Drag and drop to re-arrange the zones in the selected list.

Mars geeks: scroll to the bottom of the time zone list or search for Mars, Curiosity or Opportunity to find the Mars Rovers. Adding them to your selected time zones will show how many Sols (Martian days) the rovers have been on Mars.

Once you have selected some time zones, your menu may look like this:World Time In Words menu with added time zones

Note that the menu will indicate which time zones are currently in daylight savings time.

Version 3.0 adds the ability to see all the time digitally if you have a temporary need for greater accuracy. Hold down the Option key as you click in the menu title and the menu will appear like this:
World Time In Words digital option

To specify what will be displayed in the menu bar, you can toggle “Show time in words as menu title”. If this is checked, you have two other methods for adjusting what you will see. Select your preferred accuracy: “To closest 5 minutes” or “Precise”. Use the popup menu to select a time & date format to show in the menu bar. You can also choose 24 hour time for the menu title if you prefer.
Menu bar time & date formats

To see what time it will be in your selected time zones at various hours during your day, choose “What time will it be when…” from the menu. Move the slider to different hours in your local zone and read what the corresponding time will be in your preferred time zones.
What time will it be when...

If you want to make World Time In Words start automatically whenever you log in to your Mac, check the “Auto start…” checkbox. This uses Apple’s new methods of adding sandboxed items to the login startup list which has two consequences:

  • World Time In Words will not show up in your Login Items if you go to System Preferences
  • The auto-start will only work if the app is installed in your Applications folder.

While I do not think the second item is a problem, since the App Store automatically installs into your Applications folder, I disagree with the policy enforced in the first item. It means that if you wish to un-install World Time In Words, you should ensure that you have turned off “Auto start…” first, as there is no easy way to do this from outside the app.

However, World Time In Words is sandboxed, so it’s data and settings are kept in their own container and isolated from other apps for better security.

If you are having any problems with World Time In Words, or you have any suggestions for future improvements, please email me.


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:

Preferences 10.6

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:

Preferences 10.7

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.


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, I had to work out the interface for selecting time zones. With Time In Word for iOS, 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:

Africa/Abidjan
Africa/Accra

America/Cayman
America/Chicago

Europe/Riga
Europe/Rome
etc.

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.


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.

App Store link

Check out the Time In Words web page for more info and screen shots.


Time In Words for iOS

Permalink - Posted on 2012-02-08 00:00

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. When people look at an analog watch, they tend to interpret the time to the closest five minutes which allows for inaccuracies in the watch as well as providing only a useful level of detail. This app goes back to that, showing date and/or time in multiple ways, but all in words.

Time In Words is available from the App Store.

Does your job involve reading out the time from a clock? Perhaps over the radio or a public address system? Let Time In Words convert the time and date to words for you, so you can’t make a mistake.

Swipe though the pages of the app to see a time display, date display, time and date in words and finally, a time zone converter that explains the time and the day in words, so no conversion is needed to work out whether calling a friend in Minsk right now would be a bad idea.

Configure the colors for the text and backgrounds and adjust the brightness to suit your surroundings.

If you set your device’s Auto-Lock to Never (Settings – General) and leave it connected to power, then you can use this as a clock.

For any problems with this app, please use the Contact Me link in the sidebar.

Screen shots are for iPhone or iPod Touch. iPad is similar but allows four time zone conversions.

Time  Date Time and Date  Time zone conversion Settings