iOS 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor 2024 Scribd Download
iOS 7 Programming Cookbook 2nd Edition Vandad Nahavandipoor 2024 Scribd Download
com
https://ebookname.com/product/ios-7-programming-
cookbook-2nd-edition-vandad-nahavandipoor/
OR CLICK BUTTON
DOWLOAD NOW
https://ebookname.com/product/ios-4-programming-cookbook-
solutions-examples-for-iphone-ipad-and-ipod-touch-apps-1st-
edition-vandad-nahavandipoor/
https://ebookname.com/product/writing-game-center-apps-in-ios-
bringing-your-players-into-the-game-1st-edition-vandad-
nahavandipoor/
https://ebookname.com/product/ios-and-os-x-network-programming-
cookbook-1st-edition-jon-hoffman/
https://ebookname.com/product/programming-arcgis-with-python-
cookbook-2nd-edition-eric-pimpler/
IOS development with Xamarin cookbook over 100 exciting
recipes to help you develop iOS applications with
Xamarin 2nd Edition Tavlikos
https://ebookname.com/product/ios-development-with-xamarin-
cookbook-over-100-exciting-recipes-to-help-you-develop-ios-
applications-with-xamarin-2nd-edition-tavlikos/
https://ebookname.com/product/swift-pocket-reference-2nd-edition-
programming-for-ios-and-os-x-anthony-gray/
https://ebookname.com/product/ios-sdk-programming-a-beginners-
guide-1st-edition-james-brannan/
https://ebookname.com/product/learning-ios-programming-from-
xcode-to-app-store-third-edition-alasdair-allan/
https://ebookname.com/product/java-extreme-programming-
cookbook-1st-edition-eric-m-burke/
iOS 7 Programming Cookbook
Vandad Nahavandipoor
iOS 7 Programming Cookbook
by Vandad Nahavandipoor
Copyright © 2014 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://my.safaribooksonline.com). For more information, contact our corporate/
institutional sales department: 800-998-9938 or [email protected].
Editors: Andy Oram and Rachel Roumeliotis Indexer: Angela Howard
Production Editor: Christopher Hearse Cover Designer: Randy Comer
Copyeditor: Zyg Group, LLC Interior Designer: David Futato
Proofreader: Julie Van Keuren Illustrator: Rebecca Demarest
Nutshell Handbook, the Nutshell Handbook logo, and the O’Reilly logo are registered trademarks of O’Reilly
Media, Inc., iOS 7 Programming Cookbook, the image of a Cowan’s shrew tenrec, 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 trade‐
mark claim, the designations have been printed in caps or initial caps.
While every precaution has been taken in the preparation of this book, the publisher and author assume no
responsibility for errors or omissions, or for damages resulting from the use of the information contained
herein.
ISBN: 978-1-449-37242-2
[QG]
Table of Contents
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
iii
1.27. Presenting Master-Detail Views with UISplitViewController 148
1.28. Enabling Paging with UIPageViewController 153
1.29. Displaying Popovers with UIPopoverController 158
iv | Table of Contents
5.9. Providing Contextual Menus on Collection View Cells 311
6. Storyboards. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
6.1. Adding a Navigation Controller to a Storyboard 316
6.2. Passing Data from One Screen to Another 318
6.3. Adding a Tab Bar Controller to a Storyboard 325
6.4. Introducing Custom Segue Transitions to Your Storyboard 328
6.5. Placing Images and Other UI Components on Storyboards 332
7. Concurrency. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
7.1. Constructing Block Objects 342
7.2. Accessing Variables in Block Objects 346
7.3. Invoking Block Objects 352
7.4. Performing UI-Related Tasks with GCD 354
7.5. Executing Non-UI Related Tasks Synchronously with GCD 358
7.6. Executing Non-UI Related Tasks Asynchronously with GCD 361
7.7. Performing Tasks after a Delay with GCD 368
7.8. Performing a Task Only Once with GCD 371
7.9. Grouping Tasks Together with GCD 373
7.10. Constructing Your Own Dispatch Queues with GCD 377
7.11. Running Tasks Synchronously with Operations 380
7.12. Running Tasks Asynchronously with Operations 387
7.13. Creating Dependency Between Operations 393
7.14. Creating Timers 395
7.15. Creating Concurrency with Threads 400
7.16. Invoking Background Methods 406
7.17. Exiting Threads and Timers 407
8. Security. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
8.1. Enabling Security and Protection for Your Apps 418
8.2. Storing Values in the Keychain 422
8.3. Finding Values in the Keychain 424
8.4. Updating Existing Values in the Keychain 429
8.5. Deleting Exiting Values in the Keychain 432
8.6. Sharing Keychain Data Between Multiple Apps 434
8.7. Writing to and Reading Keychain Data from iCloud 440
8.8. Storing Files Securely in the App Sandbox 443
8.9. Securing Your User Interface 446
Table of Contents | v
9.3. Pinpointing the Location of a Device 453
9.4. Displaying Pins on a Map View 455
9.5. Displaying Pins with Different Colors on a Map View 459
9.6. Displaying Custom Pins on a Map View 465
9.7. Converting Meaningful Addresses to Longitude and Latitude 468
9.8. Converting Longitude and Latitude to a Meaningful Address 470
9.9. Searching on a Map View 472
9.10. Displaying Directions on the Map 475
vi | Table of Contents
13.1. Requesting Access to the Address Book 564
13.2. Retrieving a Reference to an Address Book 568
13.3. Retrieving All the People in the Address Book 571
13.4. Retrieving Properties of Address Book Entries 573
13.5. Inserting a Person Entry into the Address Book 577
13.6. Inserting a Group Entry into the Address Book 581
13.7. Adding Persons to Groups 584
13.8. Searching the Address Book 587
13.9. Retrieving and Setting a Person’s Address Book Image 592
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1007
Table of Contents | ix
Preface
This edition of the book is not just an update, but a total remake of the previous edition.
iOS 7 changed everything: the look and feel, the way we use our iOS devices, and most
importantly, the way we program for iOS devices. This called for a substantial rewrite
indeed. I have added roughly 50 new recipes to this book, talking about things such as
UIKit dynamics, collection views, the keychain, push notifications, and whatnot. I have
also gone through all the example codes and figures and updated them for iOS 7.
iOS 7 is a huge step forward for this amazing operating system that we all, as program‐
mers and users, have grown to love and enjoy programming for. You must have noticed
how the focus of iOS 7 is on being dynamic: how your UI should adapt to various
movements and motions that can be applied to the device. What I mean by that is Apple
wants developers to really look at the details of their apps and bring real-world physics
and dynamics into them. That’s why Apple introduced UIKit Dynamics to the SDK, and
that is why this book has a whole chapter dedicated to this concept. The more expensive
a high-end device such as the new iPhone becomes, the more demanding the users will
get as well. Nobody blames them, though! They have just bought a fantastic and top-
of-the-line new iPhone or iPad and they want to see amazing apps running on them,
leveraging all the capabilities that those devices have to offer.
That is why now more than ever developers have to get an in-depth knowledge of the
SDK and what the SDK has to offer to the developers so that we can create better and
faster apps for iOS users. Apple introduced a lot of cool new APIs to the iOS 7 SDK, and
we are going to explore them in this book.
The focus of iOS 7 is dynamics!
Before you read about this book, maybe you’d like to know about my background a bit
and how I can help you through this journey. I will just briefly let you know who I am
and how I got to love iOS. I started out writing Basic code for my Commodore 64 when
I was a kid. I then moved on to buy my own PC and started experimenting with Assembly
code. At first, it was 8-bit Assembly for DOS. I then moved onto writing my own hobby
xi
operating system, which was never really released as a commercial product, for 32-bit
Intel x86 CPU architectures.
Among all the programming languages that I have programmed in, Assembly and
Objective-C are the two that have really been different from the others, and I’ve really
liked them. Assembly because of the purity of the language: a command does only one
thing and does that one thing well. I believe that I like Objective-C for the same reason,
and in fact iOS shares the same trait with Assembly and Objective-C. Even though iOS
is an operating system and not a programming language, whatever it does, it does it best
and better than its rivals. From its simplicity to the sheer power that you can harvest
from the software and the hardware combined, using technologies such as GCD, the
bar that iOS has set in terms of ease of use and beauty is unprecedented.
This edition of the book has seen all the recipes inside all chapters completely renewed
for iOS 7. All screenshots have been updated, and many more recipes—such as those
related to security and the keychain, UI dynamics, collection views, push and local
notifications, and many more—have exclusively been written for this edition of the
book. I really have had a fun time writing this edition of the book, and packed as it is
with new features, I hope you’ll enjoy reading it. May it be a valuable addition to your
tech-book library.
Audience
I assume you are comfortable with the iOS development environment and know how
to create an app for the iPhone or iPad. This book does not get novice programmers
started but presents useful ways to get things done for iOS programmers ranging from
novices to experts.
xii | Preface
Here is a concise breakdown of the material each chapter covers:
Chapter 1, Implementing Controllers and Views
Explains how Objective-C classes are structured and how objects can be instanti‐
ated. The chapter talks about properties and delegates and subscripting by keys and
indexes. Even if you are competent in Objective-C, I strongly suggest that you read
this chapter, even if you only skim through it, to understand the basic material that
is used in the rest of the book. In this chapter, we will also explore the common
usage of various UI components, such as alert views, segmented controls, switches,
and labels. We will also talk about customizing these components with the latest
APIs provided in the SDK.
Chapter 2, Creating Dynamic and Interactive User Interfaces
Talks about UIKit Dynamics, the newest addition to the UIKit framework. These
dynamics allow you to add real-life physics and dynamics to your UI components.
This will allow you to create even livelier user interfaces with very small effort on
your side.
Chapter 3, Auto Layout and the Visual Format Language
Explains how you can take advantage of Auto Layout in the iOS SDK in order to
construct your UI in such a way that it can be resized and stretched to pretty much
any screen dimension.
Chapter 4, Constructing and Using Table Views
Shows how you can work with table views to create professional-looking iOS ap‐
plications. Table views are very dynamic in nature, and as a result, programmers
sometimes have difficulty understanding how they should work with them. By
reading this chapter and trying out the example code, you will gain the knowledge
that is required to comfortably work with table views.
Chapter 5, Building Complex Layouts with Collection Views
Collection views have been available to OS X programmers for quite some time
now, and Apple decided to provide the same APIs to iOS programmers in the iOS
SDK. Collection views are very much like table views, but they are much more
configurable and dynamic. Where in table views we have the concept of sections
and rows in each section, collection views bring columns to the equation as well,
so that you can display many items in one row if you want to. In this chapter we
will have a look at all the great user interfaces that you can create using collection
views.
Chapter 6, Storyboards
Demonstrates the process of storyboarding, the new way to define the connections
between different screens in your app. The great thing about storyboarding is that
you don’t have to know anything about iOS programming to get a simple app run‐
ning. This helps product analysts, product owners, or designers who work inde‐
pendently of developers to gain knowledge of the UI components iOS offers and to
Preface | xiii
build more robust products. Programmers can also take advantage of storyboarding
to easily create prototypes. Storyboarding is just fun, whether you do it on paper
or using Xcode.
Chapter 7, Concurrency
As humans, we can do many things simultaneously without thinking much about
it. With advances in computer technology, mobile devices are also able to multitask,
and they provide programmers with tools and mechanisms that can accomplish
more than one task at the same time. This is called concurrency. In this chapter, you
will learn about Grand Central Dispatch, Apple’s preferred way of achieving con‐
currency in iOS. You will also learn about timers, threads, and operations.
Chapter 8, Security
iOS is a very secure operating system, and apps that we write for it also have to
adhere to certain security standards and practices. In this chapter, we will discuss
how you can take advantage of keychain APIs to make your apps more secure. We
will also talk about various steps that you can take to make your user interface more
secure.
Chapter 9, Core Location and Maps
Describes how you should use Map Kit and Core Location APIs to develop location-
aware iOS applications. First you will learn about maps, and then you will learn
how to detect a device’s location and tailor your maps with custom annotations.
You will also learn about geocoding and reverse geocoding, as well as some of the
methods of the Core Location framework, which are available only in iOS 7.
Chapter 10, Implementing Gesture Recognizers
Demonstrates how to use gesture recognizers, which enable your users to easily and
intuitively manipulate the graphical interface of your iOS applications. In this
chapter, you will learn how to use all available gesture recognizers in the iOS SDK,
with working examples tested on iOS 7.
Chapter 11, Networking, JSON, XML, and Sharing
Demonstrates the built-in JSON and XML parsers. On top of that, this chapter talks
about various networking APIs and how programmers can build social networking
into our apps to allow our users to share their creations and data to social networks
such as Facebook.
Chapter 12, Audio and Video
Discusses the AV Foundation and Media Player frameworks that are available on
the iOS SDK. You will learn how to play audio and video files and how to handle
interruptions, such as a phone call, while the audio or video is being played. This
chapter also explains how to record audio using an iOS device’s built-in micro‐
phone(s). At the end of the chapter, you will learn how to access the Music Library
and play its media content, all from inside your application.
xiv | Preface
Chapter 13, Address Book
Explains the Address Book framework and how to retrieve contacts, groups, and
their information from the Address Book database on an iOS device. The Address
Book framework is composed entirely of C APIs. Because of this, many Objective-
C developers find it difficult to use this framework, as compared with frameworks
that provide an Objective-C interface. After reading this chapter and trying the
examples for yourself, you will feel much more confident using the Address Book
framework.
Chapter 14, Files and Folder Management
One of the most important tasks that, as developers, we want to perform in our iOS
apps is manipulating files and folders. Whether this means creating, reading from,
writing to, or deleting them, this chapter contains enough material to get you up
and running with file and folder management in the iOS SDK.
Chapter 15, Camera and the Photo Library
Demonstrates how you can determine the availability of front- and back-facing
cameras on an iOS device. You will also learn how to access the photo library using
the Assets Library framework. At the end of the chapter, you will learn about editing
videos right on an iOS device using a built-in view controller.
Chapter 16, Multitasking
Shows multitasking-aware applications that run beautifully on iOS devices. You will
learn about background processing, including how to play audio and retrieve users’
locations in the background, as well as how to download content from a URL while
your application is running in the background. On top of that, we will explore some
of the new APIs that iOS 7 provides to us, in order to enable our apps to download
content periodically while in the background or even while our app is not even
running.
Chapter 17, Notifications
Notifications are objects that can be composed by a source and delivered to multiple
recipients. In this chapter, we will discuss notifications, including local notifications
and push notifications, along with how you can use the latest capabilities built into
Xcode to easily enable these features in your own apps.
Chapter 18, Core Data
Describes the details of Core Data stacks and what they are made out of. You will
then be able to design your own object-oriented data models right into Xcode, using
the Core Data model editor, and also create and retrieve your objects in Core Data.
On top of that, you will learn how to add your own custom data to Core Data and
how to search for data in the background thread, leaving your UI thread ready to
process user events.
Preface | xv
Chapter 19, Dates, Calendars, and Events
Demonstrates the use of the Event Kit and Event Kit UI frameworks in order to
manage calendars and events on an iOS device. You will see how to create, modify,
save, and delete events. You will also learn, through examples, how to add alarms
to calendar events and how to set up CalDAV calendars so that you can share a
single calendar among multiple devices.
Chapter 20, Graphics and Animations
Introduces the Core Graphics framework. You will learn how to draw images and
text on a graphics context; draw lines, rectangles, and paths; and much more. You
will also learn to use the new iOS SDK APIs to capture your views’ contents as
screenshots.
Chapter 21, Core Motion
Explains the Core Motion framework. Using Core Motion, you will access the ac‐
celerometer and the gyroscope on an iOS device. You will also learn how to detect
shakes on a device. Of course, not all iOS devices are equipped with an accelerom‐
eter and a gyroscope, so you will also learn how to detect the availability of the
required hardware.
Chapter 22, iCloud
Shows how to use the iCloud service, which ties devices together and allows them
to share data to provide a seamless user experience as the user moves from one
device to another.
Chapter 23, Pass Kit
Describes Passbook: a virtual wallet, if you will, capable of managing your coupons,
boarding passes, rail and bus tickets, and much more. In this chapter, you will learn
all there is to know in order to be able to create your own digitally signed passes
and distribute them to your users easily.
Additional Resources
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 doc‐
umentation 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 devel‐
oping 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.
xvi | Preface
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.
iOS 7 brings with itself quite a lot of changes to how UI components appear on the
screen. We will talk at great length about these changes and how you, as the programmer,
can use the latest APIs to create great-looking apps for iOS 7. However, I would like to
suggest that you have a look at the iOS 7 UI Transition Guide provided by Apple, which
outlines all the UI changes that have now been made to the latest version of the SDK.
One of the things you will notice when reading Chapter 16 is the use of block objects.
This book concisely explains block objects, but if you require further details on the
subject, I suggest you read “A Short Practical Guide to Blocks”.
Throughout this book, you will see references to “bundles” and loading images and data
from bundles. You will read a concise overview about bundles in this book, but if you
require further information, head over to the “Bundle Programming Guide”.
Preface | xvii
Using Code Examples
Supplemental material (code examples, exercises, etc.) is available for download at
https://github.com/oreillymedia/iOS7_programming_cookbook.
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 ex‐
ample 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 7 Programming Cookbook
by Vandad Nahavandipoor (O’Reilly). Copyright 2014 Vandad Nahavandipoor,
978-1-4493-7242-2.”
If you feel your use of code examples falls outside fair use or the permission given here,
feel free to contact us at [email protected].
xviii | Preface
How to Contact Us
Please address comments and questions concerning this book to the publisher:
We have a web page for this book, where we list errata, examples, and any additional
information. You can access this page at http://oreil.ly/iOS7-Programming-Cookbook.
To comment or ask technical questions about this book, send email to bookques
[email protected].
For more information about our books, courses, conferences, and news, see our website
at http://www.oreilly.com.
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, my lovely editor, has again done an amazing job going through all the
changes that I made in this edition of the book. In fact, the whole book is updated in
this edition, and all example codes and screenshots have also been updated. I’d like to
also thank Krzysztof Grobelny and Krzysztof Gutowski, my great friends and colleagues,
for tech-reviewing this book. Without their help, this book wouldn’t be in your hands.
I’d like to say thank you to Rachel Roumeliotis, for supporting me and Andy, among all
the other admin work that she did for us behind the scenes. Rachel, you may be quiet,
but we’d have to be blind not to notice your hard work in the background. Also, Meghan
Connolly of O’Reilly has been a fantastic sport, listening to my nagging about paper‐
work, and she has been absolute bliss to work with. A thank-you goes to Jessica Hosman
for helping us a great deal with Git issues. Even though I didn’t believe the simple sol‐
utions that she suggested to me would work, they did, and I looked like a fool.
Last but not least, thank you to Alina Rizzoni, Bruno Packham, and Thomas Packham
for being real friends. I feel blessed to know them, and I appreciate their help and
support.
Preface | xix
CHAPTER 1
Implementing Controllers and Views
1.0. Introduction
iOS 7 has introduced a lot of new features to users, as well as tons of new APIs for us
programmers to use and play with. You probably already know that the user interface
has drastically changed in iOS 7. This user interface had stayed intact all the way from
the first version of iOS till now, and because of this, many apps were coded on the
assumption that this user interface would not ever change. Graphic designers are now
faced with the challenge of creating the user interface and thinking about the user ex‐
perience in a way that makes it great for both pre- and post-iOS 7 user interfaces (UIs).
In order to write apps for iOS 7, you need to know some of the basics of the Objective-
C programming language that we will use throughout this book. Objective-C, as its
name implies, is based on C with extensions that allow it to make use of objects. Objects
and classes are fundamental in object-oriented programming (OOP) languages such as
Objective-C, Java, C++, and many others. In Objective-C, like any other object-oriented
language (OOL), you have not only access to objects, but also to primitives. For instance,
the number –20 (minus twenty) can be expressed simply as a primitive in this way:
NSInteger myNumber = -20;
This simple line of code will define a variable named myNumber with the data type of
NSInteger and sets its value to 20. This is how we define variables in Objective-C. A
variable is a simple assignment of a name to a location in memory. In this case, when
we set 20 as the value of the myNumber variable, we are telling the machine that will
eventually run this piece of code to put the aforementioned value in a memory location
that belongs to the variable myNumber.
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.
1
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, 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 men‐
tioned. 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 some 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.
In this chapter, for most of the user interface (UI) components that we
create, we are using a Single View Application template in Xcode. To
reproduce the examples, follow the instructions in “Creating and Run‐
ning Our First iOS App” on page 2. Make sure that your app is uni‐
versal, as opposed to an iPhone or iPad app. A universal app can run
on both iPhone and iPad.
Voilà! Your first iOS app is running in iOS Simulator now. Even though the app is not
exactly impressive, simply displaying a white screen in the simulator, this is just the first
step toward our bigger goal of mastering the iOS SDK, so hold on tight as we embark
on this journey together.
You don’t always have to set a value for a variable, but you need to specify its type and
its name. Here are a few data types that you will need to know about when writing any
typical iOS app:
1.0. Introduction | 3
Mutable Versus Immutable
If a data type is mutable, you can change if after it is initialized. For
instance, you can change one of the values in a mutable array, or add
or remove values. In contrast, you must provide the values to an im‐
mutable data type when you initialize it, and cannot add to them,
remove them, or change them later. Immutable types are useful be‐
cause they are more efficient, and because they can prevent errors when
the values are meant to stay the same throughout the life of the data.
Thus, when you want to assign a string to a variable of type NSString in Objective-C,
you simply have to store the data into a pointer of type NSString *. However, if you are
about to store a floating point value into a variable, you wouldn’t specify it as a pointer
since the data type for that variable is not a class:
/* Set the myFloat variable to PI */
CGFloat myFloat = M_PI;
If you wanted to have a pointer to that floating point variable, you could do so as follows:
/* Set the myFloat variable to PI */
CGFloat myFloat = M_PI;
Getting data from the original float is a simple dereference (myFloat), whereas getting
the value of through the pointer requires the use of the asterisk (*pointerFloat). The
pointer can be useful in some situations, such as when you call a function that sets the
value of a floating-point argument and you want to retrieve the new value after the
function returns.
Going back to classes, we probably have to talk a bit more about classes before things
get lost in translation, so let’s do that next.
1.0. Introduction | 5
• The class has to be derived from a superclass, apart from a few exceptions such as
NSObject and NSProxy classes, which are root classes. Root classes do not have a
superclass.
• It has to have a name that conforms to Cocoa’s naming convention for methods.
• It has to have an interface file that defines the interface of the class.
• It has to have an implementation where you implement the features that you have
promised to deliver in the interface of the class.
NSObject is the root class from which almost every other class is inherited. For this
example, we are going to add a class, named Person, to the project we created in “Cre‐
ating and Running Our First iOS App” on page 2. We are going to then add two prop‐
erties to this class, named firstName and lastName, of type NSString. Follow these
steps to create and add the Person class to your project:
1. In Xcode, while your project is open and in front of you, from the File menu, choose
New → File...
2. On the lefthand side, ensure that under the iOS main section you have chosen the
Cocoa Touch category. Once done, select the Objective-C Class item and press the
Next button.
3. In the Class section, enter Person.
4. In the “Subclass of ” section, enter NSObject.
5. Once done, press the Next button, at which point Xcode will ask where you would
like to save this file. Simply save the new class into the folder where you have placed
your project and its files. This is the default selection. Then press the Create button,
and you are done.
You now have two files added to your project: Person.h and Person.m. The former is the
interface and the latter is the implementation file for your Person class. In Objective-
C, .h files are headers, where you define the interface of each class, and .m files are
implementation files where you write the actual implementation of the class.
Now let’s go into the header file of our Person class and define two properties for the
class, of type NSString:
@interface Person : NSObject
@end
Just like a variable, definition of properties has its own format, in this particular order:
We said that properties can have various qualifiers. Here are the important qualifiers
that you need to know about:
strong
Properties of this type will be retained by the runtime. These can only be instances
of classes. In other words, you cannot retain a value into a property of type strong
if the value is a primitive. You can retain objects, but not primitives.
copy
The same as strong, but when you assign to properties of this type, the runtime
will make a copy of the object on the right side of the assignment. The object on
the righthand side of the assignment must conform to the NSCopying or NSMutable
Copying protocol.
assign
Objects or primitive values that are set as the value of a property of type assign will
not be copied or retained by that property. For primitive properties, this qualifier
will create a memory address where you can put the primitive data. For objects,
properties of this type will simply point to the object on the righthand side of the
equation.
unsafe_unretained
The same as the assign qualifier.
weak
The same as the assign qualifier with one big difference. In the case of objects,
when the object that is assigned to a property of this type is released from memory,
the runtime will automatically set the value of this property to nil.
We now have a Person class with two properties: firstName and lastName. Let’s go back
to our app delegate’s implementation (AppDelegate.m) file and instantiate an object of
type Person:
#import "AppDelegate.h"
#import "Person.h"
1.0. Introduction | 7
@implementation AppDelegate
person.firstName = @"Steve";
person.lastName = @"Jobs";
We are allocating and initializing our instance of the Person class in this example. You
may not know what that means yet, but continue to the “Adding Functionality to Classes
with Methods” on page 8 section and you will find out.
@implementation Person
- (void) walkAtKilometersPerHour:(CGFloat)paramSpeedKilometersPerHour{
/* Write the code for this method here */
}
- (void) runAt10KilometersPerHour{
/* Call the walk method in our own class and pass the value of 10 */
@end
1. A prefix to tell the compiler whether the method is an instance method (-) or a class
method (+). An instance method can be accessed only after the programmer allo‐
cates and initializes an instance of your class. A class method can be accessed by
calling it directly from the class itself. Don’t worry if this all sounds complicated.
We will see examples of these methods in this book, so don’t get hung up on this
for now.
2. A data type for the method, if the method returns any value. In our example, we
have specified void, telling the compiler that we are not returning anything.
3. The first part of the method name followed by the first parameter. You don’t nec‐
essarily have to have any parameters for a method. You can have methods that take
no parameters.
4. The list of subsequent parameters following the first parameter.
It’s important to bear in mind that every parameter in every method has an external and
an internal name. The external name is part of the method, whereas the internal part is
the actual name or alias of the parameter that can be used inside the method’s imple‐
mentation. In the previous example, the external name of the first parameter is sing‐
Song, whereas its internal name is paramSongData. The external name of the second
parameter is loudly, but its internal name is paramLoudly. The method’s name and the
external names of its parameters combine to form what is known as the selector for the
method. The selector for the aforementioned method in this case would be sing
Song:loudly:. A selector, as you will later see in this book, is the runtime identifier of
every method. No two methods inside a single class can have the same selector.
In our example, we have defined three methods for our Person class, inside its imple‐
mentation file (Person.m):
• walkAtKilometersPerHour:
• runAt10KilometersPerHour
1.0. Introduction | 9
• singSong:loudly:
If we want to be able to use any of these methods from the outside world—for instance,
from the app delegate—we should expose those methods in our interface file (Person.h):
#import <Foundation/Foundation.h>
- (void) walkAtKilometersPerHour:(CGFloat)paramSpeedKilometersPerHour;
- (void) runAt10KilometersPerHour;
@end
Given this interface file, a programmer can call the walkAtKilometersPerHour: and
the runAt10KilometersPerHour methods from outside the Person class, but not the
singSong:loudly: method because it has not been exposed in the file. So let’s go ahead
and try to call all three of these methods from our app delegate to see what happens!
- (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[person walkAtKilometersPerHour:3.0f];
[person runAt10KilometersPerHour];
Now we know how to define and call instance methods, but what about class methods?
Let’s first find out what class methods are and how they differ from instance methods.
An instance method is a method that relates to an instance of a class. For instance, in
our Person class, you can instantiate this class twice to create two distinct persons in a
hypothetical game that you are working on and have one of those persons walk at the
speed of 3 kilometers an hour while the other person walks at 2 kilometers an hour.
@implementation Person
+ (CGFloat) maximumHeightInCentimeters{
return 250.0f;
}
+ (CGFloat) minimumHeightInCentimeters{
return 40.0f;
}
@end
+ (CGFloat) maximumHeightInCentimeters;
+ (CGFloat) minimumHeightInCentimeters;
@end
We have also added a new floating point property to our Person class
named currentHeight. This allows instances of this class to be able to
store their height in memory for later reference, just like their first or
last names.
And in our app delegate, we would proceed to use these new methods like so:
1.0. Introduction | 11
- (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
1. In Xcode, while your project is open, from the File menu, select New → File...
2. In the new dialog, on the lefthand side, make sure that you’ve selected Cocoa Touch
under the iOS main category. Once done, on the righthand side of the dialog, choose
“Objective-C protocol” and then press the Next button.
3. On the next screen, under the Protocol section, enter Car as the protocol’s name
and then press the Next button.
4. You will now be asked to save your protocol on disk. Simply choose a location,
usually in your project’s folder, and press the Create button.
Xcode will now create a file for you named Car.h with content like this:
#import <Foundation/Foundation.h>
So let’s go ahead and define the properties for the Car protocol, as we discussed earlier
in this section:
#import <Foundation/Foundation.h>
@end
Now that our protocol has been defined, let’s create a class for a car, such as Jaguar, and
then make that class conform to our protocol. Simply follow the steps provided in
“Creating and Taking Advantage of Classes” on page 5 to create a class named Jaguar
and then make it conform to the Car protocol like so:
#import <Foundation/Foundation.h>
#import "Car.h"
@end
If you build your project now, you will notice that the compiler will give you a few
warnings such as this:
Auto property synthesis will not synthesize property declared in a protocol
This is simply telling you that your Jaguar class is attempting to conform to the Car
protocol but is not really implementing the required properties and/or methods in that
protocol. So you should now know that a protocol can have required or optional items,
and that you denote them by the @optional or the @required keywords. The default
qualifier is @required, and since in our Car protocol we didn’t specify the qualifier
explicitly, the compiler has chosen @required for us implicitly. Therefore, the Jaguar
class now has to implement everything that is required from it by the Car protocol, like
so:
#import <Foundation/Foundation.h>
#import "Car.h"
@end
1.0. Introduction | 13
Perfect. Now you have an understanding of the basics of protocols and how they work
and how you can define them. We will read more about them later in this book, so what
you know right now about protocols is quite sufficient.
The __unused macro tells the compiler not to complain when a vari‐
able, such as the firstString variable in our example, is declared but
never used. The default behavior of the compiler is that it throws a
warning to the console saying a variable is not used. Our brief exam‐
ple has declared the variables but not used them, so adding the afore‐
mentioned macro to the beginning of the variable declaration keeps
the compiler and ourselves happy.
A mutable array is an array that can be mutated and changed after it has been created.
An immutable array, like we saw, cannot be tampered with after it is created. Here is an
example of an immutable array:
NSString *string1 = @"String 1";
NSString *string2 = @"String 2";
NSString *string3 = @"String 3";
Another very common collection found throughout iOS programs is a dictionary. Dic‐
tionaries are like arrays, but every object in a dictionary is assigned to a key so that later
you can retrieve the same object using the key. Here is an example:
NSDictionary *personInformation =
@{
@"firstName" : @"Mark",
@"lastName" : @"Tremonti",
@"age" : @30,
@"sex" : @"Male"
};
You can also have mutable dictionaries, just as you can have mutable arrays. Mutable
dictionaries’ contents can be changed after they are instantiated. Here is an example:
NSDictionary *personInformation =
@{
@"firstName" : @"Mark",
@"lastName" : @"Tremonti",
@"age" : @30,
@"sex" : @"Male"
};
NSMutableDictionary *mutablePersonInformation =
[[NSMutableDictionary alloc] initWithDictionary:personInformation];
1.0. Introduction | 15
mutablePersonInformation[@"age"] = @32;
You can also take advantage of sets. Sets are like arrays but must contain a unique set of
objects. You cannot add the same instance of an object twice to the same set. Here is an
example:
NSSet *shoppingList = [[NSSet alloc] initWithObjects:
@"Milk",
@"Bananas",
@"Bread",
@"Milk", nil];
Note how Milk was mentioned twice in our program but added to the set only once.
That’s the magic behind sets. You can also use mutable sets like so:
NSSet *shoppingList = [[NSSet alloc] initWithObjects:
@"Milk",
@"Bananas",
@"Bread",
@"Milk", nil];
[mutableList addObject:@"Yogurt"];
[mutableList removeObject:@"Bread"];
There are two other important classes that you need to know about, now that we are
talking about sets and collections:
NSOrderedSet
An immutable set that keeps the order in which objects were added to it
NSMutableOrderedSet
The mutable version of the ordered set
By default, sets do not keep the order in which objects were added to them. Take the
following as an example:
NSSet *setOfNumbers = [NSSet setWithArray:@[@3, @4, @1, @5, @10]];
NSLog(@"Set of numbers = %@", setOfNumbers);
What gets printed to the screen after you run this program is:
Set of numbers = {(
5,
10,
3,
4,
1
)}
But that is not the order in which we created the set. If you want to keep the order intact,
simply use the NSOrderedSet class instead:
NSOrderedSet *setOfNumbers = [NSOrderedSet orderedSetWithArray
:@[@3, @4, @1, @5, @10]];
And, of course, you can use the mutable version of an ordered set:
NSMutableOrderedSet *setOfNumbers =
[NSMutableOrderedSet orderedSetWithArray:@[@3, @4, @1, @5, @10]];
[setOfNumbers removeObject:@5];
[setOfNumbers addObject:@0];
[setOfNumbers exchangeObjectAtIndex:1 withObjectAtIndex:2];
1.0. Introduction | 17
Set of numbers = {(
3,
1,
4,
10,
0
)}
Before we move off the topic of sets, there is one other handy class that you may need
to know about. The NSCountedSet class can hold a unique instance of an object multiple
times. However, the way this is done is different from the way arrays perform the same
task. In an array, the same object can appear multiple times. But in a counted set, the
object will appear only once, but the set keeps a count of how many times the object
was added to the set and will decrement that counter each time you remove an instance
of the object. Here is an example:
NSCountedSet *setOfNumbers = [NSCountedSet setWithObjects:
@10, @20, @10, @10, @30, nil];
[setOfNumbers addObject:@20];
[setOfNumbers removeObject:@10];
The NSCountedSet class is mutable, despite what its name may lead
you to think.
But with all the advances in the LLVM compiler, this code can now be shortened to this:
NSString *const kFirstNameKey = @"firstName";
NSString *const kLastNameKey = @"lastName";
NSDictionary *dictionary = @{
kFirstNameKey : @"Tim",
kLastNameKey : @"Cook",
};
You can see that we are initializing the dictionary by providing the keys in curly brackets.
The same thing for arrays. Here is how we used to create and use arrays traditionally:
NSArray *array = [[NSArray alloc] initWithObjects:@"Tim", @"Cook", nil];
__unused NSString *firstItem = [array objectAtIndex:0];
__unused NSString *secondObject = [array objectAtIndex:1];
And now with object subscripting, we can shorten this code, as follows:
NSArray *array = @[@"Tim", @"Cook"];
__unused NSString *firstItem = array[0];
__unused NSString *secondObject = array[0];
LLVM didn’t even stop there. You can add subscripting to your own classes as well.
There are two types of subscripting:
Subscripting by key
With this, you can set the value for a specific key inside an object, just like you would
in a dictionary. You can also access/read-from values inside the object by providing
the key.
Subscripting by index
As with arrays, you can set/get values inside the object by providing an index to
that object. This makes sense for array-like classes where the elements lie in a natural
order that can be represented by an index.
For the first example, we are going to look at subscripting by key. To do this, we are
going to create a class named Person with a firstName and a lastName. Then we are
going to allow the programmer to change the first and last names by simply providing
the keys to those properties.
The reason you may want to add subscripting by key to a class like this is if your property
names are volatile and you want to allow the programmer to set the value of those
1.0. Introduction | 19
properties without having to worry about whether the names of those properties will
change later; otherwise, the programmer is better off using the properties directly. The
other reason for implementing subscripting by key is if you want to hide the exact
implementation/declaration of your properties from the programmer and not let her
access them directly.
In order to support subscripting by key on your own classes, you must implement the
following two methods on your class and put the method signatures in your class’s
header file; otherwise, the compiler won’t know that your class supports subscripting
by key.
#import <Foundation/Foundation.h>
- (id) objectForKeyedSubscript:(id<NSCopying>)paramKey;
- (void) setObject:(id)paramObject forKeyedSubscript:(id<NSCopying>)paramKey;
@end
@implementation Person
- (id) objectForKeyedSubscript:(id<NSCopying>)paramKey{
return nil;
}
@end
This code will achieve exactly the same effect as the more direct approach of setting the
properties of a class:
Person *person = [Person new];
person.firstName = @"Tim";
person.lastName = @"Cook";
1.0. Introduction | 21
__unused NSString *firstName = person.firstName;
__unused NSString *lastName = person.lastName;
You can also support subscripting by index, the same way arrays do. This is useful, as
mentioned before, to allow programmers to access objects that have a natural order
inside a class. But there are not many data structures besides arrays where it makes sense
to order and number elements, unlike subscripting by key, which applies to a wide range
of data structures. So the example I’ll use to illustrate subscripting by index is a bit
contrived. In our previous example, we had the Person class with a first and last name.
Now if you want to allow programmers to be able to read the first name by providing
the index of 0 and the last name by providing the index of 1, all you have to do is declare
the objectAtIndexedSubscript: and the setObject:atIndexedSubscript: methods
in the header file of your class, and then write the implementation. Here is how we
declare these methods in our Person class’s header file:
- (id) objectAtIndexedSubscript:(NSUInteger)paramIndex;
- (void) setObject:(id)paramObject atIndexedSubscript:(NSUInteger)paramIndex;
The implementation is also quite simple. We take the index and act upon it in a way that
makes sense to our class. We decided that the first name has to have the index of 0 and
the last name the index of 1. So if we get the index of 0 for setting a value, we set the
value of the first name to the incoming object, and so on:
- (id) objectAtIndexedSubscript:(NSUInteger)paramIndex{
switch (paramIndex){
case 0:{
return self.firstName;
break;
}
case 1:{
return self.lastName;
break;
}
default:{
[NSException raise:@"Invalid index" format:nil];
}
}
return nil;
}
Now we can test out what we’ve written so far, like so:
Person *person = [Person new];
person[kFirstNameKey] = @"Tim";
person[kLastNameKey] = @"Cook";
NSString *firstNameByKey = person[kFirstNameKey];
NSString *lastNameByKey = person[kLastNameKey];
If you’ve followed all the steps in this recipe, you should see the value Success printed
to the console now.
Solution
Utilize the UIAlertView class.
Discussion
If you are an iOS user, you have most certainly already seen an alert view. Figure 1-1
depicts an example.
The best way to initialize an alert view is to use its designated initializer:
- (void) viewDidAppear:(BOOL)paramAnimated{
[super viewDidAppear:paramAnimated];
In order to display an alert view to the user, we use the alert view’s show method. Let’s
have a look at the description for each of the parameters that we passed to the initializer
of the alert view:
title
The string that the alert view will display on the top when it is shown to the user.
This string is Title in Figure 1-2.
message
The actual message that gets displayed to the user. In Figure 1-2, this message is set
to Message.
It is possible to create an alert view without any buttons. But the view
cannot be dismissed by the user. If you create such a view, you, as the
programmer, need to make sure this alert view will get dismissed au‐
tomatically; for instance, three seconds after it is displayed. An alert
view without any buttons that does not dismiss itself automatically
gives a really poor user experience. Not only will your app get low
ratings on the App Store for blocking the UI from user access, but
chances are that your app will get rejected by Apple.
Alert views can take various styles. The UIAlertView class has a property called alert
ViewStyle of type UIAlertViewStyle:
typedef NS_ENUM(NSInteger, UIAlertViewStyle) {
UIAlertViewStyleDefault = 0,
UIAlertViewStyleSecureTextInput,
UIAlertViewStylePlainTextInput,
UIAlertViewStyleLoginAndPasswordInput
};
- (NSString *) noButtonTitle{
return @"No";
}
Now we need to make sure that we are conforming to the UIAlertViewDelegate pro‐
tocol in our view controller:
#import "ViewController.h"
@end
@implementation ViewController
...
The next step is to create and display our alert view to the user:
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
So now, our alert view will look similar to that shown in Figure 1-3.
Now we need a way to know whether the user selected the Yes or the No option in our
alert view. For this, we will need to implement the alertView:clickedButtonAtIn
dex: method of our alert view delegate:
- (void) alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex{
Language: French
LE FAMEUX CHEVALIER
GASPARD DE BESSE
PARIS
ERNEST FLAMMARION, ÉDITEUR
26, RUE RACINE, 26
Collection à 5 francs.
CHAPITRE PREMIER
Dans la prison, Gaspard qui a tout le loisir de méditer sur sa vie passée et de
songer à de nouveaux projets, pressent que, dans la gorgerette d’une
chaste pucelle, il trouvera la clef des champs.
Louis XIV, en 1660, fut reçu à Toulon par le chevalier Paul, qui lui
donna une fête dans son jardin, à Dardennes.
Pour amuser les belles dames de la Cour, Paul fit suspendre, dans
ses orangers, parmi les bigarrées, d’excellentes oranges confites,
attachées aux branches par des fils menus, habilement dissimulés :
— Oh ! voyez, chère marquise, les belles oranges, extraordinaires
d’être si douces, parmi les autres si amères !
— C’est une merveille !
— Cela ne vous étonne point ?
— Un peu sans doute ; mais les fruits du dattier, dit-on, ne sont
pas moins mielleux, collants et sucrés, et se peuvent dire
naturellement confits par les soins de la nature !
On se croyait dans cette Ile des Plaisirs que M. de Fénelon devait
plus tard imaginer pour la joie de Monseigneur le Dauphin.
Un jour, le chevalier Paul rencontra, sur le quai de Toulon, un
pauvre batelier qui, à sa vue, parut vouloir se dissimuler parmi
d’autres. Paul le reconnut pour un de ses anciens camarades. Il
l’appela par son nom ; et, l’homme s’étant approché, l’amiral se
tournant vers ses officiers :
— Je vous présente un de mes anciens camarades de jeunesse et
de misère. Souffrez, messieurs, que je m’entretienne un instant avec
lui.
Il l’interrogea en particulier sur sa famille, sur ses besoins, lui
témoigna beaucoup d’amitié et lui fit accorder un bon petit emploi…
Paul mourut en 1667, laissant toute sa fortune aux pauvres, parmi
lesquels il voulut être enterré.
— Voilà un homme ! s’écriait Gaspard qui, en lisant, dans son
cachot, ce trait de la vie de Paul, versait des larmes. Nobles larmes,
comme celles que firent verser à Condé, Corneille et la clémence
d’Auguste.
Ces émotions de Gaspard, la préférence qu’il eut pour Adraman
et le chevalier Paul — la simple et touchante bonté des actions qui
leur valurent cette préférence — suffiraient à nous révéler la qualité
de son grand cœur populaire ; et à nous faire comprendre pourquoi
le peuple de Provence a fait de Gaspard un de ses favoris.
Gaspard, aidé par les circonstances, aurait pu avoir une destinée
égale à celle des héros dont il admirait la fortune, dont il aimait
surtout la bienveillance envers les existences des plus humbles.
Comme le bandit Mandrin, qui fut un vrai capitaine, Gaspard, sur
un champ d’action plus vaste, eût sans doute acquis une renommée
universelle ; et, dans le rang des réguliers, il eût conquis l’admiration
du monde, grâce à des qualités heureuses qui ne furent pas toujours
celles des chefs de peuples. Avant tout, il aimait, autant que la
justice, la bonté. Et voilà déjà qui n’est pas commun. Son curé lui
avait appris à faire son examen de conscience ; il le fit dans la
solitude du cachot.
Il regrettait de s’être fait bandit. L’idée du juste mépris où l’on
tient les voleurs lui était difficile à supporter. Cependant, si sa
condition de chef de bande le mettait un jour à même de faire
comprendre aux puissants que le peuple exigeait la réforme de la
juridiction pénale, n’y avait-il pas quelque chose de respectable dans
sa condition ? C’est du moins ce qu’il se disait. Les vols à main armée
opérés courtoisement, sans violence inutile, n’étaient à ses yeux
qu’un impôt prélevé par lui pour l’entretien de sa troupe, à laquelle il
ne permettait aucun pillage. Des tributs volontaires rendaient les
vols de jour en jour moins nombreux. On vivait, on ne thésaurisait
pas. Il poursuivait un but hautement politique : il voulait humilier le
parlement, le ridiculiser, le dénoncer à tous les yeux comme une
institution qu’il fallait ou changer ou rendre à elle-même, c’est-à-dire
aux principes dont elle se prétendait issue et que pourtant elle
paraissait mettre souvent en oubli.
Le Parlement avait étouffé l’affaire de l’assassinat de Teisseire
parce que les coupables étaient des puissants selon l’expression du
bon La Fontaine ; et Gaspard voulait que les coupables fussent
atteints ; que la mort du père de Bernard fût expiée ; et que, dans le
châtiment des coupables, les paysans, les petits, vissent le signe de
la protection des lois étendue sur eux. Le but qu’il se donnait lui
avait paru jusqu’alors une satisfaisante excuse à ses actes de
rebelle ; toutefois il les sentait en contradiction permanente avec
l’idée d’obéissance aux lois, qu’il eût voulu servir, et de cela il
souffrait étrangement. Mais, s’il souffrait ainsi, est-ce que ce
tourment ne donnait pas à sa mission un goût de sacrifice qui la
rendait honorable, ne fût-ce qu’à ses propres yeux ? En tous cas, il
ne pouvait plus rien changer aux contradictions dont il gémissait : il
s’était engagé dans une voie où, à sa suite, il avait engagé d’autres
existences ; il se devait à elles ; il poursuivrait sa tâche. Toutefois, et
cela était nouveau en lui, il se répétait souvent : « Il est malheureux
que, pour servir mon désir de justice, j’aie cru pouvoir m’entourer de
coquins ! » L’état d’humiliation où il se voyait réduit, les chaînes qui
l’attachaient aux murs de son cachot, éveillaient en lui ces poignants
regrets. Il se sentait sous le coup de la réprobation publique ! Il
combattait ce regret en se répétant qu’un grand bien sortirait peut-
être de sa révolte condamnable. Et, tout d’abord, n’allait-il pas
donner une vie heureuse à Bernard, son frère d’adoption, en lui
faisant épouser la fille de l’usurier Cabasse, cet ancien valet de
fermier général, qui avait dépouillé tant de pauvres gens, et par qui
il avait été dépouillé lui-même de son patrimoine ?
A l’idée du bonheur qu’il préparait à Bernard et à la pupille de
Cabasse, malgré toutes les résistances du tuteur usurier, Gaspard
s’attendrissait.
Le bonheur d’amour, dans la paix, selon la loi et selon Dieu,
l’amour dans le devoir, une famille laborieuse et respectée, — c’est
ce que lui, Gaspard, n’aurait jamais ! — Donner ce bonheur à deux
jeunes êtres qui en étaient dignes, n’était-ce pas une bonne œuvre
qui lui serait comptée comme une touchante excuse aux exactions
qu’il était en train d’expier ? Il ne parvenait pas à en être sûr et à
s’absoudre pleinement… Ainsi la solitude de la prison lui montrait les
choses sous un jour nouveau, formait en lui comme une conscience
neuve.
Assis dans l’étroite cellule, les poignets pris dans des bracelets de
fer, attaché aux murs comme un chien à sa niche, Gaspard rêvait. Le
chien enchaîné, lui du moins, voit, du seuil de sa cabane, la lumière
du jour. Gaspard n’avait que la clarté de son calèn fumeux et qui
s’éteignait souvent faute d’huile ; il fallait alors attendre le bon plaisir
du geôlier Castagne. Un grillage épais, au-dessus de la porte, barrait
la mince ouverture rectangulaire par où lui arrivait un peu de la
lumière naturelle. Et cela s’appelait un jour de souffrance.
Dans cette ombre, Gaspard rêvait aussi d’amour ; et c’est là que,
pour la première fois, il se prit à reconnaître que l’image de Mme de
Lizerolles était en lui comme vivante et attirante.
Quoi ! osait-il espérer d’elle autre chose qu’une pitié hautaine ? Il
ne savait pas. Profiterait-il de l’ignorance où elle était de son nom ? Il
se refusait à cette pensée comme au plus criminel des abus de
confiance.
Or, Gaspard avait un secret d’amour, enfoui profondément dans
son cœur. A Aix, il avait trompé, séduit, sous un nom d’emprunt, une
douce et humble petite bourgeoise, misé Brun, la femme d’un
modeste horloger. Celle-là n’avait-elle pas pour lui oublié tous ses
devoirs ? Quelle honte, quelle douleur pour elle, le jour où elle
apprendrait que son amant n’était autre que Gaspard de Besse, un
chef de voleurs !
… Ainsi, il aimait assez Mme de Lizerolles pour vouloir lui
épargner une souffrance que, bien malgré lui, mais fatalement, il
infligerait tôt ou tard à misé Brun. Et la noblesse de son amour pour
la comtesse lui reprocha la bassesse de son acte vis-à-vis de la
plébéienne, en sorte qu’il prit, dans sa prison, la résolution de ne
plus revoir misé Brun. Elle pleurerait un infidèle, mais ignorerait à
jamais — il l’espérait du moins — la qualité de son déplorable
séducteur. Il éprouva un grand bien-être à s’affermir dans cette
résolution ; il se sentit un peu réconcilié avec lui-même, et, d’ailleurs,
libéré en même temps, d’une dangereuse intrigue.
Y avait-il d’autres figures de femmes dans ses souvenirs ? Sans
doute ; mais toutes comme voilées et lointaines. Il était si
« agradant », si plaisant, que, pour s’expliquer ses qualités de
séducteur, les paysans de Besse (et il ne l’ignorait pas) prétendaient
qu’il était un enfant de l’amour. Il était fils, disait-on, du marquis de
X… qui avait séduit sa mère misé Bouis. Facilement ému par la grâce
féminine, il se reconnut troublé par la fille de son geôlier, Louisette,
qui, parfois, remplaçant son père, lui apportait l’eau et le pain.
Quand c’était Louisette qui ouvrait la porte du cachot, un rayon du
joyeux soleil entrait avec elle ; et, elle aussi, était lumière et joie…
Essaierait-il de troubler le cœur de cette fillette pour obtenir d’elle la
liberté ? Il souriait malgré lui à cette idée. On racontait dans le
peuple que la fille d’un geôlier séduite par M. de Mirabeau, enfermé
au château d’If, avait favorisé l’évasion du gentilhomme. Donc, il
imiterait M. de Mirabeau…; mais, là encore, Mme de Lizerolles
intervenait, apparaissait à Gaspard avec un visage sévère : « Vous
laisserez en repos cette fille »…
Comment ! n’était-il donc plus libre de cœur et d’esprit ? Tout
caprice galant lui était-il interdit par une ombre ? Pauvre Louisette !
qu’arriverait-il de cette enfant ?… Mais, quoi ! ne pourrait-elle le
servir sans en être si mal récompensée ? Serait-elle la première qui
l’aurait ému de désir sans être mise à mal ?
Cette question réveilla en lui le souvenir d’une gentille aventure
qui lui était arrivée naguère. Il en revit les moindres détails. Elle
l’égaya tout un jour dans sa misérable geôle…