We spend a lot of our time in Xcode. It's a huge app with tons of different panels and views to explore.

Today we'll look at some of the most helpful keyboard shortcuts in Xcode and how they can help us navigate around Xcode's interface more quickly and efficiently. Let's dive in.

Xcode's keyboard shortcuts can be tricky to learn (there's quite a few), but they are actually very intuitive (and usually guessable).

We can open any of the panes in the navigator area with ⌘1-7. We can toggle the whole navigator open and closed by pressing ⌘0.

We can do the same with the utility area (right side) using ⌘βŒ₯1-7 and ⌘βŒ₯0.

We can focus in the filter bar of the current pane with ⌘βŒ₯J.

We can toggle the debug area with βŒ˜β‡§Y, toggle breaking at breakpoints with ⌘Y. We can also pause/continue execute with βŒƒβŒ˜Y.

⌘-click symbols to navigate to them.

One of Xcode's most powerful keyboard shortcuts is βŒ˜β‡§O. This displays a Quick Open panel that certainly lives up to its name. Navigate with the arrow keys, then press β†©οΈŽ to open a file.

Hold down βŒ₯ when opening a file from this panel to open it side-by-side in the assistant editor. Then toggle the assistant with βŒ˜β†©οΈŽ and ⌘βŒ₯β†©οΈŽ.

Code Signing. The very mention of certificates or provisioning profiles can send chills up an iOS engineer's spine.

We've all been there. Just finished up a great first pass at a new feature, or finally ready to submit to the App Store and BAM! We're stopped in our tracks by a confusing error related to code signing.

Today's fastlane Friday is a big one. Yesterday, a new fastlane tool launched. It's called match, and it fixes code signing. Yes, really. Let's do this. πŸš€

Most iOS teams have separate code signing identities for each member. This means most iOS teams have tons of provisioning profiles, probably lots of duplicates, invalid ones, etc.

Adding new devices or renewing certificates can be a huge hassle, and only makes on boarding new team members slower.

With match, we can avoid these issues entirely. match allows us to share one single code signing identity across our development team.

We keep this single identity (and it's associated provision profiles) in one central location.

match automatically syncs our iOS keys and profiles using a simple git repository. It handles everything (i.e. creating certificates and profiles), while we retain complete control.

Let's setup match for a project. We'll start by creating a new Github repository to hold our certificates, profiles, etc.

We'll call it certificates and make absolutely sure it's set to be private!

Then, we'll install match locally:

gem install match

Next, we'll go into our project's main directory and run:

match init

We'll be asked for the URL of the repository we created earlier, then a Matchfile will be created to hold a few settings.

Next we'll run:

match development

match will create a new certificate and provisioning profile, and store them in our Github repo. They'll all be encrypted using openssl! πŸ”

In the future, when we get a new machine for example, we will only need to run that one command to pull down everything and install it all locally. Incredible. Setting up new machines or team members has never been easier (or faster πŸš—πŸ’¨)!

This is only a small taste of how helpful match can be! Check out the incredibly well done complete guide that covers everything from start to finish at codesigning.guide

Let's draw some strings! There's plenty of text-drawing capabilities in iOS and OS X, with full frameworks like Text Kit (or the lower-level Core Text) dedicated to the task. Today, we'll start looking at these capabilities by using Core Graphics and UIKit to draw a multiline string.

Sometimes we need to draw text ourselves, β€œmanually”. This can be helpful when optimizing for scrolling performance, or when complete customization is necessary.

First we'll need a view to draw into, we'll make a new UIView, and override drawRect.

Next, we'll start implementing our drawRect function with a few variables. We'll choose a font, then setup a paragraph style to make our text multiline, with some tall lines.

We'll also setup some drawing options to tell the system we want multiline text:

let textFont = UIFont(name: "Avenir Next", size: 17.0)!
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 1.2
paragraphStyle.lineBreakMode = .ByWordWrapping

let drawingOptions: NSStringDrawingOptions = [
  .UsesLineFragmentOrigin, .UsesFontLeading]

We'll save these off into a textAttributes dictionary. Next, we'll need to figure out what rectangle we'll be drawing our text into.

We'll use the boundingRectWithSize function to find out how tall it will be when constrained to the width of our view:

let textRect = (text as NSString)
  .boundingRectWithSize(
    CGSizeMake(bounds.size.width, CGFloat.max),
    options: drawingOptions,
    attributes: textAttributes,
    context: nil)

Then we'll just pass that calculated textRect into a call to drawWithRect:

(text as NSString).drawWithRect(textRect,
  options: drawingOptions,
  attributes: textAttributes,
  context: nil)

Attributed strings are a fantastic way to work with styled text on iOS and OS X. NSAttributedString is an incredibly full-featured API, but because of this, simple tasks sometimes require a fair amount of boilerplate code. Today we'll look at BonMot, a library from Raizlabs that simplifies the process of composing attributed strings.

BonMot takes the form of a set of chainable functions that we can use to compose attributed strings:

let fancyQuote = "Traveling through hyperspace ain't" +
                 "like dusting crops, farm boy.\n" +
                 " β€” Han Solo"

quoteLabel.attributedText = BONChain()
  .fontNameAndSize("AmericanTypewriter", 17.0)
  .lineHeightMultiple(1.8)
  .string(fancyQuote)
  .attributedString

BonMot will do all the heavy lifting of applying attributes and return a fully-formed NSAttributedString ready for use wherever we need.

We can use BonMot to concatenate multiple composed attributed strings:

let chain = BONChain()

chain.appendLink(BONChain().string("one fish"))
chain.appendLink(BONChain().string("two fish"), separator:commaSpace)
chain.appendLink(BONChain().string("red fish").textColor(UIColor.redColor()), separator:commaSpace)
chain.appendLink(BONChain().string("blue fish").textColor(UIColor.blueColor()), separator:commaSpace)

BonMot even supports the NSTextAttachment parts of the NSAttributedString API. We can generate an β€œimage next to a label” like this:

chain.appendLink(BONChain().image(ackbar))
chain.appendLink(
  BONChain()
    .fontNameAndSize("Futura-MediumItalic", 17.0)
    .string("It's a trap!"), separator:" ")

We've only scratched the surface here, BonMot has a ton of features to offer. More info about BonMot can be found at git.io/bonmot

Today we're looking at SwiftyBeaver, a library from Sebastian Kreutzberger that aims to improve Xcode's logging capabilities. Let's dive in.

After adding the library to our project we'll need to import the library in our AppDelegate. We'll also need to create a global log reference we can use throughout our app:

import SwiftyBeaver
let log = SwiftyBeaver.self

Then we'll need to tell SwiftyBeaver to log somewhere, let's set it up to log to Xcode's console and a log file:

let console = ConsoleDestination()
let file = FileDestination()

log.addDestination(console)
log.addDestination(file)

SwiftyBeaver is built around the concept of "destinations". Here we're adding one for the Xcode console, then another to log to a file in our app's documents directory.

Now, we can use our global log reference to log messages. There's functions for each of the different levels. Each will log its level in its own color:

log.verbose("Nothing really happened") // gray
log.debug("A thing happened") // blue
log.info("A good thing happened") // green
log.warning("A probably bad thing happened") // yellow
log.error("A definitely bad thing happened") // red

Both built-in destinations have a ton of configuration options allowing us to customize how we'd like our logs to behave. We can customize the format of log statements or change a file destination's location, we can even define our own destinations if needed!

More info about SwiftyBeaver can be found at git.io/swiftybeaver

App Transport Security was introduced with iOS 9 and OS X 10.11. It aims to make the network calls we make from our apps more secure by enabling many best practices like TLS 1.2 and forward secrecy by default. Today we'll take a closer look, and learn how to disable it if needed.

App Transport Security makes support for Transport Layer Security 1.2 and forward secrecy mandatory. It also requires certificates to have a SHA256+, ECC256+, or RSA2048+ signature. Don't worry if that sounds like gibberish, the idea here is that Apple will maintain ATS on an ongoing basis, keeping it always up-to-date with the latest security best practices and standards.

Apple is enforcing ATS by automatically "opting-in" the NSURLConnection, NSURLSession, and CFURL APIs (plus anything built on top of them).

This means these APIs will throw errors, and the connections will fail if we try to use them with a connection that doesn't meet all the requirements.

Unfortunately, not all connections we need to make in our apps will support ATS. In these cases, we'll need to tell the system to exempt these connections, and allow them to be made insecurely. We'll do this by adding some keys to our app's Info.plist:

We'll start by opening our Project's settings, then heading to the Info tab.

Then, we'll right click the list of keys, and choose Add Row. We'll use the inline plus buttons to continue adding and configuring rows until we end up with this:

There's also keys for allowing for lower minimum TLS versions, as well as not requiring forward secrecy.

It's encouraging to see Apple putting such an emphasis on securing our apps. App Transport Security is big step forward in making all of our apps safer for us and our users.

Weekly Sponsor: Dringend πŸ› 

A giant continued 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.

It's another fastlane Friday! Last week in Bite #135, we covered how to install and setup fastlane and an initial Fastfile. Today we'll look at how we can take our fastlane skills to the next level and customize our Fastfile using actions. Let's get started.

We briefly mentioned fastlane actions in Bite #135. Let's start by taking a closer look at them.

Actions are essentially build "steps". fastlane organizes these build steps into sets called lanes. Each action is responsible for a very specific part of the lane's larger task.

Let's add an action to a lane:

lane :beta do
  increment_build_number
  sigh
  gym
  pilot
end

By simply adding the increment_build_number action, we'll never need to manually bump our build number again!

Actions can accept options:

increment_version_number(bump_type: "major")

Or return values:

changelog = prompt(text: "Changelog: ")

There's actions for all of the individual fastlane tools we've covered.

We can install dependencies with actions like carthage and cocoapods. We can deploy with the pilot and deliver actions, or use hockey and crashlytics to upload to those services.

We can notify teammates with slack or archive each release with github_release.

We can even define lanes to bootstrap our dev environment using actions like install_xcode_plugin or dotgpg_environment.

We can "shell out" to a truly custom build script as well:

sh "./script.sh"

Simply put, actions are how to get the most out of fastlane. If we're doing something each time we build or deploy, there's a good chance a fastlane already has an action for it.

If not, we can make our own. Just like the Fastfile itself, actions are written in Ruby. We can generate a new one with:

fastlane new_action

Detailed documentation on all actions is available, and we can check out the full list of 120+ actions with:

fastlane actions

One of the most useful parts of Xcode Playgrounds is the way they allow us to visualize our code. We can click the Quick Look button, or insert a preview directly into our code with the Show Result button in the Results sidebar:

We can add visual representations to the assistant timeline using XCPlayground's captureValue function (Bite #136).

This can be incredibly handy for spotting problems quickly:

Tons of system types are supported like CGPath, NSURLs, and even many of SpriteKit's classes. These are actually the same representations that can be seen if we Quick Look something while debugging in Xcode.

We can add these capabilities to our own custom types (for both debugging and Playgrounds) by adding a function like this to them, returning a supported type:

func debugQuickLookObject() -> AnyObject? { return name }

This is great, but only works on types that inherit from NSObject and won't work for things like Swift structs. Also, even though we're adding this to our own type, we'll still need to return one of the built-in, Quick Look-able types supported by Xcode.

For more flexibility, let's look at XCPlayground's XCPlaygroundLiveViewable protocol.

This will let us visualize our own types by returning a view or view controller that will be shown in the assistant timeline when we capture a value:

extension Person : XCPlaygroundLiveViewable {
  func playgroundLiveViewRepresentation() -> XCPlaygroundLiveViewRepresentation {
    let vc = PersonLiveViewableViewController(person: self)
    return .ViewController(vc)
  }
}

Now, we can set our current page's liveView to a instance of Person directly, and we'll see our custom view controller appear in the assistant timeline. Neat!

XCPlaygroundPage.currentPage.liveView = Person()
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

We're continuing our look at Xcode Playgrounds today with CocoaPods. Let's see what it takes to import a CocoaPod into a Playground.

We'll begin by creating a new Xcode Project. Next, we'll head into our project's directory and run pod init to generate our Podfile. We'll open it up and configure it just as we usually would:

platform :ios, '9.0'
use_frameworks!  
link_with 'Spaceships'

pod 'Alamofire'

Then we'll run pod install to generate the Workspace file for our project and install our pods. We're almost done, next we need create a new Playground and add it to our project.

Finally, we need to add our Playground to our Podfile's link_with directive (only its name, not the .playground extension):

link_with 'Spaceships', 'scratch-pad'

We'll run pod install one more time and we're done. We can now import the pod we installed into our Playground and try it out. Neat!

Page 23 of 38