The amount of work it took to port this to Swift (and pure Swift at that) was simply ridiculous.
First the good bits: Swift constructs like tuples, reduce and map made some code a lot nicer. My subpath length code looked like this: “return pairDistances.reduce(0.0, combine: {$0 + $1})”, where pairDistances were built from a generic array function that combined adjacent elements into 2-tuples and then combined into distances.
And the less good bits. You can’t compare CGPathElementType instances, so you have to use “.value” everywhere. CGFloat-land residents don’t live happily in Double-world.
And the really bad bits. You can’t use CGPathApply at all because reasons and CGFunctionPointers. So I ended up parsing the string descriptions of Bezier paths. No, really.
I designed everything so when Swift does support UIBezierPath decomposition properly, I have all my BezierElement structures in place, ready to go. Until then, this is a bandaid.
Ages ago, I put together a solution for tuplizing if-lets. Today, I finally got to give them a workout. Here’s what they looks like in practice. Before interpolating the cubic Bezier curve in the path element, I perform an if-let across four different optional values. If any are nil, the entire if-let fails and the statement shortcuts, just like a default if-let construct would.
case kCGPathElementAddCurveToPoint.value:
if let (currentPoint, point, controlPoint1,
controlPoint2) = tupled(current?.point, element.point,
element.controlPoint1, element.controlPoint2) {
for index in 1..<numberOfBezierSamples {
let percent = CGFloat(index) / CGFloat(numberOfBezierSamples)
let newpoint = CubicBezierPoint(percent, currentPoint,
controlPoint1, controlPoint2, point)
results += [newpoint]
}
results += [point]
current = element
}
break;
Lily Ballard helped me figure out the details of the solution. You can examine the source in this gist. Let me know if you find it at all useful.
Update: Yes, in Swift 1.2 you can combine if-let clauses with multiple tests as I described in this post. Here’s an example:
if let x = x, let y = y, let z = z {
println("All Okay")
} else {
println("At least one nil")
}
Developer Raffael Hannemann is a CS student, recipient of a WWDC 2014 scholarship, and has developed DailySales to help developers track their iTunes Connect sales figures. His app integrates into Yosemite’s Today View, which is a nice change from other solutions that offer stand-alone apps or take up precious menu bar space.
If TUAW were still up and running, DailySales would probably be an app that I’d look at and then, to be honest, pass on reviewing. It’s student-written, student-quality, and full of good intentions but it offers a minimum to distinguish itself from other competing products in the market place. However, TUAW is no longer up and running, I don’t have an editor to be responsible to, and Hanneman’s email made a great pitch.
The set-up procedure is a bit of a pain. You have to move past endless screens of legalese. You have to install Java because this requires Java to use Apple’s Autoinjestion class, rather than scraping the iTunes Connect website. It wasn’t a particularly big burden to get started but it wasn’t turn-the-key-and-get-going either.
But once you get past the painful setup, the app works. I’ve had it running over the weekend and I find that it well matches Hannemann’s initial pitch: that the app is “decent and convenient”.
The presentation is pleasant and unobtrusive. I do wish I could put in a time-out, like “don’t check more often than once an hour or twice a day”. I have other material I use the Today view for, and having the pane update each time is visually distracting.
The app has failed to update a number of times. On these occasions, it directed me to look at the console for errors: (Click to enlarge.) So it’s not always smooth sailing.
Like other apps in this arena, Hannemann recommends that you set up a sales-figures only account at iTunes connect for extra security, and your credentials are stored using the system keychain.
All in all, I find Daily Sales to offer a promising beginning to a potentially solid application. It fills a need that many developers encounter, and its $5.99 sales price makes it affordable compared to the competition.
You can learn more about Daily Sales and Hannemann’s other software at his WeAreYeah website.
Amazon emailed me over the weekend, stating that my appeal had been reviewed and declined: content updates of this magnitude can affect the reader’s user experience (invalidating highlights, bookmarks, and notes), Amazon limits its updates to quality issues that “negatively affect the overall reading experience.” The spokesperson added, “Currently, we don’t have the option to update content in regard with content expansion.” They promised to consider to “consider [my] input as we plan further improvements”.
I’ve asked them if I can withdraw early from my Select commitments in order to push this extra material out. If they say yes, I’ll be able to revise and publish on iBooks using the same title and cover art (which I love). If not, I’ll probably have to create a secondary work that is not in direct competition with Playground Secrets for at least another 70 days or so.
There are a few other options and I’d like to know what you think about them? Here’s a poll. Please let me know. Thanks!
My general rule of thumb with anything written by Oliver Drobnik of Cocoanetics fame is this: Drop whatever you’re doing and go read it. So when Oliver offered me a chance to look through his latest, a book entitled “Barcodes with iOS”, I jumped at the opportunity. (Before I go any further, I should mention that my latest book includes about 7 or 8 pages of barcode development coverage. In some vast distant galaxy where lawyers rule, that might matter. Full disclosure.)
Barcodes with iOS includes nearly 250 pages of expansive coverage of everything you might ever want to know about barcodes: their history, APIs, AV Foundation integration, who they date, what they wear to parties, and so forth. I’m being a little facetious, but there is a lot of information here for a topic that many developers may simply add to an app one afternoon and then never think about again in their lives.
Fortunately, this is a Drobnik book, which means many gems scattered among the barcode fluff (Fun fact: did you know that the first barcodes date back to World War II and were developed to help scale increase demands from a newly invigorated economy? Neither did I!) The very best bits deep dive into Passbook and beacons and other technology specifics.
When Drobnik starts talking deep-tech, that’s when things get good. In a way, I really wish the book had focused more on specific solutions rather than trying to cover every single fact related to barcodes, because the material that has to do with step-by-step development shines.
You’ll probably want to scan through the book’s table of contents before purchase, to find which bits you’ll want to focus on. Barcodes with iOS is currently selling for about $37 over at Amazon.
You’re looking at the contents of playground bundle that I was working on yesterday. That playground.xcworkspace file is new.
New to Beta 4, an xcworkspace contains all the details of how you last left your windows — which inspectors were open, how you set up your panes, and so forth.
Right now, the file isn’t being created all the time. This will likely get fixed soon. I’m told it’s supposed to be automatically established on your behalf. I find if I hop into the bundle and create a playground.xcworkspace folder manually and re-launch the playground, that everything kicks into place.
My only concern here has to do with the extra content being shipped with the playground. Playgrounds play two critical roles in SwiftWorld: learning and sharing. With sharing, I’d imagine I’d only want to include the cleanest material, without all the XCUserData stuff that crufts up in a workspace. Perhaps Apple might include a “prepare for shipping” option that cleans that up and archives it for you.
Starting in the latest betas, playgrounds have introduced a Markdown-like commenting standard for creating rich text interactive documents. This support replaces the earlier approaches Apple used to create the Guided Tour and SpriteKit Balloons walkthroughs that got people so excited about mixing interactive code with descriptive overviews
Each playground can now be shared as a single stand-alone document, with its support material embedded directly into the file. I’ve put examples up on github (the filters and OSX playgrounds) if you’d like to see what this technology looks like in its current form.
As I’m learning the new system, it’s making me focus on what it takes to design an engaging document. There are many practical uses for playground documents. You might teach algorithms, document an API, or provide usage examples for a particular technology. In each case, you build a narrative with live embedded code segments interspersed in the text.
At the same time, playgrounds also tell stories. A well-designed playground expands your user’s experience beyond source code comments. Source code, no matter how well annotated, doesn’t provide the same natural flow or the opportunity to explore the way a playground’s interactive document does.
So what does it take to accomplish this? Here are some preliminary thoughts.
The playground has to focus on the interactive. Consider how your user might adjust and interact with your code. Provide text-sourced hints on what to do and what the user should expect to happen as they do so. Suggest tweaks and adjustments your user might use to explore.
A playground should step outside of a documentation page and bring something to the table that you cannot offer in the existing medias of print, web pages, and ebooks. Interactivity and live code interpretation are what set playgrounds apart from these other information delivery platforms.
The playground should satisfy the senses. Offer your readers something beautiful that goes beyond simple text descriptions. Whether animating with SpriteKit or building simple UIImage instances, integrating programmatic aesthetics elevates the experience from (if you don’t mind me abusing a metaphor) a PowerPoint to a Keynote experience.
Distinguish reference from pedagogy. Differentiate your narrative from code comments. A playground’s rich text may share markup tasks with Quick Help but their underlying goals are distinct.
Quick Help annotates symbols for easy reference. Playground documents instruct in an interactive environment with immediate, live feedback. One is a reference materials task, the other is a guide task. The language, the structure, the examples, and the content should follow from those goals, with a playground offering a far richer set of descriptions and suggestions intended to teach as well as showcase.
So what do you think? Are there design points that I’ve missed? Or am I simply wrong about some of these suggestions? Please ping me by email or twitter or leave a comment and let me know.
I finally figured out how to get a nib/xib loaded into a playground and use it to power an app menu. It’s ridiculous how long this took and how simple the solution turned out to be.
Each playground, regardless of whether you’re building iOS or OS X code, runs as a tiny independent app on your computer. You can find that executable, and the app it is running in by peeking at NSBundle.mainBundle().executablePath.
Playground apps are tiny. OS X versions consist of a minimal bundle with a stripped-down Info.plist, a Resources folder, and a MacOS executable.
You can throw a xib file into your Resources, but the playground cannot read it or run it because it’s not in compiled form. Today, I (finallly!) thought of using ibtool to pre-compile my MainMenu.xib file into nib and then load that. When you install Xcode’s command line tools, ibtool gets added to /usr/bin. So all you need to do to compile your nib is issue the following command:
ibtool --compile MainMenu.nib MainMenu.xib
Throw that resulting nib into your playground’s resources folder and you’re ready to load it up.
The trickiest bit was trying to get all the unsafe autoreleasing mutable pointer stuff working. Swift is like a perfect haiku. It all looks simple and obvious when you’ve finished writing it but getting it debugged is a pain. The answer, by the way is this, which hopefully people will be able to google up without having to go through an hour or two of tweakage:
var array = NSArray()
var outputValue = AutoreleasingUnsafeMutablePointer<NSArray?>(&array)
NSBundle.mainBundle().loadNibNamed("MainMenu", owner: nil, topLevelObjects: outputValue)
A few further points:
I built a simple compile command line shell script so I don’t have to remember the order of the files or the arguments for ibtool. You can see it in the video in the Resources folder.
Add your xib source into your Resources as well as your compiled nib. You can then edit the xib using Xcode editors directly from the playground workspace. You still have to compile outside it. I keep a terminal window open to simplify the process.
Every now and then Xcode automatically moves things around, so use a full path in the terminal. Then use the terminal’s history to re-issue the same command as needed:
cd /Users/ericasadun/Desktop/Playgrounds/X\ -\ Playgrounds/OSX\ Menu.playground/Resources ; ./compile
Don’t compile when your nib is in use. Comment out the XCP indefinite execution line and the loadNibNamed line, and then compile in place from the command line.
You can’t much in the way of binding in your xib but you can design stuff there and then add the targets and behavior in the playground.
Yesterday, Kindle Direct Publishing responded to my request to update the book with the changes that I submitted on the 19th. They state that updates should be limited to correct quality issues and not to expand content.
“When a book undergoes significant changes, a customer receiving an updated version can no longer view any highlights, bookmarks, or notes that they made and they lose their furthest reading location.” I’ve asked for a review, which they will complete by March 31st, to decide whether or not they’ll push the changes I’ve uploaded.
Oddly enough, they went ahead and push changes to just my account so I could confirm the content changes. I had bought a copy to act as a tunnel canary and was hoping to use it to determine when any updates went live.
Of course, Apple’s iBooks’ update policy keeps looking more and more attractive. But that might just be grass-is-greener-syndrome. I have no experience yet trying to update an iBooks title. I’m working on a very short book on closures, so my next experiment will probably go iBooks. The Playgrounds exclusivity clause ends on June 10th, right around WWDC.
Once again, thanks everyone for your support as I explore: everyone who has been sending feedback via Twitter, email, and comments. And an especially big thanks to everyone who has bought or borrowed the book.