Xcode Playgrounds are great for trying out code quickly, or testing out a new API or framework. They can also be a wonderful form of interactive documentation.

Today we'll look at a few ways we can write our own interactive docs using rich comments in Xcode Playgrounds.

One of the primary ways we'll turn our Playgrounds into documentation is through rich comments.

Playgrounds have two "markup" modes: raw vs. rendered. As their names suggest, each mode specifies whether Xcode should "render" rich comments in our Playground, or make them editable.

We'll begin by creating a new Playground. Then we'll select Editor > Show Rendered Markup to switch modes.

Right away, we can see the top comment changes from:

//: Playground - noun: a place where people can play

To this:

We can write our own rich comments by adding a : symbol after the // in any comment to convert it to a rich one. Neat!

Rich comments' Markup syntax is heavily inspired by Markdown. (It's basically just Markdown).

Apple has a syntax guide, but here's the idea:

//: We can write regular text, **bold** text or *italic* text.
//: ## Headers

We can include links in our rich comments:

//: A great [link](http://littlebitesofcocoa.com).

We can allow readers to navigate pages with some special links:

//: [Next](@next) or [Previous](@previous)

Or link to specific pages (names will need to be URL encoded):

//: [View Models](View%20Models)

We can even include images in our rich comments. We just need to first add them to our Playground's Resources group, then use Markdown's normal image syntax:

//: ![](playgrounds-rock.gif)

Topics

#136: XCPlayground Basics 🎪

Topics

Xcode Playgrounds arrived in Xcode 6. They're a great way to try out some code quickly, or to learn about an API or library through interactive documentation.

Playgrounds are unbelievably useful out-of-the-box, but today we'll look at a framework called XCPlayground that makes them even better.

XCPlayground ships with Xcode. We can import it in our Playgrounds to enable all sorts of interesting functionality.

We'll begin by creating a new Playground. We can do this by selecting File > New > Playground… from Xcode's menu (or ⌥⇧⌘N). Then we'll import XCPlayground:

import XCPlayground

Let's start with one of the most common reasons for importing XCPlayground, indefinite execution. By default Playgrounds execute the code in each page, from top-to-bottom, then they stop executing. We can change this behavior like so:

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

This will allow any asynchronous code we have in our Playground to continue running indefinitely.

Once our code is done, we can call:

XCPlaygroundPage.currentPage.finishExecution()

Another great use for Playgrounds is prototyping views. We'll need to enable needsIndefiniteExecution first, then:

XCPlaygroundPage.currentPage.liveView = containerView

We set the current page's liveView property to any UIView or NSView and it will appear visually in the assistant editor.

If the assistant editor isn't already visible, we can open it by selecting View > Assistant Editor > Show Assistant Editor from Xcode's menu (or ⌥⌘↩︎).

Similarly, we can add a value to the assistant editor (including a corresponding label so know what's what) like this:

XCPlaygroundPage.currentPage.captureValue(containerWidth, withIdentifier: "Width")

We'll be looking at more neat features of Playgrounds soon. Please send your favorite Playground tips to hello@littlebitesofcocoa.com!

Weekly Sponsor: Dringend 🛠

HUGE thanks to Dringend for sponsoring this week's bites! Dringend is an app for iPhone and iPad that allows us to create, develop, and even run our apps right on our iOS devices. We've all dreamed about Xcode for iOS, and turns out it's already here, with Dringend. Let's take a look:

Dringend lets us build and run our apps directly on our iOS devices. We can see warnings/errors during builds, then run the app right on the same device we're editing its code on!

Dringend works with standard Objective-C and Swift Xcode projects. We can browse them, open files, and edit them. Just like in Xcode on the Mac. Let's step back a second to appreciate how cool this is. We've opened our Xcode project, built it, and run it, all on our iOS device!

Full git support is also included. Dringend let us push, pull, commit, switch branches and even has submodule support. Additionally, Dringend has full support for syncing projects we stored on Dropbox!

Last but certainly not least, Dringend has a full-featured code editor with syntax highlighting for Swift + Objective-C, full find/replace support, and even project-wide file search with regex support!

Dringend is being actively developed, with features like Storyboard support coming down the pipeline now. Working on Xcode projects on iOS like this simply feels like magic 🎩. Dringend is an amazing piece of software. Get it.

Dringend is available to download now at dringend.cc.

Topics

#135: Fastlane 🤖

Topics

It's another fastlane Friday here on LBOC! We've covered a few of the individual fastlane tools so far, but today we'll look at fastlane itself. It gives us a single command that brings together all the various tools in the suite like gym, snapshot, deliver, etc into one streamlined workflow. Let's get started.

We can of course continue to use each of the fastlane tools individually, but using fastlane allows us to use just one tool that connects not only each of the tools in the suite, but also integrates with other third-party tools like CocoaPods and xctool.

fastlane provides a fantastic in-depth Getting Started guide, but to get things going quickly here's the basics:

We'll begin by installing fastlane, this will install all the fastlane tools, including all the ones we've covered here, wrapped into one simple tool.

gem install fastlane

Then, we'll simply run fastlane init in the root directory of our project.

fastlane's setup assistant will ask us a few questions about our app, then it will create all the configuration files for us, where we'll be able to customize each the tools default settings as well as define our “lanes”.

After completing the intial setup process, we can start to customize our new Fastfile (which was created for us automatically). fastlane is built around the concept of “lanes”. Here's one that deploys to the App Store:

lane :appstore do
  increment_build_number
  cocoapods
  snapshot
  sigh
  deliver
  slack
end

We can run all of these tools now, each one after another by simply running fastlane appstore. Nice!

Notice commands like cocoapods and slack are here. These are some of the third-party actions mentioned earlier.

This is where fastlane's awesome community really shines. There's already 120+ actions ready to use for services like s3, slack and crashlytics, as well as commands for things such as bumping the build number, or even collecting input from the user. Neat!

More info about fastlane can be found at git.io/fastlane

Formatting strings is one of the most common tasks in building software. It's usually not that complex, but it can be tempting to cut corners.

When working with things like currency or street addresses, having a robust formatting system in place can be crucial in ensuring our app works well all over the world.

Today we'll look at Format, a library from Roy Marmelstein that can help us achieve all this with ease.

Format starts by extending Swift's number types to add a format function. We can call this on any number (even literals) and it will return a String with our desired format:

134.format(Decimals.Two) // => "134.00"

Format makes localizing a breeze. It uses the device's current locale by default, or we can render a specific one:

let gb = NSLocale(localeIdentifier: "GB")
87.format(Currency.GBP, locale: gb) // => "£ 87.00"

Ordinal numbers can really help class up the joint:

134.format(General.Ordinal) // => "134th"

Format can format in all sorts of interesting ways, for example:

10.11.format(General.SpellOut) // => "ten point one one"

Numbers are cool, but what about addresses? Almost every nation has a slightly different convention for how they format street addresses.

Format wraps CNPostalAddressFormatter from the Contacts framework (Bite #24) to make formatting addresses quite simple:

AddressFormatter().format(
  "1 Infinite Loop", 
  city: "Cupertino", state: "CA", postalCode: "95014", 
  country: "USA", ISOCountryCode: "US")

// => "1 Infinite Loop\nCupertino CA 95014\nUSA"

Format also extends CLPlacemark, adding a function to format that class's addressDictionary property. Users expect things to look familiar. Never underestimate the power of good localization.

More info about Format can be found at git.io/format

Topics

#133: Code Coverage in Xcode 🛠

Topics

Code Coverage arrived with Xcode 7. It can help us visualize which parts of our code are not being tested enough (or at all). Let's dive in:

Before we can take advantage of Code Coverage, we'll need to enable it for our project. It's off by default.

We'll begin by editing our scheme, then selecting Test in the sidebar, then enabling the Gather coverage data checkbox.

Now we'll run our tests by going to Product > Test in the menu (or pressing U). Then we can check out the test log where we'll find a new “Coverage” tab.

Xcode will display all the functions in our code with a bar graph indicating how well “covered” they are by our tests (We can mouse over to get an exact percentage). In our case, we are at 0%, since we don't have any tests. Yikes! Let's fix that by adding a simple test for a function on our PersonViewModel:

func testFullName() {
  let person = Person(firstName: "Han", lastName: "Solo")
  let personVM = PersonViewModel(person: person)
  XCTAssertEqual(personVM.fullName, "Han Solo")
}

If we run our tests again, and check the Coverage tab, we can see we now have 50% test coverage for our tiny example project.

Last but not least, Xcode will also give us a heads up with a red shaded area in the right gutter on lines of code that aren't covered by our tests. Neat!

Building a good authentication system is a lot of work. Instead of starting from scratch, it'd be great if we could build on top of some existing popular service, and allow our users to log in with their existing account there.

Today we'll check out SimpleAuth from Caleb Davenport. It provides an extremely easy-to-use way to implement social sign-in inside our apps. Let's take a look:

SimpleAuth is built around the concept of Providers. In this context, a provider contains all the code needed to talk to individual services like Twitter, Facebook, etc.

Let's add support for signing in with Twitter to an app. We'll start by adding the pod to our Podfile, then run pod install.

pod 'SimpleAuth/Twitter'

Then, we'll need a consumer key and secret from Twitter. We can get these by creating a new app on Twitter's developer portal.

Back in our Application Delegate, we'll configure SimpleAuth's Twitter provider with our info:

SimpleAuth.configuration()["twitter"] = [
  "consumer_key": "12345REDACTED",
  "consumer_secret": "ABCDETOPSECRET"
]

Finally, we can sign a user in like this:

SimpleAuth.authorize("twitter") { userDictionary, error in
  User(username: userDictionary["nickname"]).persist()
}

Then we can grab their Twitter username out of a user dictionary. (Which contains keys like uid, image, etc.) SimpleAuth uses these names to abstract away the different attribute names each service uses to represent these values. For example, the field uid always holds a unique user identifier and is present on almost all providers.

SimpleAuth ships with a ton of built-in providers (Twitter, Facebook, Instagram, Tumblr, Dropbox, Foursquare, etc.). It also makes it very straightforward to create our own providers, just in case we ever need to. Neat!

More info about SimpleAuth can be found at git.io/simpleauth.

We've covered Auto Layout quite bit, but so far we've only been using the classes and APIs that Apple ships. Today we'll start checking out some third-party libraries that can improve our experience when working with Auto Layout.

First up is Cartography from Robert Böhnke. Let's take a look:

Cartography takes the form of a sort of DSL for Auto Layout. It allows us to take conventional UIKit code like this:

view.addConstraint(
  NSLayoutConstraint(
    item: editButton,
    attribute: .Right,
    relatedBy: .Equal,
    toItem: launchButton,
    attribute: .Left,
    multiplier: 1.0,
    constant: -8.0
  )
)

And express it using a new constrain function:

constrain(editButton, launchButton) { editButton, launchButton in
  editButton.right == launchButton.left - 8
}

We can pass in up to 5 UIView or NSView instances at once, then a closure. In that closure, we'll use ==, >=, or <= operators to define constraints upon the attributes of the view instances. This can really help improve readability:

constrain(viewA) { a in
  // fixed sizes:
  a.height == 44

  // centering inside a parent view:
  a.centerX == a.superview!.centerX

  // inequalities:
  a.top >= a.superview!.top + 10
}

But wait, there's more! We can capture the created constraints like this:

let group = constrain(launchButton) { button in
  button.top  == button.superview!.top
  button.left == button.superview!.left
}

Then move that button by replacing the captured constraints like this:

constrain(launchButton, replace: group) { button in
  button.bottom == button.superview!.bottom
  button.right  == button.superview!.right
}

Additionally, it provides helper functions for aligning and distributing:

constrain(viewA, viewB, viewC) { viewA, viewB, viewC in
  align(top: viewA, viewB, viewC)
  distribute(by: 8, horizontally: viewA, viewB, viewC)
}

Cartography has shortcuts for edges and sizes, operators for setting priorities, and much more! More info can be found at git.io/cartography.

Weekly Sponsor: Hired 🏢

My continued thanks to everyone at Hired for sponsoring this week's bites. Finding a good job can be a daunting task. Today we'll take a look at how we can use Hired to save our sanity, and find a great job in the process. Let's dive in.

We'll start by entering our email and answering some basic questions:

That's it. Hired will then work with 2,500 pre-screened companies (both big and small) in 12 major metro areas to try find us a great job. Software engineers and designers on Hired can get 5+ job offers in a single week. Each offer will include salary and equity details upfront.

If we get a job through Hired, they'll give us a $2,000 "thank you" bonus! If we use the link littlebitesofcocoa.com/hired to sign up, Hired will double that, giving us a $4,000 bonus when we accept a job!

More Reasons to Use Hired

Full time or contract opportunities are available
View offers and accept or reject them without talking to anyone.
Completely FREE + no obligations ever.

Hired is the real deal. They have solved some very real problems and fixed this historically messy process. Looking for a job? Don't waste time, sign up for Hired today so you can get back to work!

It's another fastlane friday here on LBOC. Today we'll be looking at another awesome tool in the fastlane suite called scan. It provides an easy way to run the tests of our iOS or OS X app. Let's dive in.

Before we begin, let's look at why a tool like scan can be helpful.

Xcode ships with a great command line tool called xcodebuild that allows to do all sorts of interesting things to our projects from the command line. It can be a bit verbose to configure though, and its output isn't very readable at a glance.

There's other tools like xcpretty that can help improve this output, but they take a fair amount of configuration as well.

That's where scan comes in. It takes care of all of this (plus a lot more) in one simple command: scan.

We'll start by installing scan:

gem install scan

Then we run our tests at anytime like this:

scan

This is all we need for basics usage. scan will auto-detect things like our workspace, but we can always configure things as well:

scan --scheme "app-store"

Like other fastlane tools, we can run scan init to generate a new Scanfile, where we can store all our configuration options:

scheme "Spaceships"
clean true
output_types "html"

Other Features

📃 Displays nice output, stores original xcodebuild log in ~/Library/Logs/scan

📄 Can generate HTML, JSON or JUnit reports

📣 Can send well-formatted test results to Slack. Check out the slack_only_on_failure configuration option to only report failed tests.

scan also helps with resolving common Xcode oddities like duplicated simulators or simulators that stop responding. Finally, scan works great with tools continuous integration tools like Jenkins and services like Travis. Happy testing!

More info about scan can be found at git.io/scan

Page 24 of 38