Tải bản đầy đủ (.pdf) (946 trang)

iOS 8 swift programming cookbook

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (16.12 MB, 946 trang )

iOS 8 Swift Programming Cookbook
Vandad Nahavandipoor
Preface
About a year ago, noticing that Apple had not updated Objective-C much over the past few years, I
got intimations that they were working on a new language or framework for iOS development, and
even suggested it to my friends at work. They laughed and said, “Then you will have to write your
book from scratch.” They were right; this edition is almost a whole new book.
The previous edition of the book had already seemed like a very big job because I added so many
recipes as well as updated all the Objective-C code for iOS 7. But the task was dwarfed by this
edition, where everything had to be rewritten in Swift. Furthermore, so many recipes are new that I
have lost count. I can affirm that this edition of the book is the most extensive effort since my initial
effort to write the first edition. All the code has been written in Swift. Not just translated line by line,
but rewritten to take advantage of awesome features in Swift, like extensions.
None of us quite expected Swift to come out from Apple’s Worldwide Developers Conference
(WWDC) 2014. We thought it would be a normal WWDC with tons of new APIs and just some
additions to Objective-C like previous years at WWDC. But we were all surprised. At least I was.
I think Swift is a great language and has been needed for iOS development for a long time. Those of
us who grew up with the first iOS SDK or—as it was called back then—the iPhone SDK, know how
painful it was to do reference counting manually. Explaining those concepts in early editions of this
book, I felt they were sometimes unnecessary and “got in the way” when developing iOS apps.
Instead of focusing on writing great apps, we had to focus much of our attention on writing apps that
wouldn’t crash because of memory management issues. Swift has fixed a lot of those issues and has
left us with a lot more complicated things to deal with.
Swift seems like a programming language that is intended for more than iOS development, because so
many of its features are unneeded in basic applications and are more appropriate for something
complicated and demanding such as a game. When it comes to iOS development, the frameworks
seem to be more important than the language, and the frameworks are usually what we struggle with.
The difficulty is exacerbated by a lack of documentation for APIs. Many development companies,
Apple included, seem to think they can just put out documentation for each API in isolation. They
don’t understand that programmers need to use a series of APIs together to achieve something. Apple


tells you: here is a carrot, it has X number of calories, it weighs this much, its color is orange, and it
has been produced in this country. This book tells you: here is a carrot and this is how you can make a
carrot soup with it.
Apple doesn’t provide basic instructions on how to use their APIs. But they are not alone in this. It is
a very big job to document the APIs and they have done a great job with that. I will help you use those
APIs to deliver amazing apps to your customers.
I hope you’ll enjoy reading this book, and if there is anything that I have not explained, you can
contact me through Facebook or Twitter or just send me an email. I will be more than happy to help
fellow developers out.
Audience
I assume you know your way around Xcode and have written a few lines of Swift code before. This
book does not offer a tutorial about how to write Swift code, but will show you interesting and
powerful iOS apps using Swift. There is a big difference. I don’t explain the Swift language in this
book, because Apple has already done that quite thoroughly with the Swift Programming Language
guide, which is about 500 pages long! There is no need for a book to re-explain what Apple has
already explained. So if you are not comfortable with Swift yet, I suggest that you read the
aforementioned guide published and made freely available by Apple—just do a web search.
This book is also not going to teach you the very basics of iOS development. I expect you to know the
basics of software engineering and algorithms. Please do not purchase this book in the hopes that it
will make you a software engineer, because that is not its goal. If you already know about functions,
the stack, arrays, dictionaries or hash-tables, etc., this book is good for you. Otherwise, I suggest that
you first become a software engineer of some sort (even if your language is not Swift), and then pick
this book up to learn how to write awesome iOS apps.
Organization of This Book
Here is a concise breakdown of the material each chapter covers:
Chapter 1, The Basics
This chapter explains the fundamental building blocks of iOS development, such as messages,
labels, sliders, buttons, text fields and views, navigation bars, etc. I suggest that you read the
recipes in this chapter and try them out before moving on to more advanced subjects.
Chapter 2, Extensions

Finally! Apple allows us to extend iOS with these little binaries that ship with our apps, get
integrated into iOS, and can live by themselves without the need for our apps to be running in the
background. For instance, we can now create custom keyboards that can get installed on the user’s
device and the user can use those keyboards even if our app is not running. This feature has been
in Android pretty much since its beginning, so when Apple allowed this feature on iOS, I said not
“Oh, great” but “Finally.” Have a look at this chapter and make up your own mind about its value
for you.
Chapter 3, Managing Health Data with HealthKit
The HealthKit framework allows iOS apps to integrate with the health-information that is stored
on the user’s device. This information belongs to the current user of the device and can contain
very detailed information, such as the amount of fat that the user burned in the last running session
they did. This chapter teaches you how to integrate your apps with HealthKit and read and write
to this health database.
Chapter 4, Managing Home Appliances with HomeKit
HomeKit is another awesome framework in the SDK. It allows iOS apps to speak to accessories
that are HomeKit enabled, so to speak. You will learn to discover these accessories, configure
them, talk to them, and so on.
Chapter 5, Creating Dynamic and Interactive User Interfaces
Creating a lively user interface takes more than a table view and a label placed on a navigation
bar! You need to simulate real-life physics. This chapter teaches you such things as how to model
gravity and other dynamic behaviors, and how to attach those to your UI components.
Chapter 6, Table and Collection Views
A lot of the information that we want to display to the user is hierarchichal, in that it can be
separated into specific cells on the screen and eventually displayed to the user. Table views and
collection views are used pretty much everywhere in iOS. From the Photos app to the Settings,
you can see collection and table views at work everywhere. This chapter teaches you all you need
to know to create great functionality with these components in the SDK.
Chapter 7, Concurrency and Multitasking
When your app runs, by default, you will be on the main thread in your app delegate so that you
can perform UI-related tasks. But you do not want to perform heavy downloading tasks and heavy

calculations on the UI thread because you’ll trash your users’ experience. In fact, iOS will
actually kill your app if you block the UI thread for more than five seconds. Concurrency and
multithreading is taught in this chapter to allow you to create fluid apps that do all the work they
need, without stepping on the UI thread too much.
Chapter 8, Security
Do you store usernames and passwords using NSUserDefaults? If your answer is yes, you
desperately need to read this chapter. We will talk about Touch ID authentication and many
Keychain-related functionalities. You will also learn how to make your user interfaces more
secure.
Chapter 9, Core Location, iBeacon, and Maps
All the sensors in an iOS device are helpful when you try to find your way to the supermarket or
find out which floor of a building you are currently on (seriously, iOS almost always knows this).
So you can learn about iBeacons and maps and core location in this chapter.
Chapter 10, Gesture Recognizers
When Steve Jobs introduced the iPhone, he showed the world how to scroll through an iPod
music library by swiping up and down the page. I still remember people clapping and going
“Ooooh.” Apple engineers had placed a swipe gesture on the view, which allowed Mr. Jobs to
scroll up and down the page so smoothly. This chapter teaches you all about gestures.
Chapter 11, Networking and Sharing
What is an iOS device with no Internet connection? A simple phone or a tablet. Network
connectivity really adds another dimension to smartphones. This chapter teaches you how to do
background and foreground networking to download and upload files using various classes in the
SDK.
Chapter 12, Multimedia
Inside an iOS app, with the user’s permission, you can access their audio and video files and play
those files for the user, or simply grab the data for those files for whatever processing you need to
do. If you are creating a game, for instance, you might want to play some background music for the
user to add some excitement to your game. This chapter teaches you how to load and play audio
and video files.
Chapter 13, Address Book

The Address Book framework still consists of C APIs. Some people say this is for performance
reasons, but I believe Apple has just assigned a low priority to the framework and they just have
not brought it up to date with the latest technologies in the SDK. So this chapter teaches you how
to use Swift to integrate the Address Book framework into your apps in order to access the user’s
contacts’ information, after the user has given you permission to do so.
Chapter 14, Files and Folder Management
You can easily write iOS apps that do not need to work with files and folders. But as soon as you
find the need to store information in files and categorize them into folders, you can start reading
this chapter. I will teach you how to write to files, read from them, enumerate them, and so on.
Chapter 15, Camera and the Photo Library
iOS keeps a library of all the videos and photos that the user has on her device. The app that
allows the user to see these photos and videos is called Photos (obviously!). In this chapter, we
will learn how to access the raw data for the photos and videos stored on the device, so that you
can integrate this functionality into your apps without having to redirect the user to the Photos app.
Chapter 16, Notifications
Different parts of iOS interact with each other through notifications. For instance, when the app
goes to the background, iOS sends a notification into your application memory space. You can
catch this notification in any object inside your app to get notified when the app has gone to the
background, in order to do whatever there is that you want to do. This chapter teaches you all
about local, push, and app notifications.
Chapter 17, Core Data
Core Data is Apple’s database technology. You can store data, read it back, sort it, display it,
create relationships between different pieces of data, and so on. What is there not to like? Core
Data is an amazingly simple technology but requires a certain understanding of its underlying
architecture. I will walk you through that in this chapter.
Chapter 18, Dates, Calendars, and Events
Dates are important, whether we are talking about editable dates or a date with a partner-to-be or
just dates as they are in a calendar. Even though I won’t be handing out dating advice, you can
learn about calendar dates in this chapter. You will learn to construct date objects, read events
from the user’s calendar, and so on.

Chapter 19, Graphics and Animations
Every now and then you might want to impress your users with some cool graphics and
animations. This chapter is all about that. You can draw images on the screen, animate them,
rotate them, and so on. Dazzle your users.
Chapter 20, Core Motion
A pedometer is a wonderful device that can count the user’s steps-taken from time to time. As
soon as you have the user’s steps data and you know their age and other simple information, you
can start counting the calories that they are burning, display them motivating messages, and so on.
In this chapter you will learn about the pedometer, accelerometer, and gyroscope, which are some
great sensors that Apple has built into pretty much all iOS devices in the market today.
Chapter 21, Cloud
Imagine being able to store data in the cloud just as easily as you would store data in Core Data.
CloudKit allows you to do precisely that. It is another layer on top of iCloud. You will also learn
about iCloud in this chapter.
Additional Resources
Swift is a relatively new language with which you’ll want to familiarize yourself if you care about
iOS development. As I mentioned before, I recommend that you read Apple’s guide on the Swift
Programming Language. You won’t be disappointed.
From time to time, I refer to official Apple documentation. Some of Apple’s descriptions are right on
the mark, and there is no point in trying to restate them. Throughout this book, I have listed the most
important documents and guides in the official Apple documentation that every professional iOS
developer should read.
For starters, I suggest that you have a look at the iOS Human Interface Guidelines for all iOS devices.
This document will tell you everything you need to know about developing engaging and intuitive user
interfaces for all iOS devices. Every iOS programmer should read this document. In fact, I believe
this should be required reading for the product design and development teams of any company that
develops iOS applications.
I also suggest that you skim through the “iOS App Programming Guide” in the iOS Developer Library
for some tips and advice on how to make great iOS applications.
Conventions Used in This Book

The following typographical conventions are used in this book:
Italic
Indicates new terms, URLs, email addresses, filenames, and file extensions.
Constant width
Used for program listings, as well as within paragraphs to refer to program elements such as
variable or function names, databases, data types, environment variables, statements, and
keywords.
Constant width bold
Shows commands or other text that should be typed literally by the user.
Constant width italic
Shows text that should be replaced with user-supplied values or by values determined by context.
TIP
This icon signifies a tip, suggestion, or general note.
CAUTION
This icon indicates a warning or caution.
Using Code Examples
Supplemental material (code examples, exercises, etc.) is available for download at
/>This book is here to help you get your job done. In general, if example code is offered with this book,
you may use it in your programs and documentation. You do not need to contact us for permission
unless you’re reproducing a significant portion of the code. For example, writing a program that uses
several chunks of code from this book does not require permission. Selling or distributing a CD-
ROM of examples from O’Reilly books does require permission. Answering a question by citing this
book and quoting example code does not require permission. Incorporating a significant amount of
example code from this book into your product’s documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the title, author,
publisher, and ISBN. For example: “iOS 8 Swift Programming Cookbook by Vandad Nahavandipoor
(O’Reilly). Copyright 2015 Vandad Nahavandipoor, 978-1-4919-0869-3.”
If you feel your use of code examples falls outside fair use or the permission given here, feel free to
contact us at
Safari® Books Online

Safari Books Online (www.safaribooksonline.com) is an on-demand digital library that delivers
expert content in both book and video form from the world’s leading authors in technology and
business.
Technology professionals, software developers, web designers, and business and creative
professionals use Safari Books Online as their primary resource for research, problem solving,
learning, and certification training.
Safari Books Online offers a range of product mixes and pricing programs for organizations,
government agencies, and individuals. Subscribers have access to thousands of books, training
videos, and prepublication manuscripts in one fully searchable database from publishers like
O’Reilly Media, Prentice Hall Professional, Addison-Wesley Professional, Microsoft Press, Sams,
Que, Peachpit Press, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kaufmann,
IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders, McGraw-Hill, Jones
& Bartlett, Course Technology, and dozens more. For more information about Safari Books Online,
please visit us online.
How to Contact Us
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
800-998-9938 (in the United States or Canada)
707-829-0515 (international or local)
707-829-0104 (fax)
We have a web page for this book, where we list errata, examples, and any additional information.
You can access this page at />To comment or ask technical questions about this book, send email to
For more information about our books, courses, conferences, and news, see our website at
.
Find us on Facebook: />Follow us on Twitter: />Watch us on YouTube: />Acknowledgments
Andy Oram, as always, has been such an amazing editor for this edition of the book. He has worked at
the speed of light to deliver this material to you. He has gone through everything that I’ve written,
word by word, and has ensured that my content is digestible by a much wider audience than I could

ever imagine writing for. I thank you for your hard work. Thank you to Niklas Saers, who did a great
job technically reviewing this book.
Rachel Roumeliotis has also been a fantastic help at O’Reilly. She has supported me throughout my
work. She was very happy when I decided to rewrite this book for Swift so it is great having her on
my side when the time came to make a big decision like that.
Thanks to Sara, my lovely partner, for her patience while I wrote this book. I cannot imagine having a
more loving and patient partner. I genuinly appreciate all you’ve done for me throughout this period.
Also thank you to Heather Scherer and Amy Jollymore of O’Reilly for sorting out many aspects of
this book and my upcoming video series. I appreciate your help.
Thanks to Ulla, Leif, Bella, David, and the kids for every second we spend together. These times
mean a lot to me and I am forever grateful. Last but not least, I want to acknowledge Molly’s presence
and support as well and for the lovely faces that she gives me every day when we go on walks. Even
though you are quite a lot of work, I still love you. “Duktig tjej”!
Chapter 1. The Basics
1.0. Introduction
In order to write apps for iOS, you need to know some of the basics of the Swift programming
language that we will use throughout this book. Swift is Apple’s new programming language
introduced in Xcode 6 and iOS 8 SDK. Objects and classes are fundamental in object-oriented
programming (OOP) languages such as Swift, Objective-C, Java, C++, and many others.
All iOS applications essentially use the model-view-controller (MVC) architecture. Model, view,
and controller are the three main components of an iOS application from an architectural perspective.
The model is the brain of the application. It does the calculations and creates a virtual world for itself
that can live without the views and controllers. In other words, think of a model as a virtual copy of
your application, without a face!
A view is the window through which your users interact with your application. It displays what’s
inside the model most of the time, but in addition to that, it accepts users’ interactions. Any interaction
between the user and your application is sent to a view, which then can be captured by a view
controller and sent to the model.
The controller in iOS programming usually refers to the view controllers I just mentioned. Think of a
view controller as a bridge between the model and your views. This controller interprets what is

happening on one side and uses that information to alter the other side as needed. For instance, if the
user changes a field in a view, the controller makes sure the model changes in response. And if the
model gets new data, the controller tells the view to reflect it.
In this chapter, you will learn how to create the structure of an iOS application and how to use views
and view controllers to create intuitive applications.
I also want to teach you a few basics of the Swift programming language—but before we begin, I
want to make it absolutely obvious that the goal of this book is not to teach you how to program in
Swift. Apple has already released a full book more than 500 pages long that teaches you how to use
Swift. But in case you’re using this book in parallel with some other resource to learn Swift, I will go
over a few basics.
Defining Constants and Variables in Swift
We define constants with the let keyword like so:
let integerValue = 10
let stringValue = "Swift"
let doubleValue = 10.0
The value that we assign to a constant (or later to a variable) defines its type. In the examples I gave,
we did not have to define the data type of the constants at all because the Swift compiler can figure
out the proper type from the values we assigned. However, if you want to define the data type
manually, you can do so using the following syntax:
let integerFromDouble = 10.7 as Int
/* The value of this variable is 10
because the compiler truncated the value to an integer*/
When a constant is defined and a value is assigned to it, it cannot be changed later. If you need to
change a value, use a variable instead, with the var keyword:
var myString = "Swi"
myString += "ft"
/* myString is now "Swift" */
Variables can be mutable or immutable. An immutable variable cannot be changed or appended to.
Mutable variables can be changed.
Creating and Using Arrays in Swift

The [DataType] syntax can create an array. This is an example of creating an immutable array:
let allStrings = ["Swift", "Objective-C"]
If you want to create a mutable array, initialize an empty mutable array and then append values to it
like so. Use var so your allStrings array is a variable, not a constant:
var allStrings = [String]()
allStrings.append("Swift")
allStrings.append("Objective-C")
/* Our array is now ["Swift", "Objective-C" */
If you want to access values inside an array, use subscripting with the [] syntax:
var allStrings = [String]()
allStrings.append("Swift")
allStrings.append("Objective-C")
println(allStrings[0]) /* Prints out "Swift" */
allStrings.insert("C++", atIndex: 0)
println(allStrings[0]) /* Prints out "C++" */
Defining and Accessing Dictionaries in Swift
A dictionary is a hash table. Each entry in a dictionary specifies one object as a key and another
object as its value. Dictionaries in Swift are dynamically typed, based on what we feed them, and are
created with the [key: value] syntax, as shown here:
let allFullNames = [
"Vandad" : "Nahavandipoor",
"Andy" : "Oram",
"Molly" : "Lindstedt"
]
To access the value of a key, use subscripting like so:
println(allFullNames["Vandad"]) /* Prints out "Nahavandipoor" */
The dictionary that we created was immutable because of the let keyword. To create a mutable
version of the same dictionary, use the var keyword like so:
var allFullNames = [
"Vandad" : "Nahavandipoor",

"Andy" : "Oram",
"Molly" : "Lindstedt"
]
allFullNames["Rachel"] = "Roumeliotis"
This dictionary is of type [String: String] because of the values that we provided to it. You can add
any type of value or key to the dictionary to see how the data type changes:
let personInformation = [
"numberOfChildren" : 2,
"age" : 32,
"name" : "Random person",
"job" : "Something cool",
] as [String : AnyObject]
The AnyObject type, as its name implies, represents an instance of any class type. In this case, we are
saying that the keys to our dictionary are strings but the values are a mix of various class types.
Dictionaries and arrays in Swift can be freely bridged to their Cocoa Touch counterparts of
NSDictionary and NSArray.
Grouping Functionality with Classes and Structures in Swift
Structures are value types. That means that when they are passed around from one function to another,
for instance, a new instance of them is created and then passed to the function. Classes are reference
types, so that they can be passed around without having to be copied.
Imagine having the following structure:
struct Person{
var firstName, lastName: String
mutating func setFirstNameTo(firstName: String){
self.firstName = firstName
}
}
This structure has a method that can cause the structure to mutate, so it is prefixed with the keyword
mutating. Now we can create a function that can change the value of any Person instance to any given
string:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func changeFirstNameOf(var person: Person, to: String){
person.setFirstNameTo(to)
/* person.firstName is VANDAD now and only in this function */
}
func application(application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [NSObject : AnyObject]?) -> Bool {
var vandad = Person(firstName: "Vandad", lastName: "Nahavandipoor")
changeFirstNameOf(vandad, to: "VANDAD")
/* vandad.firstName is still Vandad */
return true
}
}
Note that the value of the firstName property of the person instance is changed only in the context of
the function, not outside it. That means when the instance of the Person structure was passed to the
function to change the first name to a given string, the structure as a whole was copied into the stack
and passed to the function. Therefore, even though we called the mutating function on it, the first name
of the vandad variable did not change.
Now off to classes. Classes are reference types and when passed to functions, are passed just as
references to a single copy held in memory. Have a look at the following example:
class Person{
var (firstName, lastName) = ("", "")
init (firstName: String, lastName: String){
self.firstName = firstName
self.lastName = lastName
}
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func changeFirstNameOf(person: Person, to: String){
person.firstName = to
}
func application(application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [NSObject : AnyObject]?) -> Bool {
var vandad = Person(firstName: "Vandad", lastName: "Nahavandipoor")
changeFirstNameOf(vandad, to: "VANDAD")
/* vandad.firstName is now VANDAD */
return true
}
}
You can see that the first name of the vandad variable is indeed changed in its original context after it
was passed to a function that changed the first name. Classes can also have inheritance, but structures
cannot have inheritance.
Diving into Operators in Swift
There are many valid operators in Swift. Here are a few examples:
typealias byte = UInt8
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
/* Bitwise OR operator */
let byte3 = 0b01010101 | 0b10101010 /* = 0b11111111 */
/* plus operator */
let plus = 10 + 20 /* = 30 */

/* minus operator */
let minus = 20 - 10 /* = 10 */
/* multiplication operator */
let multiplied = 10 * 20 /* = 200 */
/* division operator */
let division = 10.0 / 3.0 /* = 3.33333333333333 */
return true
}
}
You can also override operators. As we saw before, we had a class called Person. The two-
character == operator checks whether two things are equal in the sense of having the same value,
whereas the three-character === operator checks for instance equality. That means the first operator
checks whether the two instances are equal (in whatever way that makes sense in the context of your
app). The === operator is very strict: it makes sure that the two things you pass are occupying the
same position in memory.
Let’s explore the first type of equality. With our Person class, it makes sense to declare two instances
of this class equal if they have the same first and last name. Therefore, using the operator overloader
for the == operator, we can define this functionality:
func == (left: Person, right: Person) -> Bool{
if left.firstName == right.firstName &&
left.lastName == right.lastName{
return true
}
return false
}
And now, if we define two people with the same first name and last name and check whether they are
the same, even though the instances are different, they will come out the same:
let andy = Person(firstName: "Andy", lastName: "Oram")
let someoneElse = Person(firstName: "Andy", lastName: "Oram")
if andy == someoneElse{

/* This will be printed */
println("They are the same")
} else {
/* We won't get here in this case */
println("They are not the same")
}
The three-character === operator would say they’re different, because they are separate variables
and you can change one without changing the other.
Now let’s say that we want to add a postfix ++ operator to our Person class. To create some
numerical data it can operate on, we’ll add a age property of type Int to the class:
class Person{
var age: Int
var fullName: String
init(fullName: String, age: Int){
self.fullName = fullName
self.age = age
}
}
Our goal is to allow the programmer to perform the prefix and the postfix operators of ++ on our
person instances just like we would perform the prefix and postfix operator of ++ on integer values in
C:
postfix func ++ (inout person: Person) -> Person{
let newPerson = Person(fullName: person.fullName, age: person.age)
person.age++
return newPerson
}
prefix func ++ (inout person: Person) -> Person{
person.age++
let newPerson = Person(fullName: person.fullName, age: person.age)
return newPerson

}
And now we can use them like so:
var vandad = Person(fullName: "Vandad Nahavandipoor", age: 29)
var sameAgeVandad = vandad++
/*
vandad.age = 30
sameAgeVandad.age = 29
*/
let olderVandad = ++sameAgeVandad
/*
vandad.age = 30
sameAgeVandad.age = 30
olderVandad.age = 30
*/
In the same way, you can define prefix and postfix operators for any class or structure you like. Just
ensure that your operator overloaders are public functions and not defined inside any specific class or
structure.
Declaring and Using Enumerations in Swift
Enumerations are very sophisticated in Swift indeed. They can be of any given type. For instance,
they can be strings:
enum CarClassification: String{
case Estate = "Estate"
case Hatchback = "Hatchback"
case Saloon = "Saloon"
}
struct Car{
let classification: CarClassification
}
And then you can use them without having to point to the enumeration type. Just use the values:
let volvoV50 = Car(classification: .Estate)

You can then use the switch statement to find each case of an enumeration:
let volvoV50 = Car(classification: .Estate)
switch volvoV50.classification{
case .Estate:
println("This is a good family car")
case .Hatchback:
println("Nice car, but not big enough for a family")
default:
println("I don't understand this classification")
}
You can also get the raw value of an enumeration item using the rawValue property:
let volvoV50 = Car(classification: .Estate)
println(volvoV50.classification.rawValue) /* Prints out "Estate" */
Alternatively, you can construct a value of type of a specific structure using the initializer:
if let classification = CarClassification(rawValue: "Estate"){
let volvoV50 = Car(classification: classification)
}
You can use the where clause inside a switch statement to add logic to case statements. For instance,
if we have our Car type defined like so:
enum CarClassification: String{
case Estate = "Estate"
case Hatchback = "Hatchback"
case Saloon = "Saloon"
}
struct Car{
let classification: CarClassification
let year: Int
}
We can have a function that classifies our cars and, for each classification, decides how old the car
should be and still be considered in good condition:

func classifyCar(car: Car){
switch car.classification{
case .Estate where car.year >= 2013:
println("This is a good and usable estate car")
case .Hatchback where car.year >= 2010:
println("This is an okay hatchback car")
default:
println("Unhandled case")
}
}
And we can use the function like so:
let oldEstate = Car(classification: .Estate, year: 1980)
let estate = Car(classification: .Estate, year: 2010)
let newEstate = Car(classification: .Estate, year: 2015)
let hatchback = Car(classification: .Hatchback, year: 2013)
let newSaloon = Car(classification: .Saloon, year: 2015)
classifyCar(oldEstate) /* Will go to the default case */
classifyCar(estate) /* Will go to the default case */
classifyCar(newEstate) /* Will be picked up in the function */
classifyCar(hatchback) /* Will be picked up in the function */
classifyCar(newSaloon) /* Will go to the default case */
1.1. Adding Blur Effects to Your Views
Problem
You want to add blur effects to various UI components on your application.
Solution
Use the following two classes:
UIBlurEffect
This is a class that represents a blur effect. You can initialize an instance of this class with its
designated constructor and pass a value of type UIBlurEffectStyle to it. This value will then
decide what type of blur effect you want to create.

UIVisualEffectView
This is a simple UIView subclass that can accept and apply a visual effect of type UIVisualEffect.
Because the UIBlurEffect class is a subclass of the UIVisualEffect, you can simply create a blur
effect and pass it to your visual effect view. Once you have the visual effect view, you can add it
to any other existing view that you have on or off screen.
Figure 1-1 shows Safari’s icon rendered with a visual effect view that includes a blur effect, blurring
the center of that image.
Figure 1-1. Applying a blur effect on a view
Discussion
For the purpose of this discussion, I have already added an image view on my view controller. The
image is Safari.app’s icon. I have explained the process of extracting this icon in Recipe 19.2, so if
you are curious and don’t have any other icon to use on your view controller, you can have a look at
the aforementioned section of the book to learn how to extract Safari’s icon (or any other app’s icon
for that matter). My view controller looks like Figure 1-2 at the moment.
Figure 1-2. View controller with Safari’s icon on it
What I want to do now is add a blurred view on top of this image view. As we learned in the Solution
section of this recipe, we are going to create our blur effect and then create a visual effect view on
top of our current view, like so:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let blurEffect = UIBlurEffect(style: .Light)
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.frame.size = CGSize(width: 200, height: 200)
blurView.center = view.center
view.addSubview(blurView)
}
}
The UIBlurEffect class can be initialized with any of the blur styles that are specified in the

UIBlurEffectStyle enumeration like so:
enum UIBlurEffectStyle : Int {
case ExtraLight
case Light
case Dark
}
In our example code, we used a light blur effect, but you can use any of the ones just listed. Once you
have your blur effect, you can add it to the UIVisualEffectView class. This class itself can accept any
visual effect of type UIVisualEffect. Another class of the aforementioned type is the
UIVibrancyEffect. This class is very similar to the UIBlurEffect class, and in fact under the hood uses
a blur effect as well. UIVibrancyEffect brings out the colors on the layers that are behind it. For
instance, if you have a popup window that is about to appear on top of another view that contains
many colorful photos on it, it is best to add a UIVibrancyEffect to a visual effect view and construct
your popup using this visual effect view. That way, the colors underneath the popup (colors that come
from the photos) will be more appealing to the user and the user will be able to get a better
understanding of the content under your popup.
1.2. Presenting Temporary Information on the Screen with
Popovers
Problem
You want to display a temporary view to the user on the screen and allow them to interact with it.
When they are done, this view will need to get dismissed. On an iPad, you would like this
information to take up only a bit of the screen real estate, not the whole.
Solution
Use a popup controller of type UIPopoverController and display it on your view controllers using the
presentPopoverFromBarButtonItem:permittedArrowDirections:animated: method of the popup
controller. A popup controller has to originate from a specific rectangular space on the screen. This
is usually a button or a control on the screen where the user taps and expects to see the popover. This
item could be of type UIBarButtonItem, in which case you can display the popover using its
presentPopoverFromBarButtonItem:permittedArrowDirections:animated: method. Otherwise, you
can display and originate a popover from any rectangular spot on the screen using the

presentPopoverFromRect:permittedArrowDirections:animated: method.
Discussion
Popovers are used to display temporary information on the screen. They can be used both on regular
and on compact size devices such as iPads and iPhones. In this recipe, we want to build an
application with a main view controller embedded inside a navigation bar. On the navigation bar we
show a plus (+) button which, upon pressing, will display a table view that is populated with 100
items. This table view will be embedded inside its own navigation bar with a Cancel button on it.
When the user selects an item in the table view, the popover will be dismissed and the selected item
will be passed to the root view controller for processing (see Figure 1-3).
Figure 1-3. Our popover is displayed on the iPad screen
The table view controller has its own class and works with a completion handler. When an item is
selected, this controller takes the selected item and passes it to its completion handler. Therefore,
processing is very decoupled and it is best to start our implementation of this controller first. Before
we begin, we need to define a few handy extensions:
extension Array{
subscript(path: NSIndexPath) -> T{
return self[path.row]
}
}
extension NSIndexPath{
class func firstIndexPath() -> NSIndexPath{
return NSIndexPath(forRow: 0, inSection: 0)
}
}
The first extension retrieves an item from an array using an index path, which is really cool, and the
other extension constructs an index path at the first row of the first section to relieve us from doing it
manually every time. We will be using these quite soon, so don’t worry if you don’t fully understand
their use yet.
Next we are going to define the most useful variables for our table view controller. The most useful
one out of all these variables is the array of items that we are going to display to the user in the table

view, so they can select one. This is an array of strings and we populate it lazily:
class PopoverTableViewController: UITableViewController {
struct TableViewValues{
static let identifier = "Cell"
}
/* This variable is defined as lazy so that its memory is allocated
only when it is accessed for the first time. If we don't use this variable,
no computation is done and no memory is allocated for this variable */
lazy var items: [String] = {
var returnValue = [String]()
for counter in 1 100{
returnValue.append("Item \(counter)")
}
return returnValue
}()
var cancelBarButtonItem: UIBarButtonItem!
var selectionHandler: ((selectedItem: String) -> Void!)?
<# rest of the code #>
}
When the table view is displayed to the user, we will also construct our bar button items and show
them on the navigation bar without an animation:
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
tableView.registerClass(UITableViewCell.classForCoder(),
forCellReuseIdentifier: TableViewValues.identifier)
}
override init(style: UITableViewStyle) {

super.init(style: style)

×