Now that I'm starting out using Swift, this edition is my Bible—I'd have been lost without it.—João Duarte ” Senior iOS Software Engineer Twitter: @oreillymedia Entirely rewritten for Ap
Trang 1MOBILE DEVELOPMENT/IOS
iOS 8 Swift Programming Cookbook
“ From coding with new iOS features to tackling complex requirements, Vandad's iOS
Programming Cookbook always provides me with the resources I need and good, clear, practical examples Now that I'm starting out using Swift, this edition is my Bible—I'd have been lost without it.—João Duarte ”
Senior iOS Software Engineer
Twitter: @oreillymedia
Entirely rewritten for Apple’s Swift programming language, this updated
cookbook helps you overcome the vexing issues you’re likely to face when
creating apps for iOS devices
You’ll find hundreds of new and revised recipes for using the iOS 8 SDK,
including techniques for working with Health app data and HomeKit
accessories, enhancing and animating graphics, storing and protecting
data, sending and receiving notifications, and managing files and folders
Each recipe includes sample code on GitHub that you can use right away
■ Use CloudKit APIs to store information in the cloud with ease
■ Create custom keyboards and extensions
■ Access users’ health-related information with HealthKit
■ Interact with accessories inside the user’s home with HomeKit
■ Create vibrant and lifelike user interfaces with UIKit Dynamics
■ Use the Keychain to protect your app’s data
■ Develop location-aware and multitasking-aware apps
■ Work with iOS 8’s audio and video APIs
■ Use Event Kit UI to manage calendars, dates, and events
■ Take advantage of the accelerometer and the gyroscope
■ Get working examples for implementing gesture recognizers
■ Retrieve and manipulate contacts and groups from the
Address Book
■ Determine a camera’s availability and access the Photo Library
Vandad Nahavandipoor is an iOS and OS X programmer for an international
media group with over 7,000 employees in more than 29 countries Previously
he worked for Lloyds Banking Group in England to deliver their iOS apps to millions
of users in the UK.
iOS 8 Swift Programming Cookbook
SOLUTIONS & EXAMPLES FOR IOS APPS
Trang 2iOS 8 Swift Programming Cookbook
“ From coding with new iOS features to tackling complex requirements, Vandad's iOS
Programming Cookbook always provides me with the resources I need and good, clear, practical examples Now that I'm starting out using Swift, this edition is my Bible—I'd have been lost without it.—João Duarte ”
Senior iOS Software Engineer
Entirely rewritten for Apple’s Swift programming language, this updated
cookbook helps you overcome the vexing issues you’re likely to face when
creating apps for iOS devices
You’ll find hundreds of new and revised recipes for using the iOS 8 SDK,
including techniques for working with Health app data and HomeKit
accessories, enhancing and animating graphics, storing and protecting
data, sending and receiving notifications, and managing files and folders
Each recipe includes sample code on GitHub that you can use right away
■ Use CloudKit APIs to store information in the cloud with ease
■ Create custom keyboards and extensions
■ Access users’ health-related information with HealthKit
■ Interact with accessories inside the user’s home with HomeKit
■ Create vibrant and lifelike user interfaces with UIKit Dynamics
■ Use the Keychain to protect your app’s data
■ Develop location-aware and multitasking-aware apps
■ Work with iOS 8’s audio and video APIs
■ Use Event Kit UI to manage calendars, dates, and events
■ Take advantage of the accelerometer and the gyroscope
■ Get working examples for implementing gesture recognizers
■ Retrieve and manipulate contacts and groups from the
Address Book
■ Determine a camera’s availability and access the Photo Library
Vandad Nahavandipoor is an iOS and OS X programmer for an international
media group with over 7,000 employees in more than 29 countries Previously
he worked for Lloyds Banking Group in England to deliver their iOS apps to millions
of users in the UK.
iOS 8 Swift Programming Cookbook
Trang 3Vandad Nahavandipoor
iOS 8 Swift Programming
Cookbook
Trang 4iOS 8 Swift Programming Cookbook
by Vandad Nahavandipoor
Copyright © 2015 Vandad Nahavandipoor All rights reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use Online editions are
also available for most titles (http://safaribooksonline.com) For more information, contact our corporate/ institutional sales department: 800-998-9938 or corporate@oreilly.com.
Production Editor: Nicole Shelby
Proofreader: Gillian McGarvey
Indexer: Lucie Haskins
Cover Designer: Ellie Volckhausen
Interior Designer: David Futato
Illustrator: Rebecca Demarest
November 2014: First Edition
Revision History for the First Edition:
2014-11-06: First release
See http://oreilly.com/catalog/errata.csp?isbn=9781491908693 for release details.
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc iOS 8 Swfit Programming Cookbook, the
cover image, and related trade dress are trademarks of O’Reilly Media, Inc.
Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks Where those designations appear in this book, and O’Reilly Media, Inc was aware of a trademark claim, the designations have been printed in caps or initial caps.
While the publisher and the author have used good faith efforts to ensure that the information and instruc‐ tions contained in this work are accurate, the publisher and the author disclaim all responsibility for errors
or omissions, including without limitation responsibility for damages resulting from the use of or reliance
on this work Use of the information and instructions contained in this work is at your own risk If any code samples or other technology this work contains or describes is subject to open source licenses or the intel‐ lectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights.
Trang 5Table of Contents
Preface ix
1 The Basics 1
1.1 Adding Blur Effects to Your Views 9
1.2 Presenting Temporary Information on the Screen with Popovers 12
1.3 Displaying Images with UIImageView 17
1.4 Displaying Static Text with UILabel 21
1.5 Adding Buttons to the User Interface with UIButton 27
1.6 Displaying Alerts and Action Sheets 31
1.7 Creating, Using, and Customizing Switches with UISwitch 37
1.8 Picking Values with the UIPickerView 41
1.9 Picking the Date and Time with UIDatePicker 46
1.10 Implementing Range Pickers with UISlider 49
1.11 Grouping Compact Options with UISegmentedControl 53
1.12 Presenting Sharing Options with UIActivityViewController 57
1.13 Presenting Custom Sharing Options with UIActivityViewController 63
1.14 Displaying an Image on a Navigation Bar 68
1.15 Adding Buttons to Navigation Bars Using UIBarButtonItem 70
1.16 Accepting User Text Input with UITextField 75
1.17 Displaying Long Lines of Text with UITextView 83
1.18 Creating Scrollable Content with UIScrollView 88
1.19 Loading Web Pages with WebKit 91
1.20 Loading Web Pages with UIWebView 94
1.21 Displaying Progress with UIProgressView 97
1.22 Creating a Provision Profile 99
2 Extensions 107
2.1 Adding New Photo Editing Capabilities to the Photos App 110
Trang 62.3 Building Custom Keyboards 129
2.4 Creating a Service Within Your App with Action Extensions 137
2.5 Adding Widgets to the Notification Center 144
3 Managing Health Data with HealthKit 155
3.1 Setting Up Your App for HealthKit 155
3.2 Retrieving and Modifying the User’s Weight Information 160
3.3 Accessing and Modifying the User’s Height Information 165
3.4 Retrieving User Characteristics 172
3.5 Observing Changes to the User’s Health Information 177
3.6 Reading and Modifying the User’s Total Calories Burned 183
3.7 Converting Between Units 196
4 Managing Home Appliances with HomeKit 201
4.1 Simulating HomeKit Accessories 203
4.2 Managing the User’s Home in HomeKit 212
4.3 Adding Rooms to the User’s Home 219
4.4 Specifying Zones in the User’s Home 224
4.5 Discovering and Managing HomeKit Enabled Accessories 229
4.6 Interacting with HomeKit Accessories 234
4.7 Grouping Services of HomeKit Accessories 242
5 Creating Dynamic and Interactive User Interfaces 247
5.1 Adding Gravity to Your UI Components 249
5.2 Detecting and Reacting to Collisions Between UI Components 250
5.3 Animating Your UI Components with a Push 257
5.4 Attaching Multiple Dynamic Items to Each Other 262
5.5 Adding a Dynamic Snap Effect to Your UI Components 266
5.6 Assigning Characteristics to Your Dynamic Effects 269
6 Table and Collection Views 275
6.1 Populating a Table View with Data 277
6.2 Enabling Swipe Deletion of Table View Cells 281
6.3 Constructing Headers and Footers in Table Views 282
6.4 Displaying a Refresh Control for Table Views 288
6.5 Providing Basic Content to a Collection View 292
6.6 Feeding Custom Cells to Collection Views Using xib Files 297
6.7 Handling Events in Collection Views 303
Trang 77 Concurrency and Multitasking 315
7.1 Performing UI-Related Tasks 319
7.2 Performing Non-UI Related Tasks 321
7.3 Performing Tasks After a Delay 329
7.4 Performing a Task Only Once 331
7.5 Grouping Tasks Together 332
7.6 Creating Simple Concurrency with Operations 335
7.7 Creating Dependency Between Operations 340
7.8 Firing Periodic Tasks 342
7.9 Completing a Long-Running Task in the Background 345
7.10 Adding Background Fetch Capabilities to Your Apps 348
7.11 Playing Audio in the Background 357
7.12 Handling Location Changes in the Background 360
7.13 Handling Network Connections in the Background 363
8 Security 367
8.1 Authenticating the User with Touch ID 373
8.2 Enabling Security and Protection for Your Apps 376
8.3 Storing Values in the Keychain 381
8.4 Finding Values in the Keychain 383
8.5 Updating Existing Values in the Keychain 386
8.6 Deleting Existing Values in the Keychain 390
8.7 Sharing Keychain Data Between Multiple Apps 392
8.8 Writing to and Reading Keychain Data from iCloud 397
8.9 Storing Files Securely in the App Sandbox 399
8.10 Securing Your User Interface 403
9 Core Location, iBeacon, and Maps 407
9.1 Detecting Which Floor the User Is on in a Building 407
9.2 Defining and Processing iBeacons 409
9.3 Pinpointing the Location of a Device 415
9.4 Displaying Pins on a Map View 420
9.5 Displaying Custom Pins on a Map View 423
9.6 Searching on a Map View 429
9.7 Displaying Directions on the Map 434
9.8 Customizing the View of the Map with a Camera 440
10 Gesture Recognizers 445
10.1 Detecting Swipe Gestures 447
10.2 Detecting Rotation Gestures 449
10.3 Detecting Panning and Dragging Gestures 452
Trang 810.5 Detecting Tap Gestures 458
10.6 Detecting Pinch Gestures 460
10.7 Detecting Screen Edge Pan Gestures 462
11 Networking and Sharing 465
11.1 Downloading Data Using NSURLSession 465
11.2 Downloading Data in the Background Using NSURLSession 473
11.3 Uploading Data Using NSURLSession 477
11.4 Downloading Asynchronously with NSURLConnection 479
11.5 Handling Timeouts in Asynchronous Connections 483
11.6 Downloading Synchronously with NSURLConnection 484
11.7 Customizing URL Requests 487
11.8 Sending HTTP Requests with NSURLConnection 488
11.9 Serializing and Deserializing JSON Objects 491
11.10 Integrating Social Sharing into Your Apps 495
12 Multimedia 499
12.1 Playing Audio Files 499
12.2 Recording Audio 501
12.3 Playing Video Files 509
12.4 Capturing Thumbnails from Video Files 513
12.5 Accessing the Music Library 516
13 Address Book 525
13.1 Retrieving a Person Entity with System UI 527
13.2 Retrieving a Property of a Person Entity with System UI 531
13.3 Requesting Access to the Address Book 534
13.4 Retrieving All the People in the Address Book 537
13.5 Retrieving Properties of Address Book Entries 538
13.6 Inserting a Person Entry into the Address Book 541
13.7 Inserting a Group Entry into the Address Book 544
13.8 Adding Persons to Groups 547
13.9 Searching the Address Book 549
13.10 Retrieving and Setting a Person’s Address Book Image 552
14 Files and Folder Management 555
14.1 Finding the Paths of the Most Useful Folders on Disk 557
14.2 Writing to and Reading from Files 559
Trang 915 Camera and the Photo Library 577
15.1 Detecting and Probing the Camera 579
15.2 Taking Photos with the Camera 583
15.3 Taking Videos with the Camera 587
15.4 Storing Photos in the Photo Library 590
15.5 Storing Videos in the Photo Library 595
15.6 Searching for and Retrieving Images and Videos 597
15.7 Reacting to Changes in Images and Videos 602
15.8 Editing Images and Videos Right on the Device 608
16 Notifications 615
16.1 Sending Notifications 616
16.2 Listening for and Reacting to Notifications 618
16.3 Listening and Reacting to Keyboard Notifications 621
16.4 Scheduling Local Notifications 630
16.5 Listening for and Reacting to Local Notifications 636
16.6 Handling Local System Notifications 639
16.7 Setting Up Your App for Push Notifications 642
16.8 Delivering Push Notifications to Your App 648
16.9 Reacting to Push Notifications 656
17 Core Data 659
17.1 Performing Batch Updates on Core Data 661
17.2 Writing to Core Data 664
17.3 Reading Data from Core Data 666
17.4 Deleting Data from Core Data 668
17.5 Sorting Data in Core Data 670
17.6 Boosting Data Access in Table Views 672
17.7 Implementing Relationships in Core Data 680
17.8 Fetching Data in the Background 686
17.9 Using Custom Data Types in Your Core Data Model 690
18 Dates, Calendars, and Events 697
18.1 Constructing Date Objects 698
18.2 Retrieving Date Components 699
18.3 Requesting Permission to Access Calendars 700
18.4 Retrieving Calendar Groups on an iOS Device 705
18.5 Adding Events to Calendars 707
18.6 Accessing the Contents of Calendars 712
18.7 Removing Events from Calendars 714
18.8 Adding Recurring Events to Calendars 718
Trang 1018.10 Adding Alarms to Calendars 725
19 Graphics and Animations 729
19.1 Drawing Text 734
19.2 Drawing Images 736
19.3 Constructing Resizable Images 739
19.4 Drawing Lines 745
19.5 Constructing Paths 751
19.6 Drawing Rectangles 755
19.7 Adding Shadows to Shapes 759
19.8 Drawing Gradients 764
19.9 Transforming Views 770
19.10 Animating Views 776
20 Core Motion 787
20.1 Retrieving Altitude Data 788
20.2 Retrieving Pedometer Data 790
20.3 Detecting the Availability of an Accelerometer 794
20.4 Detecting the Availability of a Gyroscope 796
20.5 Retrieving Accelerometer Data 797
20.6 Detecting Shakes on an iOS Device 801
20.7 Retrieving Gyroscope Data 802
21 Cloud 805
21.1 Setting Up Your App for CloudKit 807
21.2 Storing Data with CloudKit 812
21.3 Retrieving Data with CloudKit 820
21.4 Querying the Cloud with CloudKit 826
21.5 Observing Changes to Records in CloudKit 831
21.6 Retrieving User Information from CloudKit 839
21.7 Storing and Synchronizing Dictionaries in iCloud 846
21.8 Creating and Managing Files and Folders in iCloud 851
21.9 Searching for Files and Folders in iCloud 855
Index 863
Trang 11About a year ago, noticing that Apple had not updated Objective-C much over the pastfew years, I got intimations that they were working on a new language or frameworkfor iOS development, and even suggested it to my friends at work They laughed andsaid, “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 wasdwarfed by this edition, where everything had to be rewritten in Swift Furthermore, somany recipes are new that I have lost count I can affirm that this edition of the book isthe most extensive effort since my initial effort to write the first edition All the codehas 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 Con‐ference (WWDC) 2014 We thought it would be a normal WWDC with tons of newAPIs and just some additions to Objective-C like previous years at WWDC But we wereall surprised At least I was
I think Swift is a great language and has been needed for iOS development for a longtime 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 Explainingthose concepts in early editions of this book, I felt they were sometimes unnecessaryand “got in the way” when developing iOS apps Instead of focusing on writing greatapps, 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 develop‐ment, because so many of its features are unneeded in basic applications and are more
Trang 12the frameworks are usually what we struggle with The difficulty is exacerbated by a lack
of documentation for APIs Many development companies, Apple included, seem tothink they can just put out documentation for each API in isolation They don’t under‐stand 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 carrotand 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 withthat 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 bemore than happy to help fellow developers out
Audience
I assume you know your way around Xcode and have written a few lines of Swift codebefore This book does not offer a tutorial about how to write Swift code, but will showyou interesting and powerful iOS apps using Swift There is a big difference I don’texplain the Swift language in this book, because Apple has already done that quite thor‐oughly 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 youare not comfortable with Swift yet, I suggest that you read the aforementioned guidepublished 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 purchasethis book in the hopes that it will make you a software engineer, because that is not itsgoal 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 softwareengineer 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
Trang 13Chapter 2, Extensions
Finally! Apple allows us to extend iOS with these little binaries that ship with ourapps, get integrated into iOS, and can live by themselves without the need for ourapps to be running in the background For instance, we can now create customkeyboards that can get installed on the user’s device and the user can use thosekeyboards even if our app is not running This feature has been in Android prettymuch 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 mindabout its value for you
Chapter 3, Managing Health Data with HealthKit
The HealthKit framework allows iOS apps to integrate with the health-informationthat is stored on the user’s device This information belongs to the current user ofthe device and can contain very detailed information, such as the amount of fat thatthe 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 discoverthese 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 yousuch things as how to model gravity and other dynamic behaviors, and how to attachthose 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 theuser 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 workeverywhere This chapter teaches you all you need to know to create great func‐tionality 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 heavydownloading tasks and heavy calculations on the UI thread because you’ll trashyour users’ experience In fact, iOS will actually kill your app if you block the UIthread for more than five seconds Concurrency and multithreading is taught inthis chapter to allow you to create fluid apps that do all the work they need, without
Trang 14Chapter 8, Security
Do you store usernames and passwords using NSUserDefaults? If your answer isyes, you desperately need to read this chapter We will talk about Touch ID authen‐tication and many Keychain-related functionalities You will also learn how to makeyour 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 thesupermarket 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 corelocation 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 peopleclapping and going “Ooooh.” Apple engineers had placed a swipe gesture on theview, which allowed Mr Jobs to scroll up and down the page so smoothly Thischapter 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 chapterteaches you how to do background and foreground networking to download andupload 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 videofiles and play those files for the user, or simply grab the data for those files forwhatever processing you need to do If you are creating a game, for instance, youmight want to play some background music for the user to add some excitement toyour 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 forperformance reasons, but I believe Apple has just assigned a low priority to theframework 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 AddressBook 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
Trang 15Chapter 15, Camera and the Photo Library
iOS keeps a library of all the videos and photos that the user has on her device Theapp 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 videosstored on the device, so that you can integrate this functionality into your appswithout 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 applicationmemory space You can catch this notification in any object inside your app to getnotified 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 appnotifications
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 isthere not to like? Core Data is an amazingly simple technology but requires a certainunderstanding of its underlying architecture I will walk you through that in thischapter
Chapter 18, Dates, Calendars, and Events
Dates are important, whether we are talking about editable dates or a date with apartner-to-be or just dates as they are in a calendar Even though I won’t be handingout 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 graphicsand 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 othersimple information, you can start counting the calories that they are burning, dis‐play them motivating messages, and so on In this chapter you will learn about thepedometer, accelerometer, and gyroscope, which are some great sensors that Applehas 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
Trang 16Additional Resources
Swift is a relatively new language with which you’ll want to familiarize yourself if youcare about iOS development As I mentioned before, I recommend that you read Apple’sguide on the Swift Programming Language You won’t be disappointed
From time to time, I refer to official Apple documentation Some of Apple’s descriptionsare right on the mark, and there is no point in trying to restate them Throughout thisbook, I have listed the most important documents and guides in the official Apple doc‐umentation that every professional iOS developer should read
For starters, I suggest that you have a look at the iOS Human Interface Guidelines forall iOS devices This document will tell you everything you need to know about devel‐oping engaging and intuitive user interfaces for all iOS devices Every iOS programmershould read this document In fact, I believe this should be required reading for theproduct 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 iOSDeveloper 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:
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 deter‐mined by context
This icon signifies a tip, suggestion, or general note
Trang 17This icon indicates a warning or caution.
Using Code Examples
Supplemental material (code examples, exercises, etc.) is available for download at
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 2014 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 permissions@oreilly.com
Safari® Books Online
Safari Books Online (www.safaribooksonline.com) is anon-demand digital library that delivers expert content inboth book and video form from the world’s leadingauthors in technology and business
Technology professionals, software developers, web designers, and business and crea‐tive professionals use Safari Books Online as their primary resource for research, prob‐lem solving, learning, and certification training
Safari Books Online offers a range of product mixes and pricing programs for organi‐zations, government agencies, and individuals Subscribers have access to thousands ofbooks, training videos, and prepublication manuscripts in one fully searchable databasefrom publishers like O’Reilly Media, Prentice Hall Professional, Addison-Wesley Pro‐fessional, Microsoft Press, Sams, Que, Peachpit Press, Focal Press, Cisco Press, John
Trang 18Press, Apress, Manning, New Riders, McGraw-Hill, Jones & Bartlett, Course Technol‐ogy, and dozens more For more information about Safari Books Online, please visit usonline.
Find us on Facebook: http://facebook.com/oreilly
Follow us on Twitter: http://twitter.com/oreillymedia
Watch us on YouTube: http://www.youtube.com/oreillymedia
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 througheverything 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 yourhard work Thank you to Niklas Saers, who did a great job technically reviewing thisbook
Rachel Roumeliotis has also been a fantastic help at O’Reilly She has supported methroughout my work She was very happy when I decided to rewrite this book for Swift
Trang 19Also thank you to Heather Scherer and Amy Jollymore of O’Reilly for sorting out manyaspects 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 toacknowledge 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 loveyou “Duktig tjej”!
Trang 21All 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’ inter‐actions Any interaction between the user and your application is sent to a view, whichthen 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 men‐
tioned Think of a view controller as a bridge between the model and your views Thiscontroller interprets what is happening on one side and uses that information to alterthe other side as needed For instance, if the user changes a field in a view, the controllermakes sure the model changes in response And if the model gets new data, the controllertells the view to reflect it
In this chapter, you will learn how to create the structure of an iOS application and how
Trang 22I 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 teachyou how to program in Swift Apple has already released a full book more than 500pages long that teaches you how to use Swift But in case you’re using this book in parallelwith 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:
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 Ifyou 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 orappended 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 immutablearray:
let allStrings "Swift" , "Objective-C" ]
If you want to create a mutable array, initialize an empty mutable array and then appendvalues 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" )
Trang 23allStrings append ( "Objective-C" )
println ( allStrings [ ]) /* Prints out "Swift" */
allStrings insert ( "C++" , atIndex: 0
println ( allStrings [ ]) /* 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 andanother 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:
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 amutable version of the same dictionary, use the var keyword like so:
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" ,
Trang 24Grouping Functionality with Classes and Structures in Swift
Structures are value types That means that when they are passed around from onefunction to another, for instance, a new instance of them is created and then passed tothe function Classes are reference types, so that they can be passed around withouthaving 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 withthe keyword mutating Now we can create a function that can change the value of anyPerson instance to any given string:
@ UIApplicationMain
class AppDelegate: UIResponder , UIApplicationDelegate
var window: UIWindow?
func changeFirstNameOf (var person: Person , to: String ){
launchOptions: [ NSObject AnyObject ] ) -> Bool
var vandad Person ( firstName: "Vandad" , lastName: "Nahavandipoor" )
changeFirstNameOf ( vandad , to: "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
Trang 25Now off to classes Classes are reference types and when passed to functions, are passedjust 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" )
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 ,
Trang 26Let’s explore the first type of equality With our Person class, it makes sense to declaretwo 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 {
let andy Person ( firstName: "Andy" , lastName: "Oram" )
let someoneElse Person ( firstName: "Andy" , lastName: "Oram" )
if andy == someoneElse {
Trang 27The three-character === operator would say they’re different, because they are separatevariables 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 createsome 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
postfix func++ inout person: Person ) -> Person {
let newPerson Person ( fullName: person fullName , age: person age )
And now we can use them like so:
var vandad Person ( fullName: "Vandad Nahavandipoor" , age: 29 )
var sameAgeVandad vandad++
Trang 28Declaring and Using Enumerations in Swift
Enumerations are very sophisticated in Swift indeed They can be of any given type Forinstance, they can be strings:
enum CarClassification: String {
case Estate "Estate"
case Hatchback "Hatchback"
case Saloon "Saloon"
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 {
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"
Trang 29let year: Int
}
We can have a function that classifies our cars and, for each classification, decides howold 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
UIVisualEffectView
This is a simple UIView subclass that can accept and apply a visual effect of type
Trang 30you have the visual effect view, you can add it to any other existing view that youhave on or off screen.
Figure 1-1 shows Safari’s icon rendered with a visual effect view that includes a blureffect, 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 viewcontroller The image is Safari.app’s icon I have explained the process of extracting thisicon in Recipe 19.2, so if you are curious and don’t have any other icon to use on yourview controller, you can have a look at the aforementioned section of the book to learnhow to extract Safari’s icon (or any other app’s icon for that matter) My view controllerlooks like Figure 1-2 at the moment
Trang 31Figure 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 thencreate a visual effect view on top of our current view, like so:
import UIKit
class ViewController: UIViewController
override funcviewDidLoad ()
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:
enumUIBlurEffectStyle Int
case ExtraLight
case Light
Trang 32In our example code, we used a light blur effect, but you can use any of the ones justlisted 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 ofthe aforementioned type is the UIVibrancyEffect This class is very similar to theUIBlurEffect 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 manycolorful photos on it, it is best to add a UIVibrancyEffect to a visual effect view andconstruct your popup using this visual effect view That way, the colors underneath thepopup (colors that come from the photos) will be more appealing to the user and theuser 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 interactwith it When they are done, this view will need to get dismissed On an iPad, you wouldlike 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 con‐trollers using the presentPopoverFromBarButtonItem:permittedArrowDirections:animated: method of the popup controller A popup controller has to originatefrom a specific rectangular space on the screen This is usually a button or a control onthe screen where the user taps and expects to see the popover This item could be of typeUIBarButtonItem, 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 usingthe presentPopoverFromRect:permittedArrowDirections:animated: method
Trang 33in the table view, the popover will be dismissed and the selected item will be passed tothe 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 completionhandler Therefore, processing is very decoupled and it is best to start our implemen‐tation of this controller first Before we begin, we need to define a few handy extensions:
extension Array {
Trang 34}
}
extension NSIndexPath {
class funcfirstIndexPath () -> NSIndexPath {
return NSIndexPath ( forRow: 0 inSection: 0
/* 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 ]()
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 itemsand show them on the navigation bar without an animation:
Trang 35tableView registerClass ( UITableViewCell classForCoder (),
forCellReuseIdentifier: TableViewValues identifier )
}
override init ( style: UITableViewStyle ) {
}
override func viewDidLoad ()
cancelBarButtonItem UIBarButtonItem ( title: "Cancel" , style: Plain ,
target: self, action: "performCancel" )
navigationItem leftBarButtonItem cancelBarButtonItem
override func tableView ( tableView: UITableView ,
didSelectRowAtIndexPath indexPath: NSIndexPath ) {
let selectedItem items [ indexPath ]
selectionHandler? selectedItem: selectedItem )
dismissViewControllerAnimated ( true , completion: nil )
}
This way the root view controller can become the selection handler and get notifiedwhenever the user has selected an item As soon as our table view appears on the screen,
we will set the preferred size of the popover controller:
override func viewWillAppear ( animated: Bool ) {
preferredContentSize CGSize ( width: 300 , height: 200 )
}
Last but not least, we will display the items that we have prepared, inside the table view:
override func tableView ( tableView: UITableView ,
numberOfRowsInSection section: Int ) -> Int
return items count
}
override func tableView ( tableView: UITableView ,
cellForRowAtIndexPath indexPath: NSIndexPath ) -> UITableViewCell
Trang 36cell textLabel text items [ indexPath ]
return cell
}
Now let’s go to our root view controller and construct an instance of our popover con‐troller We place it inside a navigation bar so that the popover controller has a place toput the bar button items:
import UIKit
class ViewController: UIViewController
var selectedItem: String?
lazy var popoverContentController: UINavigationController
let controller PopoverTableViewController ( style: Plain )
controller selectionHandler self selectionHandler
let navigationController UINavigationController (
rootViewController: controller )
return navigationController
}()
lazy var popoverController: UIPopoverController
return UIPopoverController ( contentViewController:
funcselectionHandler ( selectedItem: String ){
self selectedItem selectedItem
/* Do something with the selected item */
}
I’ve left the implementation quite open, as you may want to do something special withthe value that the table view passed to you For instance, you may want to display analert view to the user using what you have learned in Recipe 1.6 The plus (+) button on
Trang 37of the popover Have another look at Figure 1-3 Can you see the arrow that is originatingfrom the plus (+) button? That is the source of the popover In this case, the arrow ispointing upwards towards the button, but you can change this behavior by changingthe value of the permittedArrowDirections parameter of the aforementioned method
to any of the values inside the UIPopoverArrowDirection structure
The UIImageView is one of the least-complicated classes in the iOS SDK As you know,
an image view is responsible for displaying images There are no tips or tricks involved.All you have to do is instantiate an object of type UIImageView and add it to your views.Now, I have a photo of Safari’s icon and I would like to display it in an image view Let’sstart with our view controller’s implementation file:
import UIKit
class ViewController: UIViewController
let image UIImage ( named: "Safari" )
var imageView: UIImageView
required init( coder aDecoder: NSCoder ){
imageView UIImageView ( image: image )
Trang 38Go ahead and add the image view to your view controller’s view:
override func viewDidLoad ()
imageView center view center
view addSubview ( imageView )
}
Now if we run the app, we will see something similar to Figure 1-4
Figure 1-4 An image view that is too big to fit on the screen
I should mention that the Safari image that I’m loading into this image view is 512×512pixels, and as you can see, it certainly doesn’t fit into the screen So how do we solve thisproblem? First, we need to make sure that we are initializing our image view using theinitWithFrame: method, instead of the initWithImage: method, as the latter will setthe width and height of the image view to the exact width and height of the image Solet’s remedy that first:
import UIKit
class ViewController: UIViewController
Trang 39imageView UIImageView ( frame: view bounds )
imageView image image
imageView center view center
view addSubview ( imageView )
}
}
So how does the app look now? See Figure 1-5
Figure 1-5 An image whose width is squished to fit the width of the screen
This isn’t really what we wanted to do, is it? Of course, we got the frame of the imageview right, but the way the image is rendered in the image view isn’t quite right So whatcan we do? We can rectify this by setting the contentMode property of the image view.This property is of type UIContentMode
Here is an explanation of some of the most useful values in the UIViewContentModeenumeration:
Trang 40The clipsToBounds property of UIView denotes whether the sub‐
views of that view should be clipped if they go outside the bound‐
aries of the view You use this property if you want to be absolutely
certain that the subviews of a specific view will not get rendered
outside the boundaries of that view (or that they do get rendered
outside the boundaries, depending on your requirements)
So to make sure the image fits into the image view’s boundaries and that the aspect ratio
of the image is right, we need to use the UIViewContentModeScaleAspectFit content mode:
import UIKit
class ViewController: UIViewController
let image UIImage ( named: "Safari" )
var imageView: UIImageView!
override func viewDidLoad ()
imageView UIImageView ( frame: view bounds )
imageView contentMode ScaleAspectFit
imageView image image
imageView center view center
view addSubview ( imageView )
}
}