Archive for November, 2015

Did the Verge just insult me?

Me, a few weeks ago:

When your brain and fingers are absolutely wired for Emacs editing, it’s a frustrating experience to have to work on the iPad, with all its touching. As a touch-typist, any time I have to move my hands away from the keyboard, it feels like I have failed.

After some searching around App Store, I eventually downloaded a few Emacs-style editors. Of these, em notes (about five bucks) offered the best solution. It links with your Dropbox account and enables you to edit text in an application folder there, ensuring you can load and work on documents and have them available as well in the “real world”, aka anywhere you’re not working on an iPad.

The Verge, today:

Oh and it should go without mentioning, that the keyboard itself is only a solution for geeks and no one else…for a regular person who wants to regularly use an iPad Pro with a keyboard, your only solution is using the UI with your fingers constantly. This is simply true; just as it’s true that only the nerdiest of nerds should learn how Emacs and its keybindings work…

Sniff.

Wrapping and indentation opinions

What do you think of the following?

This code does a bunch of things that aren’t typical. First, all function params are single-lined and left-aligned including the first param. Second, the return token and the closing paren are on their own line. Third, the complex return ternary is split into 4 lines, with left-aligned ? and : cases.

I’m just messing with styling, there are no rules or principles here. Thoughts?

Update: Jessy suggests using combined lets for sequential assignments but I’m not really seeing the appeal here:

More examples in his gist.

Black Friday, Cyber Monday: Buy my books, save some money at InformIT

According to my InformIT sources, the Swift Developer’s Cookbook preorder is 35% off on Black Friday Week. Coupon Code: BF2015. If you pick up Gourmet at the same time,  you save 55% off the pair. (Sun 22 Nov – Sat Nov 28).

On Digital Monday, you can pick up my ebooks (“digital products”) for 55% off, using the Coupon Code: CM2015 (Sunday 29 Nov – Mon 30 Nov)

Read the fine print for details or ping @InformIT on Twitter if you have any questions.

Apple TV: Exploring physical activity

Incorporating, or more accurately trying to incorporate, physical activity into a tvOS app isn’t easy. Apple TV is no Kinect or Wii. At this time, about the best you can do with “native equipment” is wave a Siri remote around in the air or pop it into a pocket and use it as a kind of pedometer when walking on a treadmill or in place.

I spent a bit of time reviewing some of the “greatest hits” of physical TV gaming from walking companions to boxing/cheerleading games (would be much better with a secondary nunchuck) to yoga/balance and so forth. The best of these look at a lot more than a single arm-action point of control.

If you don’t mind going cross-system, of course, you can use motion features already on iOS and project them (directly over AirPlay or indirectly through Bonjour, etc) to a tvOS app but we’re already now talking bigger, bulkier, more planning, less impulse use, and less tvOS “app” design.

In theory you can use a wrist strap of some kind with the Siri remote and rely on arm motion to model physical activity. The chances of flinging the remote remain quite high unless the remote is physical tied down to a forearm, requiring a well-designed physical adaptor.

Conclusion? At this point, Apple is wasting a strong health branding component with its Apple TV product. Between the watch, iOS Motion, and Health Kit, Apple TV should be much more proactive than apps limited to logging meals (still easier to do on an iOS device) and offering coaching advice.

Opportunity wasted, premature entry onto the market, or simply wrong aim/branding?

A stroll through a Swift oddity: argument ordering

This little oddness popped up in IRC and I thought I’d share.

When creating methods and functions, you cannot normally re-order arguments. Try it (see this Swiftstub), and you’ll raise an error like this example’s “argument ‘a’ must precede argument ‘c’“.

But give each argument a default value, and you can re-order as desired (see this Swiftstub). Cool, right?

I’m guessing this is less an intentional feature than an artifact of Swift’s default value implementation. When defaults are available, you’d generally want to offer more permissive inclusion and exclusion.

As things stand, I think it’s kind of nifty. That said, I wouldn’t be surprised if it was either eliminated in the language or the expressibility expanded to all functions and methods with fully-articulated external names.

Deducing your playground “device”

When your playground doesn’t find the exact device it wants to simulate it gets cranky. When your playground gets cranky, it displays this error, which more or less tells you nothing about which run destination to install:

Screen Shot 2015-11-22 at 6.05.21 PM

So what are you supposed to do?

The easiest solution is to hop into Xcode > Windows > Devices and add one of every kind of possible simulator so Xcode stops throwing fits. Quit and restart and Xcode loses that wild-eyed crazy look and playgrounds start behaving…better.

But say you’re of a parsimonious frame of mind. Imagine those extra simulators offend you with their patent lack of efficiency. Which simulated devices can you toss from Xcode?

  • Well, if you’re going to do any Apple TV dev, don’t toss the Apple TV one.
  • You don’t need a “simulator” for OS X dev. So you probably never got an error in the first place.
  • But what about for general iOS development? Which one was right?

Easy way to find out: print(NSTemporaryDirectory()). It will look something like this:

/Users/ericasadun/Library/Developer/XCPGDevices/9A03F9FE-79F4-4FEA-B180-AB0D454C9A61/data/Containers/Data/Application/004CC333-1E33-4E20-AFEC-A8A5B7778562/tmp/

Then hop into the XCPGDevices folder to the subfolder with that UUID, and open the property list.

{
 UDID = "9A03F9FE-79F4-4FEA-B180-AB0D454C9A61";
 deviceType = "com.apple.CoreSimulator.SimDeviceType.iPad-Pro";
 name = "iPad Pro";
 runtime = "com.apple.CoreSimulator.SimRuntime.iOS-9-2";
 state = 3;
}

Boom. This instantly told me that the one simulator I couldn’t toss for iOS  playgrounds was the iPad Pro one.

There’s, of course, not a lot of harm in keeping a bunch of simulators around — and they can be extremely helpful to have on hand. But some deeply OCD part of me is now relieved that I know which simulator my playground is running on. I hope this will comfort some of you as well.

Fact: Sets are the Jan Brady of Swift Collections

Swift can infer array types:

let myArray = ["a", "b", "c", "d"]

Swift can infer dictionary types:

let myDictionary = ["key1": "value1", "key2": "value2"]

But what about sets?

let mySet = ["a", "b", "c", "d"] as Set // or
let mySet: Set = ["a", "b", "c", "d"]

These johnny-come-lately collections offer no automatic inferencing. Don’t sets deserve love too?

Parentheses are already taken by tuples. Angle brackets are protocol/generic specific No one wants to type 《》. Face it. Sets are Swift’s Jan Brady collections.

Swift playgrounds use braces to show sets in the results sidebar:

Screen Shot 2015-11-19 at 10.34.41 AM

But of course, braces mean closures:

Screen Shot 2015-11-19 at 10.36.50 AM

And even if Swift could infer a set from comma-delineated braced items, should it?

let mySet = {"a", "b", "c", "d", "e"} // wrong, bad, wrong 
let mySet = {members | "a", "b", "c", "d", "e"} // nope

You could do a lot worse.

let mySet = ~1, 2, 3~ // The "mustache" delimiter
let mySet = ¯\_(ツ)_/¯ 1,2,3, ¯\_(ツ)_/¯
let mySet = •< 1, 2, 3 >•
// ...etc...

Even if there were a way to infer sets, Swift still wouldn’t be able to infer option sets, bags, ordered sets, ordered dictionaries, counted sets, fashionable totes, shopping satchels, and unique arrays.

let myTotes = [(Gucci, Prada, Louis Vuitton)]

You could try (or try! or try?) but you’re just (ahem) setting yourself up for failure.

So what should Swift do? You tell me.

Thank you everyone in #swift-lang IRC for your suggestions.

Swift Developer’s Cookbook: Status Update (Mark December 17 on your calendars!)

41XD0j6+b5L._SX388_BO1,204,203,200_

Checking in on the Swift Developer’s Cookbook:

  • The book has finished production. It’s available for pre-order at Amazon. InformIT has a pre-order page up as well.
  • It’s available right now to read at Safari Books Online through their Rough Cuts program. You can get a free multi-day trial.
  • The book will participate in Pearson/Addison Wesley’s new Content Update Program, which I describe below in this post.
  • My editor says the actual pub date is December 17. It will make an awesome holiday present for yourself or your favorite geek.

What’s in it?

The cookbook kicks off with a discussion of how to migrate code when the language changes. (Some persons I showed this to inside Fruit-world were dismayed: “Why are you starting off with migration?” Everyone outside Fruit-world I showed this to nodded their heads with wry understanding.)

Within the book, each chapter focuses on day-to-day-development concepts and best practices. This is the book you buy after working through Apple’s language tour, to learn how to use all those language features to get real work done. You can view a full table of contents at InformIT in the Sample Content tab.

I’m hoping this book will work for both Apple-centric Swift developers as well as new developers jumping in from Linux after the big Open Source event.

The Content Update program

My Pearson team and I spent a lot of time discussing how to develop content for a language that’s been changing since it launched. While I think Swift 2 is going to be a lot more stable than Swift 1, I wanted to be sure we accounted for Apple’s constant, accelerated tech changes.

The Swift cookbook participates in Pearson’s new Content Update program, which works like this:

  • As Apple makes significant updates to the Swift 2 language, sections of my book may be updated or new sections added.
  • Book updates are delivered via a free Web Edition, which can be accessed with any Internet connection.
  • Customers register their books (print versions, ebook versions, whatever) with AW/Pearson, and if and when content changes, they receive email updates.

In other words, the CU program acts a guard against the book going out of date two days after you purchase it. What’s more, I architected the book to be as long-lived as possible, focusing on core language concepts.

So, to wrap up, thank you everyone who has pre-ordered and thank you everyone who’s considering a purchase soon. If you have any specific questions about the program or the book, drop me an email.

 

If this book existed, would you buy it? (Part 2 in a series)

Remember my poll about a possible Swift Markup book? Based on your feedback and support, I went ahead and wrote it; Swift Documentation Markup is now at iTunes and from Leanpub. Thank you everyone!

So, next, how about this?

Style

Would you buy a book about common Swift style rules? Something similar to the topics I brought up yesterday in this related post but more comprehensive, with discussion and code samples? Keep in mind this wouldn’t be a bible — just helpful, hopefully well sourced, opinions and suggestions.

A few things:

  • If there’s anything specific you’d like to see in a book or any issues you have with the ideas I throw out in my posts, please ping me and let me know.
  • Now that I’m set up over at Leanpub, I’m intrigued by their system of installment-publishing. iBooks also supports updates, revisions, and expansions. Would you be more interested in a whole-book-at-once or reading-as-I-write in general?

And finally, these are the existing books in my self-published series:

Screen Shot 2015-10-14 at 3.08.34 PM  cover

A handful of Swift style rules #swiftlang

Revisiting some old style rules with new twists.

The Rule of Lily: “When a trailing closure argument is functional, use parentheses. When it is procedural, use braces.”

myCollection.map({blah}).filter({blah}).etc
myCollection.forEach {} // or 
dispatch_after(when, queue) {}

The consistency of style communicates whether closures return values. There’s an ongoing dispute as to whether a space should be left before  trailing braces.

The Rule of Self: “Implicit member expressions enable you to omit self when the compiler can unambiguously infer member types. Use self whenever a method call reflexively refers back to an instance.”

Consider the following for-loop’s where clause. The contains method call lacks an explicit subject.  What is doing the containing? A container isn’t included as method parameter so it has to be the calling instance.

for (flagLessOne, string) in strings.enumerate() 
    where contains(
        Features(rawValue: 1<<(flagLessOne + 1))) {
    nameArray.append(string)
}

Fully qualifying the call clarifies the subject ambiguity and vastly improves readability:

for (flagLessOne, string) in strings.enumerate() 
    where self.contains(
        Features(rawValue: 1<<(flagLessOne + 1))) {
    nameArray.append(string)
}

The Rule of Conditional Binding Cascades: “Unless you’re mixing var and let conditional bindings, use a single if let or if var introduction. Add liberal whitespace as needed.”

Instead of:

if let x = x, let y = y, let z = z {blah}

use:

if let x = x, y = y, z = z {blah}

Removing extraneous let keywords simplifies the binding cascade, and Xcode will nicely co-align these for you:

if let
    x = x,
    y = y,
    z = z {
    ...blah...
}

Although cascaded bindings avoids the pre-Swift 2 “pyramids of doom”, they tend towards “constipated blocks of horror”. When faced with excess serial bindings, interleave them with spaces and comments, as in the following example, or use a sequence of guard statements.

if let
    // Access JSON as dictionary 
    json = json as? NSDictionary,

    // Retrieve results array
    resultsList = json["results"] as? NSArray,

    // Extract first item
    results = resultsList.firstObject as? NSDictionary,

    // Extract name and price
    name = results["trackName"] as? String, 
    price = results["price"] as? NSNumber {

    // ... blah blah ...
  }

The Rule of  Pattern Matching Keywords: “When everything’s a binding, unify your bindings.”

Combine multiple pattern matching bindings by moving keywords out of tuples. Instead of:

if case (let x?, let y?) = myOptionalTuple {
    print(x, y)
}

Use:

if case let (x?, y?) = myOptionalTuple {
    print(x, y)
}

The Rule of isEmpty: “If you’re testing a collection’s count, you’re probably doing it wrong.”  Prefer isEmpty to count == 0.

The Rule of Void: “Use Void return types, not ().” A function returns -> Void and not -> ().

func doThis() -> Void 
func notThis() -> ()

The Rule of !: “Every time you use an exclamation point in Swift, a kitten dies.” Wherever possible, avoid forced casts and forced unwrapping.

The Rule of Collection Creation: “Use explicit typing and empty collections.” Types to the left of the assignment, empty instances to the right.

Instead of:

var x = [String: Int]() // and
var y = [Double]()
var z = Set<String>()
var mySet = MyOptionSet()

use

var x: [String: Int] = [:]
var y: [Double] = []
var z: Set<String> = []
var mySet: MyOptionSet = []

Cite.

The “Mike Ash” colon rule: “Space to the right. No space to the left.” Or no soup for you!

Prefer

[key: value] // and
struct Foo: MyProtocol

to

[key : value]
struct Foo : MyProtocol

The Rules of Moving-On-From-Objective-C

  • Don’t add Objective-C-style parentheses around if and switch conditions or with return keywords.
  • Use camel case for allTheConstants and not ALL_CAPS
  • Prefer Swift constructors to legacy ones, e.g. CGPoint(x: 1, y:1) over CGPointMake(1, 1)
  • Avoid terminal semicolons even though they compile. They make you look bad and you should feel bad for using them.

Update: Yes, I don’t just talk the talk, I walk the walk with these rules in my code:

Screen Shot 2015-11-18 at 10.31.13 AM

github repo