22 Apr

Swift Performance Benchmark

 

SwiftPerformanceBenchmark


This is a hybrid Swift/Objective-C project for Mac OS. You can download it by clicking the following link:  SwiftPerformanceBenchmark

It was written as a performance benchmark to compare Swift and OBjective-C in a memory and compute-intensive task.

It calculates large arrays of prime numbers in both languages and tracks the amount of time required for both.

For the Swift test, you can choose to use either an Array object or an Array

For the Objective-C test, you can choose between NSArrays or C arrays.

It demonstrates a number of different techniques:

  • Definining classes in both Swift and Objective-C using a common protocol so that they can be used interchangeably.
  • Using Mac OS Cocoa Bindings to attach a window’s UI elements directly to properties of an object.
  • Running time-consuming tasks in the background with GCD and reporting status back on the main thread.

It also uncovers a limitation with the current version of Swift (1.1?) It seems that you can’t use KVO or Cocoa bindings to observe properties of an object, or link them with Mac OS Cocoa Bindings unless you write extra code. Cocoa bindings work perfectly when you change the property values from Objective-C, but the KVO methods fail to fire when you change the property values from Swift code.

The fix for this is to write custom willSet/didSet methods for the properties being observed that manaully call the methods willChangeValueForKey and didChangeValueForKey.

An example is the property swift_totalCalculated, defined in ComputedRecord.swift.

 

18 Apr

Password Generator

This sample project generates passwords using random words from a large word list available on the internet.

It illustrates several useful techniques:

  • Parsing raw text into a binary plist and adding that plist to your application
  • Reading a plist from your application bundle to load saved resources
  • Using the arc4random() function to pick random words from an array

You can download the project from Github at the following link:

Password generator project on Github

18 Apr

Using Core Animation Groups to Create Animation Sequences

 

iOS-CAAnimation-group-demo

This is a demo project that illustrates various animation techniques

It shows 3 different kinds of animations:

  • A simple UIView animation that animates an image in a straight line while increasing the scale of the image and rotating it around it’s axis
  • A “clock wipe” animation that gradually reveals an image in a circular arc like a radar display, then hides it again
  • A complex sequence of animations that are managed using a CAAnimationGroup.

UIVIew animation (View Animation button)

The UIView animation is performed by the method -doViewAnimation: (id) sender in viewController.m. It uses the method animateWithDuration:delay:options:animations:completion: to do it’s job. UIView animations modify animatable properties of one or more views. It is possible to animate mutliple animatable properties of multiple view objects with a single UIView animation call. the doViewAnimation method animates the view’s center, scale, and rotation all at the same time.

Clock Wipe animation (Mask Animation button)

The clock wipe animation is performed in the method - (IBAction)doMaskAnimation:(id)sender;. It works by creating a shape layer (CAShapeLayer) and setting it as the mask for an image view’s layer. We set the shape layer to contain a an arc that describes a full circle, where the radius of the arc is 1/2 of the center-to-corner distance of the view. The line width of the arc is set to the arc radius, so the arc actually fills the entire image bounds rectangle.

CAShapeLayers have a properties strokeStart and strokeEnd. Both values range from 0.0 to 1.0. Normally strokeStart = 0 and strokeEnd = 1.0. If you set strokeEnd to a value less than 1, only a portion of the shape layer’s path is drawn.

The doMaskAnimation method sets strokeEnd = 0 to start, which means the path is empty, and the entire image view is hidden (masked.) It then creates a CABasicAnimatimation that animates the strokeEnd property from 0.0 to 1.0. That causes the layer’s path to animate an ever-increasing arc. Since the line thickness for hte shape layer is very thick, the arc fills the entire bounds of the image view, revealing an ever-increasing portion of the image view.

The animation looks like this:

Clock wipe

CAAnimationGroup animation. (CAAnimation button)

The “CAAnimation” button invokes the method - (IBAction)doAnimation:(id)sender. It performs a whole sequence of animations. It does this buy creating a CAAnimationGroup, and then creating a sequence of individual CAAnimation objects of different flavors. It sets the beginTime property of each animation so that each animation step in the animation group begins when the next animation finishes.

What you will learn:

This project demonstrates a wide variety of animation techniques

  • Using CABasicAnimation to animate a property and move images around on the screen.
  • Using different animation timing functions like kCAMediaTimingFunctionLinear, kCAMediaTimingFunctionEaseIn, and kCAMediaTimingFunctionEaseInEaseOut to get different effects
  • Using CAKeyframeAnimation and a CGPath to animate a layer along a curved path (a figure 8).
  • Creating a custom subclass of UIView that has a CAShapeLayer as it’s backing layer so you can draw shapes in a view “for free.”
  • Adding a CGPath to a shape layer to draw shapes on the screen.
  • Using CAAnimationGroup to create a linked series of animations that run in sequence
  • Creating a very clean “per animation” completion block scheme using the fact that CAAnimation objects support the setValue:forKey: method. I add a code block to an animation object and set up the animation delegate’s animationDidStop:finished method to check for a special key/value pair with the key kAnimationCompletionBlock.
  • Using the cumulative property on animations to create a single repeating animation that continuously rotates a layer by any desired amount.
  • Using a CATapGestureRecognizer to detect taps on a view.
  • Detecting taps on a view while it animates “live” by using the hitTest method of the view’s presentation layer
  • Pausing and resuming animation on a layer.