Topics

#196: Apple Pay Basics 💰

Topics

Today we'll take a look at how to add Apple Pay to an app, letting users buy things. Let's begin.

Our first step is to go to Project > Capabilities > Apple Pay and flip the switch to "on". This will configure our project to use Apple Pay and create a Merchant ID for us automatically (We'll use this later when configuring our payment request). Then, we'll importing PassKit, and add a button to kick off the process:

let paymentButton = PKPaymentButton(type:.Buy, style: .Black)
paymentButton.addTarget(self, action: "paymentButtonTapped", forControlEvents: .TouchUpInside)

Next, inside paymentButtonTapped, we'll create a payment request, andan authorization view controller.

func paymentButtonTapped() {
  let request = PKPaymentRequest()

  request.merchantIdentifier = "merchant.com.magnus.apple-samplecode.apple-pay.Emporium"

  request.countryCode = "US"
  request.currencyCode = "USD"

  request.supportedNetworks = [PKPaymentNetworkVisa, PKPaymentNetworkMasterCard]
  request.merchantCapabilities = .Capability3DS // 3DS or EMV

  request.paymentSummaryItems = [
    PKPaymentSummaryItem(label: "Little Bites of Cocoa Volume 1", amount: NSDecimalNumber(double: 39.99), type: .Final),
    PKPaymentSummaryItem(label: "Shipping", amount: NSDecimalNumber(double: 5.99), type: .Final),
    PKPaymentSummaryItem(label: "Tax", amount: NSDecimalNumber(double: 3.79), type: .Final),
    PKPaymentSummaryItem(label: "Total", amount: NSDecimalNumber(double: 49.77), type: .Final)
  ]

  let authVC = PKPaymentAuthorizationViewController(paymentRequest: request)
  authVC.delegate = self
  presentViewController(authVC, animated: true, completion: nil)
}

Then we'll implement the authorized delegate function:

func paymentAuthorizationViewController(controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, completion: (PKPaymentAuthorizationStatus) -> Void) {
  print(payment.token)
  completion(.Success)
}

Now that we've got the groundwork laid, we can sign up for a payment provide like Stripe.

Essentially we'll just send the payment.token we got to them, wait for them to process, then call the given completion closure with their result.

Weekly Sponsor: Hired 🏢

A continued huge thanks to the folks at Hired.com 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.com 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 over 3,000 pre-screened companies (both big and small) in 13 major metro areas (North America & Europe) 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.

We can view interview requests and accept or reject them before talking to any company. If we get a job through Hired, they'll give us a $1,000 "thank you" bonus!

Even better, if we sign up through this link: littlebitesofcocoa.com/hired, they'll double our bonus to $2,000!

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!

Topics

#195: Mastering UIColor with Hue 🌈

Topics

Today we'll check out a library from Hyper called Hue. It gives us all kinds of helpful utilities for working with colors, let's dive in.

First, Hue helps us easily can parse colors from hex strings:

let beige = UIColor.hex("#FEFAF1")
let lightBrown = UIColor.hex("#AB9372")
let brown = UIColor.hex("#8C5637")

In addition, Hue can analyze colors:

beige.isDark // returns false

Hue can easily create gradients. Here we'll take a couple of colors, and create a CAGradientLayer from them:

let gradient = [lightBrown, brown].gradient { gradient in
  gradient.locations = [0.25, 1.0]
  return gradient
}

Finally, Hue can analyze a UIImage, returning a tuple of colors it finds inside.

let (bg, primary, secondary, _) = albumArt.colors()

It provides background, primary, secondary and detail colors from the image. We can the use these to create interfaces such as the one found in iTunes on OS X, where the colors in the UI match those found in the album artwork. Neat!

More info about Hue can be found at git.io/hue

Ever since 1983 when Matthew Broderick's IMSAI 8080 began speaking out loud, we've dreamed of computers that can have conversations with us.

In iOS 9, Apple added the ability to synthesize speech using the high-quality 'Alex' voice. Sadly it's only available on US devices for now, but that's sure to change. Let's try it out:

guard let voice = AVSpeechSynthesisVoice(identifier: AVSpeechSynthesisVoiceIdentifierAlex) else { return }

let synth = AVSpeechSynthesizer()
synth.delegate = self

let utter = AVSpeechUtterance(string: "Would you like to play a game?")
utter.voice = voice

synth.speakUtterance(utter)

We start by making sure 'Alex' is available, then we make a new synthesizer. Next, we create an AVSpeechUtterance, and set it's voice. Then, we simply tell the synthesizer to speak! Very cool.

Even cooler, we can implement one of the optional functions of AVSpeechSynthesizerDelegate to get live progress callbacks as each word is spoken. Neat!

func speechSynthesizer(synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) {
  print(characterRange)
}

Topics

#193: UIView Transition Basics 🐛

Topics

Most iOS developers have used the fantastic UIView animateWithDuration family of functions. But there's another, slightly-lesser known static function on UIView that can help us transition like a pro. Let's check it out:

The function we'll be trying is transitionWithView. At first glance you'll see it's takes the same duration, options, and closures as its more-popular sister function.

However, instead of applying our changes over time, this function will (conceptually) take a snapshot of our view before and after the work in the animations** closure** is performed, then visually transition from the first snapshot to the second.

func flip() {
  flipped = !flipped

  UIView.transitionWithView(
    button,
    duration: 0.3,
    options: .TransitionFlipFromTop,
    animations: {
      self.button.setTitle(self.flipped ? "👎🏻" : "👍🏻", forState: .Normal)
    },
    completion: nil
  )
}

The type of transition depends on the animation option we pass in. We can do everything from simple cross-dissolves (fades), to fancy 3D flips. Super handy for simple transitions.

Download a sample project at j.mp/bite193. In it, we flip a thumbs up emoji using this incredibly simple technique.

Topics

#192: Being a Good Low Power Mode Citizen 🔋

Topics

Low Power Mode debuted in iOS 9. It's a great way to get another hour or two of use out of a device.

When Apple first introduced this functionality, they touted how the feature turns of lots of little things that contribute to the battery savings.

It turns out we can actually provide these same savings in our own apps. Today we'll learn how. Let's get started:

The first way we'll interact with Low Power Mode is through a property on NSProcessInfo.

Here we're working on app that displays animated GIFs. When the user stops scrolling, we automatically begin looping the GIF. However, if the user has Low Power Mode enabled, we'll save a few CPU/GPU cycles by requiring the user to tap to start the animation:

func userStoppedScrolling() {
  guard NSProcessInfo.processInfo().lowPowerModeEnabled == false else { return }
  gifView.beginPlaying()
}

We'll finish up by registering for this NSNotification:

NSNotificationCenter.defaultCenter()
  .addObserver(self, 
    selector: "lowPowerModeChanged:", 
    name: NSProcessInfoPowerStateDidChangeNotification, 
    object: nil
  )

Then, inside lowPowerModeChanged, we can check with NSProcessInfo again. Now when a user returns to our app, we'll start/stop visible GIFs based on the Low Power Mode state. Neat!

Today we'll check out a library called Tactile. It's a "Swiftier" way to respond to gesture recognizers and control events. Let's get started.

Tactile gives us a safer, more idiomatic way to install/react to gesture recognizers (Check Bite #38 for gesture basics).

In it's simplest form, Tactile works like this:

let tapGR = UITapGestureRecognizer()
tapGR.numberOfTapsRequired = 2

view.on(tapGR) { (tapGR: UITapGestureRecognizer) in
  // ...
}

We can also react to specific state changes:

let panGR = UIPanGestureRecognizer()
view.on(panGR, [.Began, .Ended], beganOrEnded)

func beganOrEnded(panGR: UIPanGestureRecognizer) {
  // ...
}

Tactile also adds similar functions to UIControl:

button.on(.TouchUpInside, tapped)
button.on([
  .TouchUpInside: tapped,
  .TouchUpOutside: cancelledTap
])

We can attach a single recognizer to multiple views:

viewA.on(tapGR, { tapGR in /* ... */ })
viewB.on(tapGR, { tapGR in /* ... */ })

Last but not least, we can remove all recognizers with

view.off()

just one with:

view.off(tap)

or all of a type with:

view.off(UITapGestureRecognizer.self)

More info about Tactile can be found at git.io/tactile

Weekly Sponsor: Hired 🏢

A continued huge thanks to the folks at Hired.com 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.com 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 over 3,000 pre-screened companies (both big and small) in 13 major metro areas (North America & Europe) 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.

We can view interview requests and accept or reject them before talking to any company. If we get a job through Hired, they'll give us a $1,000 "thank you" bonus!

Even better, if we sign up through this link: littlebitesofcocoa.com/hired, they'll double our bonus to $2,000!

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!

Today we'll follow up with another Bite in our localization series (sort of). Units of measurement are important to get right when localizing our apps for different cultures.

Today we'll look at a library from Khoa Pham called Scale that can help us convert between different units of measurement (for either localization or just-for-fun purposes). Let's begin.

Scale makes it incredible simple to work with different units of measurement:

let length = 5.kilometer + 7.meter  // 5,007 meters
let weight = 10.0.kilogram * 5.gram // 50,000 grams

Everything is strongly-typed, and conversion is a breeze:

2.week.to(unit: .hour) // 336 hours

Scale even provides nicely formatted debug output. For example, print'ing that last statement logs:

Time(value: 336.0, unit: Scale.TimeUnit.hour)

Scale supports a wide variety of units:

let angle = 5.degree + 2.radian
let area = 5.acre + 2.hectare
let metric = 5.base + 2.kilo
let volume = 5.liter + 2.gallon
// + many more...

One more example to show off how readable Scale's API is. Here we'll add two typed units together, then convert them:

let time = 4.day + 1.week
print(time.to(unit: .week))
Time(value: 1.57142857142857, unit: Scale.TimeUnit.week)

More info about Scale can be found at git.io/scale

Most Swift developers are familiar with how great Swift is at integrating with Objective-C, but what about C itself? Today we'll look at how we can interact with C variables and pointers in Swift. Let's dive in.

Here's a few variables in C:

const int *someInt
int *anotherInt
struct Spaceship *spaceship

When referenced in Swift, these become:

UnsafePointer<Int>
UnsafeMutablePointer<Int>
COpaquePointer

What about those pesky void pointers in C?

void launchSpaceshipWithID(const void *spaceshipID);

Buckle up, for this we'll need to go unsafe...

Swift tries its best to keep us safe, so for something like void pointers, we'll need to jump through a few safety-defying hoops:

var sID = 31
withUnsafePointer(&sID) { (p: UnsafePointer<Int>) in
  let voidP = unsafeBitCast(p, UnsafePointer<Void>.self)
  launchSpaceshipWithID(voidP)
}

First we create a regular Int value in Swift. Nothing special. Then, we'll pass it in to the withUnsafePointer function, along with a closure. Inside, we'll be passed in an UnsafePointer version of our original Int. We'll use the unsafeBitCast function to convert it into to a void pointer. Finally, we'll pass it in the C function. Whew!

Page 17 of 38