The personal blog of Stuart Breckenridge

Office Fonts from H&Co  

H&Co:

Today we’re introducing twelve families of Office Fonts, all of them available for purchase and download. Some coordinate with our best-known typefaces (which serve the world’s best-known brands), Office Fonts for Gotham, Archer, Whitney and Sentinel. We’re also introducing Office Fonts for some of our newest releases, including this year’s Whitney Narrow and Operator.

I own Whitney Pro and Operator Mono. It’s mildly irritating that there are now Office versions of them.



Auto-generating Quick Help Text with Xcode 8

Xcode 8 introduces new Editor Extension functionality that allows you to customise your coding experience. Given that Xcode 8 is still in beta I haven’t seen or tested any third party extensions just yet. However, in amongst all the new feature blurb something caught my attention:

Auto-generate Quick Help documentation

For the last few years I’ve been using the excellent VVDocumenter to assist in generating the Quick Help text, but as of Xcode 8, it’s been sherlocked.

How do you use the new in-built Quick Help text generation functionality? Simply click on the function you wish to add documentation to and then use the following key combination option + command + /, as seen in the below example.


Shoehorning 3D Touch onto the Home Screen

iOS 10 implements a 3D Touch Share option on the home screen for all applications.

The problem with the Share option is that the intent is not clear: what are you actually sharing? A link to the app? The app itself? Some app content? This seems like a way to shoehorn 3D Touch onto all apps on the home screen.


Bug Report: Core Data Generated Files Not Found by Xcode 8

Xcode 8 promises to bring many improvements to Core Data, however, it seems to be having an issue in that it stops working pretty quickly even after several reinstalls.

My issue is that Xcode generates new NSManagedObject’s and then can’t find them in the build process. Instead, I see the following error:

<unknown>:0: error: no such file or directory: '~/Library/Developer/Xcode/DerivedData/Project-ehewnupfwfyaezbdvoohlbtmspad/Build/
Intermediates/Project.build/Debug-iphonesimulator/Project.build/DerivedSources/
CoreDataGenerated/Project/.Country+CoreDataClass.swift'

Interestingly, the file the error is referring to — .Country+CoreDataClass.swift — exists in the folder above without the leading .. I’ve filed Radar 27151410.

See also:


The FFI List: In-App Subscription  

Yesterday I released v1.1 of The FFI List and with it, I’m trying a new business model. The app is now free and from July onwards new FFI List downloads will be accessible through an auto-renewing subscription.1

I intend to keep this going for six months and then review the uptake.

  1. £0.79/$0.99 per month. ↩︎


The Measurement Type

The new Measurement type1 is a hugely helpful addition to the Foundation framework. It allows for conversion amongst many different measurements:

  • Acceleration
  • Angle
  • Area
  • Concentration Mass
  • Dispersion
  • Duration
  • Electric Charge
  • Electric Current
  • Electric Potential Difference
  • Electric Resistance
  • Energy
  • Frequency
  • Fuel Efficiency
  • Length
  • Illuminance
  • Mass
  • Power
  • Pressure
  • Speed
  • Temperature
  • Volume

Usage is simple:

var mLs = Measurement(value: 125, unit: UnitVolume.milliliters) // 125 mL
var flOz = mLs.converted(to: UnitVolume.fluidOunces) // 4.2267 fl oz

Apple has provided excellent documentation on how to subclass the Dimension type, and on extending existing Dimension types. My quick experiment was to create a new UnitUKCurrency type:

class UnitUKCurrency: Dimension {
    static let pence = UnitUKCurrency(symbol: "pence", converter: UnitConverterLinear(coefficient: 1.0))
    static let pounds = UnitUKCurrency(symbol: "pounds", converter: UnitConverterLinear(coefficient: 100.00))
    
    override static func baseUnit() -> UnitUKCurrency {
        return self.pence
    }
}

Which, in use, looks like this:

let pennies = Measurement(value: 1234.0, unit: UnitUKCurrency.pence) // 1234.0 pence
let poundage = pennies.converted(to: UnitUKCurrency.pounds) // 12.34 pounds

If only Measurement was around for v1.2 of Baby’s Milk!

  1. The NSMeasurement class in Objective-C. ↩︎


App Store Changes  

From developer.apple.com:

We’re introducing exciting new capabilities and tools designed to help grow your app’s business and engage with new and existing customers on the App Store.

Search Ads
Search Ads is an efficient and easy way for you to promote your app directly within the U.S. App Store search results, helping customers discover or reengage with your app, while respecting their privacy. Starting this summer, you’ll be able to participate in the Search Ads beta and see the ads in action.

Subscription Enhancements
We’re opening auto-renewable subscriptions to all app tags including games, increasing developer revenue for eligible subscriptions after one year, providing greater pricing flexibility, and more.

Search Ads has been rumoured for a while and their implementation seems to be a fair to users from a privacy standpoint and to developers—both large and indie—from an ad pricing standpoint. Subscription changes open up the possibility of free trials—something developers have been demanding for a long, long time!

In addition, App Store review times have been cut to 48 hours in 90% of cases. I can vouch for this, one my apps was submitted on Saturday and was approved within a day.


UIAlertController Preferred Action

In a scenario where your UIAlertController alerts only have .Default actions, how do you add emphasis to what should be considered the preferred action of the user? Prior to iOS 9, this wasn’t possible without using a .Cancel action type, or creating your UIAlertController-like class from scratch. Enter preferredAction.

Let’s look at an example:

let alert = UIAlertController(title: "Send Error", message: "Your email failed to send.", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Try Again", style: .Default, handler: nil))
alert.addAction(UIAlertAction(title: "Remind Me Later", style: .Default, handler: nil))
alert.addAction(UIAlertAction(title: "Delete Draft", style: .Destructive, handler: nil))
        
presentViewController(alert, animated: true, completion: nil)

The above code will present a UIAlertController as follows:

UIAlertController Example 1

There is no obvious default action being highlighted to the user. To set a preferredAction, you just add this piece of code prior to presentViewController...:

alert.preferredAction = alert.actions[1] // Remind Me Later is at index 1 in the actions array.

Voila! Emphasis has been added to what should be considered as the preferred action.

UIAlertController Example 1


SLComposable

Update: SLComposable is available on Cocoapods:
pod "SLComposable"

I’m in the process of rebuilding an old demo app I created three years ago for the Social framework. In that demo app I created individual instance methods for creating an SLComposeViewController with initial text, with initial text and an image, for each social network, and so on.

With the rebuild, I’ve gone about it a different way. I’ve created a protocol, SLComposable, which defines one method:

func composePost(text text:String?, image:UIImage?, url:NSURL?, network: SLComposableServiceType)

That’s it. One method for all social networks supported on iOS.

It’s been extended to UIViewController with an implementation that will check if posting to the specified social network is allowed, and if it isn’t it will present an UIAlertController to the user.

The full gist is below: