Archive for March, 2015

Swift: Fetching the updated docs as an ebook

Over at DevForums, users post that the 1.2 docs are online but not accessible in an ebook version.

Visit the prerelease website for the Swift Programming Language and you’ll see that the last update is 3/11/15 and the document revision history goes up to 2/9/15. So how do you get this website into an ebook form suitable for your iPad?

This is what I did.

1. Download Used sitesucker to fetch https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/index.html

Make sure the Download Option is set to Get All Files in Same Directory so you don’t inadvertently download all of developer.apple.com.

2. Locate index.html. Navigate into your Downloads folder into developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language. Find the Index.html folder

3. Launch Calibre. Grab a copy if you don’t already have one.

4. Drag index.html into Calibre. Wait for a while. Reading the metadata and adding to library takes time.

5. Select The Swift Programming Language.  Click Convert books. Choose EPUB or Mobi or whatever from the Output format popup. Set the Author to Apple.

6. Optionally add a cover image. If you want one from your existing Swift Language reference, navigate to ~/Library/Containers/com.apple.BKAgentService/Data/Documents/iBooks/Books and find the epub by grepping. Within the epub folder is a file called iTunesArtwork. Copy it to your desktop and add a jpeg extension then drag it into the Book Cover well.

7. Click OK. Wait for the book to convert.

8. Retrieve the new epub. Click Path: Click to Open. Your ebook appears in the newly opened folder. It’s big. Many many pages.

Swift: fixing “unable to decode playground data”

The dreaded “unable to decode playground data” error just happened to me and I thought I’d share my solution. What happened was this. I pasted some code from a Word document into the playground and immediately bad things started happening. The Playground kept complaining. So I cut out the pasted material and everything went back to behaving.

I set out to figure out what was going wrong. I tried stripping the text, first assuming the issues might involve rich text or something like that. But no, the error persisted. So then I tried typing the code in directly, skipping the paste. This time, the playground worked. Something was traveling with the paste, even stripped down to text, that was killing the playground.

So I pasted my copied code into one text file and the manually-typed version into another and diff’ed them at the command line. Immediate a problem jumped out, encouraging me to list the two files there. In one case, I was using standard returns, in the other (the one copied from Word) ^M’s. You can see this in the following shot: (Click it to expand to full size)

Screen Shot 2015-03-23 at 10.26.00 AM

To test, I created a new playground, pasted in the problematic code and once again got an error. Then at the end of each line, I performed a delete and then a manual return. Problem fixed. Everything ran properly.

What’s interesting about all this is that the issue wasn’t apparent until the command line. Everything looked identical when inspected in TextEdit and when I peeked at the contents.swift file. Here’s the hex dump of the non-working contents.swift (top) and working (bottom). If you open the full-size version, you’ll see that the error appears when the lines end with ^M (0x0d) versus ^J (0x0a).

Screen Shot 2015-03-23 at 10.36.29 AM

I accidentally slipped one extra 0x0a line return in the non-working version, so there’s an extra 0a there at the start of the second-to-last line.

Presumably, the decoding error is not limited to ^M vs ^J, but hopefully this write-up will show up in someone’s future web search and maybe help them out of a sticky situation.

 

 

Swift: More Fun with Reflection

Today, I was kicking around in a playground because (1) writing about playgrounds is kind of a thing right now and (2) because my kids were away and I had some time. I started trying to mess with tuples, and more specifically to zip them because tuples and structs tend to have related data in similar positions.

In any case, I ended up creating a small set of what I call  EVIL UNIVERSE SPOCK UTILITIES using mirroring and goatees. I thought I’d throw these out there to see whether they’re generally useful or interesting:

// MARK: Mirror-based Utilities
// These work across arrays, structures, tuples
// Goatees are mandatory

// This function maps a closure across anything
func mirrorDo<S>(structure:S, closure:(Int, String, Any)->()) {
    let mirror = reflect(structure)
    for index in 0 ..< mirror.count {
        closure(index, mirror[index].0, mirror[index].1.value)
    }
}

// This function collects the results of the mapped closure
func mirrorMap<S>(structure:S, closure:(Int, String, Any)->Any)->[Any]{
    let mirror = reflect(structure)
    var results = [Any]()
    for index in 0 ..< mirror.count {
        let result = closure(index, mirror[index].0, mirror[index].1.value)
        results += [result]
    }
    return results
}

// This converts nearly anything into an array
func mirrorToArray<S>(structure:S) -> [Any] {
    return mirrorMap(structure){return $2}
}

// This function zips things into array pairs
func mirrorZipToArray<S, T>(s:S, t:T)->[[Any]] {
    var array = [[Any]]()
    for each in zip(mirrorToArray(s), mirrorToArray(t)) {
        array += [mirrorToArray(each)]
    }
    return array
}

For example, you might look at all the elements or fields in a tuple or structure:

for test : Any in [tuple1, rect, point, transform] {
    println("\(test.dynamicType): ")
    mirrorDo(test){ (index: Int, field : String, value : Any) -> () in
        println("type:\(value.dynamicType), index: \(index), field: \(field), value: \(value)")
    }
}

Or you might convert items to an array:

for test : Any in [tuple1, rect, array2, point, transform] {
    println("Converting \(test) to array")
    println(mirrorToArray(test))
}

Or you might just zip stuff together into arrays:

mirrorZipToArray(array3, array2)
mirrorZipToArray(tuple1, tuple2)

You’ll find the code and a bunch of examples that showcase their use in this gist.

Two other things that simply pleased my aesthetics today. First: I really like that you can apply maps to zips.

var results = map(zip(["a", "b", "c"], ["d", "b", "e"])){$0==$1}

And also you can pass tuples to functions and closures as parameter sets:

func plus(a: Int, b: Int) -> Int {return a + b}
let xx = (2, 3); let yy = (5, 9)
plus(xx)
plus(yy)

Best of all, you can combine these approaches to zip and then use the tuples in a function call like this:

map(zip([1, 2, 3, 4], [5, 6, 7, 8])){plus($0)}

Isn’t that cool for a boring Sunday?

Swift: My favorite Playground feature of the week

As I code and test, I like to keep ongoing notes in text format. Normally, I add these to my workspace and remove them from build phases to ensure they don’t ship with my app. With playgrounds, I just discovered an entirely new approach and thought I’d share that with you.

In the File Navigator, select the Resources folder and type Command-N (File > New > File). Xcode automatically creates a new text file for you, places it into the Resources folder and opens a text field for you to edit its name.

Screen Shot 2015-03-19 at 11.48.41 AM

The notes file is bundled into the playground, so it travels with it, keeping my journal in-place for easy reference.

As I just discovered this, I didn’t get a chance to put this tip into the playgrounds book. I’m hoping once I figure out how to revise the book, it will be in the next version.

 

And about that…

People are mostly buying not borrowing the book and I’m timid about putting out a completely new version knowing they’d have to re-purchase to get the update.

What do you think about just emailing me when (if?) I put out a second version if you’ve already bought the first? There aren’t that many people who have bought this thing so far, so it wouldn’t be too much of a hassle.

I’d also love to hear what people have to say about switching over to iBooks instead. The KDP exclusivity clause prevents this with the Playgrounds book for 90 days but I could for any other titles. And iBooks does have auto-update.

Of course, given the sales numbers, it might not be a brilliant idea to try to go it alone for this kind of niche book except for a pure passion project like the Playgrounds book.

What do you think?

Swift: Vroom vroom fast playgrounds

Read more about Swift Playgrounds in Playground Secrets and Power Tips

You may have already discovered that while playgrounds are cool, convenient, and fun, they’re not exactly speedy. The playground’s rich interactive environment and copious feedback mechanisms produce significant overhead.

A playground’s biggest computation load is its logging. Eliminate that feedback and you can make your playground zing with efficiency. Here’s how.

Beta 3 introduced separate source files: files that are embedded into the playground bundle, and which do not require a module framework. These files aren’t just convenient for clearing up the workspace presentation, they also provide a way to significantly reduce execution overhead.

Consider the following code. When executed in my playground, it took almost 36 seconds to run.

func slow () {
    var a = 0
    for i in 0...100000 {a = a + 1}
}

By moving this function to a bundled Swift source file and calling it from there, that time shrank down to just 0.0059 seconds compared to the 35.9876 seconds when defined in the playground. Here’s how I timed that execution.

public func timetes(block:()->()){
    let date = NSDate()
    block()
    let timeInterval = NSDate().timeIntervalSinceDate(date)
    println("Elapsed time: \(timeInterval)")
}

Ages ago, I implemented a playground spirograph system that, quite honestly, took forever to run. Today, I updated that project to use separate source. Instead of spirographs that each took minutes to create, updates were near instantaneous. The following video shows my playground in action.

Swift: Working around Sources playground bugs

The Xcode release notes are pretty clear on bugs that exists for a playground’s Sources folder:

Description: Sometimes Xcode will crash after editing a supporting source file for a playground and then viewing the playground itself. This happens when using the Project navigator to move back and forth between the playground and its enclosed files. (20094959)

Workaround: Open and edit the playground supporting source files in their own windows

Description: Playgrounds with supporting source files sometimes fail to execute, showing an error in the Console Output like: “Playground execution failed: error: Couldn’t lookup symbols: __TF16EnrichMe_Sources2hiFT_T_ __TF16EnrichMe_Sourcesau2piSd”. (20100043)

Workaround: View the supporting source file, then view and re-execute the playground

Description: Playgrounds with supporting source files sometimes fail to execute after changing the name of a function in the support file. You may see an error in the Console Output like: “Playground execution failed: MyPlayground.playground:6:1: error: use of unresolved identifier ‘myFunc’”. (20109247)

Workaround: Quit and relaunch Xcode. You may then need to view the supporting file, then view and re-execute the playground

There’s also a problem where new files are simply not recognized, and any material you add is ignored.  When this happens quit and relaunch Xcode. This keeps biting me when I develop code in the playground and then create a new Swift source file, paste the code in, and try to access it from the playground.

Hopefully this post will help you avoid the wasted time I spent.

 

Swift: What’s the best way of invoking a callback selector?

“M” asks: “What’s the best way of invoking a callback selector? I’m overriding an ObjC method that takes a target/selector/argument combo, and performSelector is not available in Swift”

Answer: Use NSThread to perform the selector on an ObjC class instance.

class MyClass : NSObject {
    func hello() {println("Hello")}
}

var instance = MyClass()
var selector = Selector("hello")
NSThread(target: instance, selector: selector, object: nil).start()

Warning: this doesn’t run on the main thread. (You can use main() instead of start() off label to achieve this but it seems iffy and undocumented.) Of course, a much better answer is to use closures wherever possible.

Implicit unwrappage and nil checks

With apologies to the Rolling Stones, failable initializers enforce the you don’t always get what you want rule. For example, NSURL(string:”blah:/123\\zd”) or UIImage(named:”notarealresourcename”) both return nil instead of wrapped instances. There are several early-return ways to deal with this reality.

I’m specifically interested in hearing thoughts about the following pattern, which goes like this:

let x : SomeType! = constructor(...args...) // impl. unwrap.
if (x == nil) return
...use x...

The implicit unwrapping applies when the variable is first accessed and not during the nil check. If you omit the nil check (something that the compiler does not check for) you’re going to run into trouble when using x. Which sort of defeats the whole safety thing.

Here’s an example. This function compiles, runs, works.  If you comment out the nil check line, it still compiles, still runs, still works so long as the image returned is valid. but call it it with a non-existent image and it’s crashsville.

func image(name:String) -> Bool {
    var image : UIImage! = UIImage(named:name)
    if (image == nil) {return false}
    println(image.size)
    return true
}

So how do you feel about this pattern? Is it fundamentally different from this?

let failable : Type? = constructor(...args...)
if (failable == nil) return
let unfailable : Type = failable! // unwrap
...use unfailable...

It uses fewer variables and fewer lines, but is it improved substantially? I’d like to know what you think.