Saturday, 12 December 2015

Approaches to Testing Software

TL;DR - Knowing the different ways and strategies to test software will give you the ability to define your approach depending on your project limitations
Over the last few weeks we've been exploring less technical topics around software development (Designing reusable componentsThe Art of Estimation and Separating data from logic in Swift). In this article I discuss the various approaches I take around testing software. I'll focus on testing of mobile applications, specifically iOS apps but most concepts are applicable to other software.
When I think of testing an app 3 approaches come to mind:
  • Basic manual testing
  • Automated testing
  • Exploratory testing

Basic Manual Testing

The basic and most common testing carried out in software is manual testing. Specifically, this involves a person going through the app manually tapping buttons, filling in textfields and so forth.
To make manual testing work it's important to define very clearly test scenarios. This way any other tester joining the project can follow these test cases to ensure that all the edge-cases known are tested every time. More often than not these test cases are carried out by a click engineer. Someone that will blindly follow a set of instructions tapping buttons without much thought.

Blindly following test cases is of limited value. The tester testing should understand the app in a way that when a bug is found, they can provide insights and hypothesis on the underlining cause of the issue.

Automated Testing

Manual testing will work on projects that have a lower budget and focus on short term goals. However, it'll be less valuable in the long term as the time taken to manually complete all the test cases is always the same. This is where automation testing is useful since there is a high setup time/cost to write the automated tests but running them is very fast.
The value of automation is sometimes misinterpreted specially when people rely on test coverage percentage as a measure of testing quality or they have a blind obsession with it. Some aspects can be tested using automation and some others can't, and so should be manually tested.
There are some of the types of automated tests I have written:
  • Logical unit tests
  • Performance unit tests, this one is tricky to test because most of the times we run out test-suite in our CI server or development laptop but it is key this is run on the slowest of the devices that your app is meant to run
  • Snapshot tests, which are useful to ensure the UI is consistently the same
  • Sensor related tests (e.g. gps location, accelerometer, gyroscope, barometer and so forth), where mocking of the signals is necessary
  • UI tests, which ensure the flow between screen does not break
  • Server integration tests
  • Static content validation tests (Check spelling of content, check all fields expected for the content exist and are of the expected format)
This list is not exhaustive but it will give you an indication of what is possible.

Exploratory Testing

The real value of automation tests is that it allows for time spent doing exploratory testing. This literally involves using the app in different ways as user would. By doing this it'll be possible to catch edge-cases that were not found by previous manual and/or automated tests.
This is where the human value comes into play. We make apps for people. Therefore, it's best if other people use the app to pick up unexpected and/or undesired behaviour.

Conclusion

Generally speaking it's best to automate the monotonous part of a an application where it's time efficient to do so. Basic manual testing should be left to cases where automating something would be very time consuming. This is very valuable in the long term as regression testing before a release is reduced. Thus, the focus can be on a more real-life exploratory testing approach.
The testing strategy depends very much on the team developing the software and their limitations (skills, time and so forth). Hopefully, after reading this article you'll be able to make more educated choices about how you test your software.

Saturday, 5 December 2015

Separating data from logic in Swift

TL;DR Try to separate data from logic for better code reusability. Ideally, data structures and their properties should be immutable.
We've recently been discussing how we can design reusable components and how we can provide useful estimates for our work. 
Today, I want discuss a key concept that can help with writing reusable code: Separating the data from the program's logic. This is nothing more than implementing the Separation of concerns. The idea is to illustrate this with the onboarding component we've discussed in the prior post about designing reusable components. The examples will be in Swift, so while some of the language facilities might be unavailable in different languages, the concepts should still be useful. 

Identify what is data

The first step to separate the data from the logic is to identify what is data. In our onboarding example, the data is composed of all the attributes that must be customizable (identified in our design phase) for our onboarding to be reusable in other projects. These were:
  • Button placement
  • Fonts
  • Background image
  • Animation speed
  • Corner radius of body copy box
  • Line width of body copy box
  • Border colour
  • Text aligment (justified, centred)
  • Logo image
The logic in this example will mainly boil down to presenting the different onboarding pages and UI elements based on the data provided. User interaction with the onboarding would also be part of the program's logic.

Modelling the data

Ideally, we want the data to be inmmutable in order to reduce the errors that happen when one part of the program modifies the data affecting another section that didn't expected that data to change.
The first step is therefore to use immutable properties wherever possible. This means using constants instead of variable (let instead of var in Swift), and copying data rather than passing a reference to it. In Swift, structs are ideal for modelling data because they use value-semantics. When a struct is passed to a method or a function, a copy is made. This method can then alter the data without affecting other methods that might have a copy of the struct.
To illustrate this point, we can have a look at the struct used to contain the attributes of our onboarding example: 
struct FlexiOnboardContent {
    let backgroundImage: UIImage?
    let logoImage: UIImage?
    let title: String
    let text: String
    
    let titleFont: UIFont?
    let titleColor: UIColor?
    let textFont: UIFont?
    let textColor: UIColor?
    let isTextCentered: Bool?
    
    let hasBorder: Bool?
    let borderWith: CGFloat?
    let borderColor: UIColor?
    
    let hasRoundedCorner: Bool?
    
    let action: (() -> (Void))? 
}
The FlexibleOnboardContent structure can then be passed to the main onboarding class to instantiate a new onboarding component. All of the properties in this example are optionals because none are required.
There might be situations, such as when the data is managed by Core Data, where it's not possible to use structs. In such situations, reducing the parts of the code where data is accessed might be the best option. 

Conclusion

We've seen through this brief post how we should attempt to separate the program's logic from its data by using inmmutable properties and value-semantics. A process of trial and error might be required in some instances, so it's definately worth using Swift's playground to try out your ideas.

Saturday, 28 November 2015

The Art of Estimation

TL;DR - Estimating software is hard, to be reasonably accurate it is best to split the requirements in very small stories, and naturally experience does help
Estimation in the software environment is more an art than a science. In most cases anything that is estimated takes longer than originally planned. There are generally two outcomes; the deadline is moved and the budget is increased or the scope is reduced. Software estimation is a huge subject, so I only intend to explain some ideas that have helped me throughout the projects I've been involved in.
Naturally, somebody that has already done a similar task before will be able to provide a better estimate. For example, specifically to iOS/Mac development, the setting up of a CoreData stack will usually be more accurately estimated by a senior developer as opposed to a junior developer. However, by being meticulous about estimates a reasonable level of accuracy can be achieved.

Importance of requirements

Before estimating software, it is good too start with very high-level epic stories. An epic story is a high-level requirement, for example, in a recipe app, one of the epics would be to be able to show the details of a recipe (i.e. ingredients, steps, summary and so forth). When defining this it's important to focus on the most valuable ones firsts. This is easier said that done as Oscar Wilde said "Nowadays people know the price of everything and the value of nothing.”. One you have your epics, then you can work your way down to individuals stories and the small tasks necessary to complete the story. 
Requirements and estimation are tightly linked, naturally if the requirements change so will the estimates. Growing requirements lead to scope-creep and will make your project fail if they are not controlled. Hence, unstable requirements lead to poor estimates. This tends to occur when the value of what we are building is not clear.

Keep estimations small

The bigger the task the harder it's to estimate. The reason for this is that variables, edge-cases and requirements are too many to get a real grasp of. As a rule of thumb if a task is estimated to take more that two days, it should be broken down to a simpler form. As an oversimplified example, it is harder to estimate a task that is:
  • Load the recipe data onto the app
Than these tasks:
  • Define and document the specification of the data
  • Create a model representing a recipe
  • Define relevant images for a recipe
  • Parse JSON (or relevant data type) and map it to the create model
  • Write unit tests to prove that the JSON has been parsed correctly into the models
By keeping estimates small and concise, it's easy to compare the result of how long something was estimated to take and how long it took. This is key to fine tune the ability to estimate small tasks in the future.

Dealing with the unknown

Sometimes we need to estimate something that we have never done before. You may think that if the implementation of a task is unknown we should give a very high estimate. However, "Work expands so as to fill the time available for its completion" as defined by Parkinson's law. Among other things, this suggests that overestimating is not the solution since the task will just take longer without necessarily adding more value.
In this case, it's best not to give an estimate as the time you think it will take will be as good as throwing a dice. Therefore, for these stories it's best to spend a small amount doing a spike. A spike is about spending a small amount of time to investigate the unknown before estimating the story. For example, before implementing a new SDK or library, it can be used in a sample project for one or two days to know how it works. This will give you much more information to later provide a more accurate estimate.

Conclusion

Requirements will change over time as discussed previously. Hence, it's important to understand and plan for high-level estimates to change as the project evolves. Naturally, the allowance for changes will depend on your time and budget constraints.
Underestimating leads to low team moral, increased costs, more bugs and ultimately projects failing. On the other hand, overestimating will mean that the relationship between the value of a project and the cost will be diminished as a lot of time will be spent procrastinating.

Saturday, 21 November 2015

Designing reusable components

TL;DR Plan the different part of your projects before you start coding. Try and separate implementation details from the general requirements of your project.
When working on a project, it's always tempting to start coding immediately. While we might tell ourselves that this code is only a prototype and can later be thrown away, it seldom happens. Temporary solutions have the bad habit of becoming permanent. To make matters worse, we usually feel time pressures that hinder our ability to plan and spend time thinking about what we need to do. 
In the new few weeks we're going to publish a series of blog posts exploring different aspects of project organisation and management such as:
  • Designing before coding
  • Developing reusable components
  • How to produce estimates
The objective of this article is to briefly go through the design of a generic component. By design we mean the work that is done before the actual coding. We use the term component to refer to a small part of a larger project. We will illustrate what is being discussed with a real component that I developed recently: the onboarding process of a mobile app.

Capturing requirements

The traditional software development process seems to imply that there is a magical way to know what our client might want. That it's only a matter of sitting down and writing down all of these requirements before we start with development. The reality is far from that.
Requirements will change as the project is developed because in many instances your client or customer doesn't really know what they want or it's not possible to know at such an early stage. At this stage we should therefore aim to get a general picture of what we're trying to produce before we write any code. 

High-level requirements

We should start with the high-level requirements, that is requirements that are not specific to any design or implementation. This means asking questions like:
  • What is our component supposed to do?
  • Who will be using it?
  • Where will it be used?
  • What is our preferred outcome?
Brainstorming our ideas can be the right approach to capture as much information as possible.
In the mobile onboarding example, after brainstorming our diagram could look like this: 

In our onboarding example the requirements could be the following:
  • Introduce the user to a new app
  • For mobile phone and tablet users
  • Delight the user
  • Indicate possible actions that can be performed
  • Easy to read instructions

Implementation specific requirements

After we've gathered our high-level requirements, we might concentrate on implementation-specific ones, which will usually stem from the high level requirements. We might ask ourselves questions such as:
  • What screen sizes will it support?
  • Will it have text or images?
  • Will there be animatations?
  • Will there be buttons or other UI components?
  • Should we use a table, a grid, or some other layout?
During this phase, I find it quite useful to do pencil drawings about what the component might look like (or diagrams if it's an internal component without a UI).
A basic diagram used for reasoning about the onboarding component could look like this: 

So, going back to our onboarding example, these might be some of the implementation-specific requirements:
  • Must have a full-screen background image
  • Must use pages to support multiple instructions
  • There should be animations or effects when we change a page (for example a parallax effect)
  • There should be a clear header plus a longer body copy
  • It should be possible to have a button on every page that can be linked to an action

Designing

By now we should have as good as an idea as we can about the generic component we're designing. It's therefore a good time to start doing some visual prototyping that we can later on use for development. Through this process we might also discover more requirements as well. There are many tools out there for rapid prototyping, some more sophisticated than others. I've used Sketch because it's easy to use and one can look at the design in the target device quite easily. Use whatever you feel more comfortable. 
Onboarding example design prototype:

Through this iterative process you'll end up with a design to implement as well as attributes that might need to be easily changeable to make your component generic. In our onboarding example, we decided that the following attributes should be customizable: 
  • Button placement
  • Fonts
  • Background image
  • Animation speed
  • Corner radius of body copy box
  • Line width of body copy box
  • Border colour
  • Text aligment (justified, centred)
  • Logo image
Even if you think that some of this attributes might seldom be changed, it's better to code in a way that they're customizable so there's more flexibility in adjusting the component's design when it's actually implemented. There's nothing more irritating than having to rewrite parts of your code because your customer or design team want the component to do something else. The later in a project that one needs to make changes, the more painful they can be.

Conclusion

The basic idea is to try and spend some time thinking about your component or project in a general way, before writing any code. This is likely to save you time and effort in the long run, as well as produce more generic code that can be reused in future projects.

Saturday, 14 November 2015

The state of the tvOS App Store

TL;DR - The tvOS App Store is a bit too light on features and discoverability is very poor meaning that it is very unlikely that even your mother will download your app

Discoverability

After uploading two very simple no thrills games Helicopter [1] and Ping Pong Arcade [2] for tvOS and looking into the tvOS App Store for 2 weeks we have found that discoverability is very poor in its current state. 
As a user it's hard to find relevant apps to you and as a developer it's hard to target specific users to your app. Currently depending on which country you are on you'll see between 3 and 5 tabs; Featured, Purchased and Search, and optionally depending on your country Top Charts and Categories. For example, the UK store does not currently have a categories section.
This will get better as Apple is adding various category sections and rankings as more apps come to the store. This is slowly being introduced because of the lack of tvOS apps out there. If you feel like exploring what tvOS apps are out there, you are out of luck.
Searching the tvOS App Store is quite a painful experience (quite literally). Siri dictation cannot be used for searching and it does not look like 3rd party external keyboards are compatible with the latest Apple TV. Currently, the only way to search is by using the Apple TV Remote with the displayed keyboard. This is indeed an annoying limitation of the Apple TV (Apple Support CommunitiesMacRumors forum). On the bright side given the lack of apps in the store only typing a few letters will generally find you what you need.
Given the current state, if you want to get a descent number of downloads (either paid or free) you need to be featured, so users can easily find your app.

Featured section (UK store)

iOS and tvOS apps can share the same bundle ID, meaning that a user that downloads your app on the iOS App Store will see it on the purchased section of the tvOS App Store. Depending on your business model it may make sense to have the same bundle ID for your iOS and tvOS. This way there is a better chance you'll get users downloading your tvOS app since it will be more visible to them as there is a dedicated Purchased section.

Limited deep linking to your app

As far as I know, the only way to link to your app is from another tvOS App. For example:
if let appStoreURL = NSURL(string: "https://itunes.apple.com/uk/app/helicopter/id1047310922?mt=8") {
      UIApplication.sharedApplication().openURL(appStoreURL)
}
Within iOS there are numerous ways of doing this; links on websites, mobile ads, emails, SMS and so forth. At the moment it's hard to picture how deep linking would work on the Apple TV but I'm sure this will be solved in the coming months since tvOS is still very new.

App previews are limited

After a great adventure, a user has finally found your app (whoohoo!). However, this is only half the battle won, now you have to do everything in your power to convince them to actually download your app. Even though the design of an app page is nice(-ish), it's interesting that there are no app preview videos. This feels like something that is distinctly missing, specially considering this feature is available in the iOS App Store.

Helicopter

Ping Pong Arcade


Only a star rating from 1 to 5 is allowed, no actual reviews. This does make sense when you understand how painful it's to write using the Apple TV remote. However, as a user it's hard to be convinced to download an app after seeing just a star rating. To be honest even if the user could write reviews, there is a pretty good chance that they will end up writing something short using monosyllabic words.
At the moment there are no analytics to know how many people actually reach your app preview page as it's the case of the iOS App Store. This makes it very hard to know if people can't find your app or they find it but don't download it.

Conclusion

The tvOS store feels very limited, frankly it looks like it's a beta version. It's hard to find the apps you are looking for and explore what is out there. Should you invest time/money in a tvOS app? If you intend to make money out of it and you don't have a huge (and I do mean huge) pile of cash for marketing then probably hold fire for now until the tvOS App Store develops into something more user friendly.
If you are not looking to make money, you should absolutely develop for tvOS. The development is very similar to iOS and it's a good learning experience. The platform is different enough that you will think about UI/UX in a different way. Having been developing for tvOS since September I can see that the Apple TV has a huge potential but currently only big players can reach users given the current state of the tvOS Store.

Footnotes

Saturday, 7 November 2015

Storing your data on tvOS, part 2: CloudKit

cloudkit-post In the first part of this series about data storage on tvOS, we've discussed using NSUserDefaults and iCloud KVS on tvOS. Today we're going to go through a very brief introduction of CloudKit. As we discussed before, the Apple TV has rather limited local storage space. If you plan to store a significant amount of data (according to our Apple overloards that means more than 1 MB) you might want to check out CloudKit. The information about CloudKit is not tvOS-specific, so it should still be useful to you if you're working on an iOS or Mac app.
The idea of this post is to briefly describe CloudKit's main features and workflow so you can then go on your merry way and try it out.

So what is CloudKit and why use it?

CloudKit is a BaaS (Backend as a service, like Parse) managed by Apple. It's easy to use an low cost relative to other options. Just for being a rockstar member of Apple's developer programme you get for free:
  • 10 Gb Asset storage
  • 100MB database
  • 2GB Data transfer
  • 40 requests per second
In the likely event that your app is an overnight success, you can go and purchase more storage to cover your ever-growing needs.
It's worth mentioning here that CloudKit does not make use of any of the user's iCloud storage. In a sense, it's separate from iCloud. It only uses the user's existing credentials for authentication.

Getting started

Naturally, you first need to enable the CloudKit entitlement on your project. Go to the target preferences and click on the 'capabilities' tab. Turn on iCloud and then select CloudKit.
This will create a default container for you as well. You might be wondering, what the heck is a container?! Well, a container keeps your app's records on the server. It's essentially a grouping of databases. You might have there a public database that is shared and a private one which is user-specific for example.

The CloudKit dashboard

The dashboard is where you'll be creating the records that your app will be using. You can click 'CloudKit Dashboard' in the capabilities pane to go straight to it.
You'll see 'Record Types', 'Security Roles' and 'Subscription Types'. In this post we will only deal with record types. If you've used other BaaS before you might be familiar with these concepts. If not, you can think of a record like a model class in your app. Essentially, a record type is a set of fields of various attributes. A record is an instance of a record type.
For example, if we had a phone book app, we might have a record type called entry that contains the fields name, address and phone number.
To create a new record type, select 'Record Types' under 'Schema' and then press the '+' button.

Public and Private zones

CloudKit supports both private and public zones so you can have data that is in common to all users of your app as well as private data that is user-specific. When you create a new record, you can decide if it will be used for public data or private data by adding it to the corresponding section. For example, if we want to add a new phone book entry to our public data (let's imagine this is a corporate phonebook so it must be available to all) we can follow the following steps:
  1. Go to the default zone under public data
  2. Make sure that the Entry entity is selected
  3. Press the '+' button
  4. Fill in the fields for the new record and press save

A whistlestop tour of CloudKit's API

There are various ways of accessing records in CloudKit. The two main ways of doing so are: 1. Fetching individual records by record ID 2. Using a query with a predicate to get a list of records

Fetching records by identifier

  1. In order to fetch records, we must first retrieve the public database in our container. In our case we're using the default container.
  2. We need to create a CKRecordID object with our record name.
  3. We then call the fetchRecordWithID: method with our CKRecordID object.
//1
let publicDatabase = CKContainer.defaultContainer().publicCloudDatabase
//2
let phoneEntryID = CKRecordID(recordName: "9f922b1c-7bd2-4550-b63d-342918a55230")
//3
publicDatabase.fetchRecordWithID(phoneEntryID) { record, error in

    guard error == nil else 
        return
    }
    print(record)
}
 

Fetching records by prediate

Fetching by predicate is very similar to fetching by identifier. The main difference being that we must create an NSPredicate object that we can then use with a CKQuery object. We then use our query object to peform a query on our database.
let publicDatabase = CKContainer.defaultContainer().publicCloudDatabase
let predicate = NSPredicate(format: "phone = %@", "12341234")
let query = CKQuery(recordType: "Entry", predicate: predicate)
publicDatabase.performQuery(query, inZoneWithID: nil) {
    recordsArray, error in
    
    guard let records = recordsArray else {
        return
    }
    
    for record in records {
        print(record)
    }
            
}

Saving and creating records programatically

Downloading data is all well and good, but what if you wanted your app to update the fetched records and send the changes back to CloudKit? Luckily for you, this is quite easy to achieve.
Each record is represented by a CKRecord object. It has the standard methods setObject:ForKey:, objectForKey, allKeys and changedKeys, you can use to update or add new fields. Once you're done with your changes you simple call saveRecord:completionHandler: on your CKDatabase object. If you've retrieved the record previously, any changes will update the version stored on CloudKit. If you've create a new record, a new entry will be created instead.
Interestingly enough, if you set values for keys that were not originally defined in your entry, they will be added to your entry by CloudKit. This is a nice and easy way to change an Entity without having to go through CloudKit's dashboard.
If this is all clear as mud, don't worry, we'll look at a simple example of creating a new entry in our ficticious phone book:
//1
let publicDatabase = CKContainer.defaultContainer().publicCloudDatabase
//2
let newRecord = CKRecord(recordType: "Entry")
newRecord.setObject("Sherlock Holmes", forKey: "name")
newRecord.setObject("21B Baker Street, London", forKey: "address")
newRecord.setObject("123456789", forKey: "phone")
newRecord.setObject("Consulting Detective", forKey: "job")

//3
publicDatabase.saveRecord(newRecord) {
    savedRecord, error in
    
    print(savedRecord)
    
}
  1. First we retrieve the database, in our case this is just the public database in the default container.
  2. We create a new CKRecord of type Entity and set the values for all the keys. Note that we've added a new key we hadn't defined in CloudKit's dashboard, that of "Private Detective".
  3. We save our new record, and if all goes well the callback will return the saved record.
We can now see our new record on CloudKit's Dashboard together with its new field, which is now available to all Entry objects.

Final words

We've barely touched the surface here. Think of this post as just the tip of the iceberg. As you can imagine, CloudKit has various notifcations so you can keep track of changes that happen in the cloud. CloudKit is packed with a vast array of features to do with security, multiple user roles and so on. Furthermore, 'CloudKit JS' provides a javascript API in case you need to use CloudKit from your webserver for example.
The idea of this tutorial is to show you the basic workflow so you can decide if CloudKit is useful for you. The bottom line is that CloudKit is a sophisticated BaaS run by Apple. If your app is exclusive for tvOS or iOS devices and it requires a fair amount of storage in the cloud, then you should definately check CloudKit out.

Saturday, 31 October 2015

On-Demand Resources on tvOS

TL;DR - tvOS app bundles are limited to 200MB and there is no storage on the Apple TV, so if your apps requires more than 200MB of static assets the option is to use On-Demand Resources
iOS 9 introduced on-demand resources (ODR). This is useful on iOS to reduce the download time of your application so that the user can start using your app quicker and so that the app can be downloaded on a mobile network connection. These benefits are nice things to have but generally not key requirements for an iOS app MVP.
However, on tvOS the limit per app is 200MB (compared to 2GB on iOS) meaning that there is a good chance that you will need to use this feature if your app needs many resources as there is no way to persist large amounts of data on the Apple TV as explained previously. This is probably due to the fact that the Apple TVs capacity is either 32GB or 64GB, which is not that much when considering the Apple TV will be used for content-heavy and/or entertainment apps. Other relevant sizes for on-demand resources are defined on the documentation:
ItemSize
tvOS App bundle - The size of the sliced app bundle downloaded to the device200MB
Tag - A string that identifies a set of resources512MB
Initial install tags - The total sliced size of the tags marked for initial install2GB
Initial install and prefetched tags - The total sliced size of the tags marked for initial install and the tags marked for prefetching.4GB
In use on-demand resources - The total sliced size of the tags in use by the app at any one time. A tag is in use as long as at least one NSBundleResourceRequest object is accessing it.2GB
Hosted on-demand resources - The total pre-sliced size of the tags hosted on the App Store20GB
As recommended on the developer forums:
If you have content that is required for initial app launch, you can include up to 2GB of tags as initial install, which means the assets are included in the initial download from the App Store before the app can be launched. You can also mark assets for "prefetch", which means that the app can be launched even if they haven't been downloaded, but that tvOS will automatically start downloading them in the background when the app is purchased.
Tags are used to identify a set of resources that need to be downloaded, note that resources could belong to multiple tags. Even though tags are limited to 512MB it is probably best to have much smaller tags otherwise your app will need to wait longer while all the pack is downloaded.
At any one time the app can use up to 2GB of static resources which is plenty even for the graphic intensive games. It is important to note that this extra data is cached by the OS, so the app can request when it needs resource and the OS will either download them or retrieve them from a cache. This means that depending on the disk space left on the Apple TV resources may be needed to be re-downloaded frequently or not. This is important to understand when designing your app around ODR since there is no guarantee that resources will be immediately available when requested if previously downloaded.

Implementing on-demand resources

Apple has made available a guide to downloading and accessing on-demand resources that answers most questions. Luckily, it is quite straightforward to setup this and test on Xcode.
Firstly, on your xcassets set the resources tags the images belong to (images can belong to multiple tags):



On the project settings define which tags need to be "initial install tags", "prefetched tags" or "download on demand tags".

Note that it does not look like these states can be simulated as when running the app for the first time all resources appear as not downloaded regardless of the which category they belong to.

To download the images from a tag 
let tagString = "RedTag"
// Create a resource request with the required tag(s)
let resourceRequest = NSBundleResourceRequest(tags: [tagString])

// Optionally define the loading priority if downloading multiple resources,
// use NSBundleResourceRequestLoadingPriorityUrgent if resources are required now
resourceRequest.loadingPriority = NSBundleResourceRequestLoadingPriorityUrgent

// Check if the resources are cached first
resourceRequest.conditionallyBeginAccessingResourcesWithCompletionHandler({ (resourcesAvailable : Bool) -> Void in
  if (resourcesAvailable) {
    // Do something with the resources
    print("Resources originally available")
  } else {
    // Resources not available to they will need to be downloaded
    // using beginAccessingResourcesWithCompletionHandler:
    print("Resources will be downloaded")
    resourceRequest.beginAccessingResourcesWithCompletionHandler({ (error : NSError?) -> Void in
      if (error != nil) {
        print("Failed to download resources with error: \(error)")
      } else {
        // Do something with the resources
        print("Resources downloaded successfully")
      }
    })
  }
})
Optionally set the preservation priority of a tag so that the operating system will know which resources to purge first.
let preservationPriorityForRedTag = 0.5
NSBundle.mainBundle().setPreservationPriority(preservationPriorityForRedTag, forTags: [redTagString])
Once the resources are available, they can be accessed as they normally would, for example:
let redImage = UIImage(named: "Red.png")
[redTagString])
Once the resources are no longer used Apple recommends to call endAccessingResources() on the request, Call this method as soon as you have finished using the tags managed by this request. If needed, this method will be called by the system when the resource request object is deallocated.
The progress of resources requests can be observed using KVO on the fractionCompleted property of the progress of the resources request, this progress can also be used to manage the request state, for example:
resourceRequest.progress.pause()
resourceRequest.progress.resume()
resourceRequest.progress.cancel()
Resources can be purged from the simulator easily from Xcode:

Demo

The basic code to setup ODR explained on this article is on GitHub. Generally speaking, it may be more appropriate to wrap the methods of ODR in an object that is custom to your needs. This way your app can manage the different states of the tags as they are needed. This is important as the priority of the resources being used will vary throughout the lifecycle of any application and ideally it would be best if the OS does not purge resources that are currently being used.