You are on page 1of 106

Basic Sensors in iOS

Basic Sensors in iOS


$ODVGDLU$OODQ
Beijing Cambridge Farnham Kln Sebastopol Tokyo
Basic Sensors in iOS
Ly Alasuaii Allan
Copyiight 2011 Alasuaii Allan. All iights ieseiveu.
Piinteu in the Uniteu States ol Ameiica.
PuLlisheu Ly O`Reilly Meuia, Inc., 1005 Giavenstein Highway Noith, SeLastopol, CA 95+72.
O`Reilly Looks may Le puichaseu loi euucational, Lusiness, oi sales piomotional use. Online euitions
aie also availaLle loi most titles (http://ny.sajariboo|son|inc.con). Foi moie inloimation, contact oui
coipoiate/institutional sales uepaitment: (S00) 99S-993S oi corporatcorci||y.con.
Editor: Biian ]epson
Proofreader: O`Reilly Piouuction Seivices
Cover Designer: Kaien Montgomeiy
Interior Designer: Daviu Futato
Illustrator: RoLeit Romano
Printing History:
]uly 2011: Fiist Euition.
Nutshell HanuLook, the Nutshell HanuLook logo, anu the O`Reilly logo aie iegisteieu tiauemaiks ol
O`Reilly Meuia, Inc. Basic Scnsors in iOS, the image ol a Malay lox-Lat, anu ielateu tiaue uiess aie
tiauemaiks ol O`Reilly Meuia, Inc.
Many ol the uesignations useu Ly manulactuieis anu selleis to uistinguish theii piouucts aie claimeu as
tiauemaiks. Vheie those uesignations appeai in this Look, anu O`Reilly Meuia, Inc. was awaie ol a
tiauemaik claim, the uesignations have Leen piinteu in caps oi initial caps.
Vhile eveiy piecaution has Leen taken in the piepaiation ol this Look, the puLlishei anu authoi assume
no iesponsiLility loi eiiois oi omissions, oi loi uamages iesulting liom the use ol the inloimation con-
taineu heiein.
ISBN: 97S-1-++9-30S+6-9
LSI
1311179730
Table of Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii
1. The Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
AvailaLle Sensoi Haiuwaie 1
Dilleiences Between iPhone anu iPau 2
Device Oiientation anu the iPau +
Detecting Haiuwaie Dilleiences +
Cameia AvailaLility 5
Auuio Input AvailaLility 5
GPS AvailaLility 6
Magnetometei AvailaLility 6
Setting Reguiieu Haiuwaie CapaLilities 6
Peisistent ViFi 7
Backgiounu Moues 7
2. Using the Camera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
The Haiuwaie 9
Captuiing Stills anu Viueo 10
Viueo ThumLnails 1S
Viueo ThumLnails Using the UIImagePickei 1S
Viueo ThumLnails Using AVFounuation 19
Saving Meuia to the Photo AlLum 20
Viueo Customization 23
3. Using Audio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
The Haiuwaie 25
Meuia PlayLack 26
Recoiuing anu Playing Auuio 31
Recoiuing Auuio 32
Playing Auuio 35
v
4. Using the Accelerometer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
ALout the Acceleiometei 37
Viiting an Acceleiometei Application 3S
Deteimining Device Oiientation +3
Deteimining Device Oiientation Diiectly Using the Acceleiometei +6
OLtaining Notilications when Device Oiientation Changes +S
Vhich Vay Is Up? +9
Convenience Methous loi Oiientation 52
Detecting Shaking 53
5. Using the Magnetometer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
ALout the Magnetometei 57
Viiting a Magnetometei Application 59
Deteimining the Heauing in Lanuscape Moue 62
Measuiing a Magnetic Fielu 6S
6. Using Core Motion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Coie Motion 71
Pulling Motion Data 72
Pushing Motion Data 73
Accessing the Gyioscope 75
Measuiing Device Motion 79
Compaiing Device Motion with the Acceleiometei S3
7. Going Further . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
The iPhone SDK S7
Geolocation anu Maps S7
Thiiu-Paity SDKs S7
Speech Recognition SS
Computei Vision SS
Augmenteu Reality SS
Exteinal Accessoiies SS
vi | Table of Contents
Preface
Ovei the last lew yeais the new geneiation ol smait phones, such as Apple`s iPhone,
has linally staiteu to live up to theii name anu have Lecome the piimaiy inteilace uevice
loi geogiaphically taggeu uata. Howevei not only uo these uevices know wheie they
aie, they can tell you how they`ie Leing helu, they aie sulliciently poweilul to oveilay
uata layeis on the cameia view, anu iecoiu anu inteipiet auuio uata, anu they can uo
all this in ieal time. These aie not just smait phones, these aie computeis that just
happen to Le aLle to make phone calls.
This Look shoulu pioviue a soliu intiouuction to using the haiuwaie leatuies in the
iPhone, iPou touch, anu iPau.
Who Should Read This Book?
This Look pioviues an intiouuction to the hot topic ol location-enaLleu sensois on the
iPhone. Il you aie a piogiammei who has hau some expeiience with the iPhone Leloie,
this Look will help you push youi knowleuge luithei. Il you aie an expeiienceu Mac
piogiammei, alieauy lamiliai with OLjective-C as a language, this Look will give you
an intiouuction to the haiuwaie specilic paits ol iPhone piogiamming.
What You Should Already Know?
The Look assumes some pievious expeiience with the OLjective-C language. Auui-
tionally some lamiliaiity with the iPhone platloim woulu Le helplul. Il you`ie new to
the iPhone platloim you may Le inteiesteu in Lcarning iPhonc Progranning, also Ly
Alasuaii Allan (O`Reilly).
What Will You Learn?
This Look will guiue you thiough guiue you thiough ueveloping applications loi the
iPhone platloim that make use ol the onLoaiu sensois: the thiee-axis acceleiometei,
vii
the magnetometei (uigital compass), the gyioscope, the cameia anu the gloLal posi-
tioning system
Whats In This Book?
Chaptei 1, Thc Hardwarc
This chaptei summaiizes the availaLle sensois on the iPhone anu iPau platloims
anu how they have, oi coulu Le, useu in applications. It talks aLout the uilleiences
Letween the haiuwaie platloims.
Chaptei 2, Using thc Cancra
Valkthiough ol how to use the iPhone`s cameia loi still anu viueo. How to cieate
viueo thumLnails anu customise viueo.
Chaptei 3, Using Audio
Valkthiough ol how to playLack iPou meuia, as well as how to play anu iecoiu
auuio on youi uevice.
Chaptei +, Using thc Accc|cronctcr
Valkthiough ol how to use the acceleiometei, uiscussion ol what is implieu with
iespect to the oiientation ol the uevice Ly the iaw ieauings.
Chaptei 5, Using thc Magnctonctcr
Valkthiough ol how to use the magnetometei, uiscussion ol comLining the mag-
netometei anu acceleiometei to get the yaw, pitch anu ioll ol the uevice.
Chaptei 6, Using Corc Motion
This paiagiaph uiscusses the new Coie Motion liamewoik; this new liamewoik
allows youi application to ieceive motion uata liom Loth the acceleiometei anu
(on the latest geneiation ol uevices) the gyioscope.
Chaptei 7, Going Iurthcr
Pioviues a collection ol pointeis to moie auvanceu mateiial on the topics we cov-
eieu in the Look, anu mateiial coveiing some ol those topics that we uiun`t manage
to talk aLout in this Look.
Conventions Used in This Book
The lollowing typogiaphical conventions aie useu in this Look:
|ta|ic
Inuicates new teims, URLs, email auuiesses, lilenames, anu lile extensions.
Constant width
Useu loi piogiam listings, as well as within paiagiaphs to ielei to piogiam elements
such as vaiiaLle oi lunction names, uataLases, uata types, enviionment vaiiaLles,
statements, anu keywoius.
viii | Preface
Constant width bold
Shows commanus oi othei text that shoulu Le typeu liteially Ly the usei.
Constant width italic
Shows text that shoulu Le ieplaceu with usei-supplieu values oi Ly values uetei-
mineu Ly context.
This icon signilies a tip, suggestion, oi geneial note.
This icon signilies a waining oi caution.
Using Code Examples
This Look is heie to help you get youi joL uone. In geneial, you may use the coue in
this Look in youi piogiams anu uocumentation. You uo not neeu to contact us loi
peimission unless you`ie iepiouucing a signilicant poition ol the coue. Foi example,
wiiting a piogiam that uses seveial chunks ol coue liom this Look uoes not ieguiie
peimission. Selling oi uistiiLuting a CD-ROM ol examples liom O`Reilly Looks uoes
ieguiie peimission. Answeiing a guestion Ly citing this Look anu guoting example
coue uoes not ieguiie peimission. Incoipoiating a signilicant amount ol example coue
liom this Look into youi piouuct`s uocumentation uoes ieguiie peimission.
Ve appieciate, Lut uo not ieguiie, attiiLution. An attiiLution usually incluues the title,
authoi, puLlishei, anu ISBN. Foi example: Basic Scnsors in iOS, Ly Alasuaii Allan.
Copyiight 2011 O`Reilly Meuia, Inc., 97S-1-++93-0S+6-9.
Il you leel youi use ol coue examples lalls outsiue laii use oi the peimission given heie,
leel liee to contact us at pcrnissionsorci||y.con.
A lot ol the examples won`t woik completely in the simulatoi, so you`ll
neeu to ueploy them to youi uevice to test the coue.
Safari Books Online
Salaii Books Online is an on-uemanu uigital liLiaiy that lets you easily
seaich ovei 7,500 technology anu cieative ieleience Looks anu viueos to
linu the answeis you neeu guickly.
Vith a suLsciiption, you can ieau any page anu watch any viueo liom oui liLiaiy online.
Reau Looks on youi cell phone anu moLile uevices. Access new titles Leloie they aie
Preface | ix
availaLle loi piint, anu get exclusive access to manusciipts in uevelopment anu post
leeuLack loi the authois. Copy anu paste coue samples, oiganize youi lavoiites, uown-
loau chapteis, Lookmaik key sections, cieate notes, piint out pages, anu Lenelit liom
tons ol othei time-saving leatuies.
O`Reilly Meuia has uploaueu this Look to the Salaii Books Online seivice. To have lull
uigital access to this Look anu otheis on similai topics liom O`Reilly anu othei puL-
lisheis, sign up loi liee at http://ny.sajariboo|son|inc.con.
How to Contact Us
Please auuiess comments anu guestions conceining this Look to the puLlishei:
O`Reilly Meuia, Inc.
1005 Giavenstein Highway Noith
SeLastopol, CA 95+72
S00-99S-993S (in the Uniteu States oi Canaua)
707-S29-0515 (inteinational oi local)
707-S29-010+ (lax)
Ve have a weL page loi this Look, wheie we list eiiata, examples, anu any auuitional
inloimation. You can access this page at:
http://www.orci||y.con/cata|og/978111930819
Supplementaiy mateiials aie also availaLle at:
http://www.progranningiphoncscnsors.con
To comment oi ask technical guestions aLout this Look, senu email to:
boo|qucstionsorci||y.con
Foi moie inloimation aLout oui Looks, couises, conleiences, anu news, see oui weLsite
at http://www.orci||y.con.
Finu us on FaceLook: http://jaccboo|.con/orci||y
Follow us on Twittei: http://twittcr.con/orci||yncdia
Vatch us on YouTuLe: http://www.youtubc.con/orci||yncdia
Acknowledgments
Eveiyone has one Look in them. This is my seconu, oi uepenuing how you want to
look at it, my Platloim 9', since this Look, along with the othei thiee loithcoming
shoit Looks on iOS anu sensoi technology, will loim the Lulk ol Progranning iOS1
Scnsors, which woulu pioLaLly Le classeu Ly most as my seconu ieal Look loi O`Reilly.
x | Preface
At which point, I`u like to thank my euitoi at O`Reilly, Biian ]epson, loi holuing my
hanu just one moie time. As evei his haiu woik maue my haiu woik much Lettei than
it otheiwise woulu have Leen. I also veiy much want to thank my wile Gemma HoLson
loi hei continueu suppoit anu encouiagement. Those small, anu sometimes laigei,
saciilices an authoi`s spouse ioutinely has to make uon`t get any less inconvenient the
seconu time aiounu. I`m not suie why she let me wiite anothei, peihaps Lecause I
claimeu to enjoy wiiting the liist one so much. Thank you Gemma. Finally to my son
Alex, still too young to ieau what his uauuy has wiitten, hopelully this volume will
keep you in Looks to chew on just a little longei.
Preface | xi
CHAPTER 1
The Hardware
The aiiival ol the iPhone changeu the whole uiiection ol soltwaie uevelopment loi
moLile platloims, anu has hau a piolounu impact on the haiuwaie uesign ol the smait
phones that have lolloweu it. The aiiival ol the iPau has tuineu what was a single class
ol uevice into a platloim.
Available Sensor Hardware
Vhile the iPhone is almost unigue amongst moLile platloims in guaianteeing that youi
application will iun on all ol the cuiient uevices (see Figuie 1-1), howevei theie is an
incieasing amount ol vaiiation in availaLle haiuwaie Letween the vaiious mouels, as
shown in TaLle 1-1.
Iigurc 1-1. Tinc|inc showing thc avai|abi|ity oj iPhonc, iPod Touch, iPad nodc|s
1
Tab|c 1-1. Hardwarc support in various iPhonc, iPod touch, and iPad
Hardware Feature
iPhone iPod touch iPad iPad 2
O
r
i
g
i
n
a
l
3
G
3
G
S
4 1
s
t

G
e
n
2
n
d

G
e
n
3
r
d

G
e
n
4
t
h

G
e
n
W
i
F
i
3
G
W
i
F
i
3
G
Cellular
WiFi
Bluetooth
Speaker
Audio In
Accelerometer
Magnetometer
Gyroscope
GPS
Proximity Sensor
Camera
Video
Vibration
Most ol the examples in this Look will Le Luilt as iPhone howevei uepenuing on the
availaLility ol haiuwaie the examples will iun egually well on the iPou touch anu iPau;
the unueilying coue is egually applicaLle as we`ie uealing loi the most pait uiiectly
with that haiuwaie.
Differences Between iPhone and iPad
The most stiiking, anu oLvious, uilleience Letween the iPhone anu the iPau is scieen
size. The oiiginal iPhone scieen has +S0320 pixel iesolution at 163 pixels pei inch.
The iPhone + anu +th geneiation iPou touch Retina Displays have a iesolution ol
9606+0 pixel at 326 pixels pei inch. Meanwhile Loth geneiations ol the iPau scieen
have 102+76S pixel iesolution at 132 pixels pei inch. This uilleience will Le the single
most lunuamental thing to allect the way you uesign youi usei inteilace on the two
platloims. Attempting to tieat the iPau as simply a iathei oveisizeu iPou touch oi
iPhone will leau to Lauly uesigneu applications. The metaphois you use on the two
uilleient platloims
The incieaseu scieen size ol the uevice means that you can uevelop uesktop-sizeu ap-
plications, not just phone-sizeu applications, loi the iPau platloim. Although in uoing
so, a iethink ol the usei inteilace to auapt to multi-touch is neeueu. Vhat woiks loi
the iPhone oi the uesktop, won`t automatically woik on an iPau. Foi example, Apple
2 | Chapter 1:The Hardware
totally ieuesigneu the usei inteilace ol the iVoik suite when they moveu it to the iPau.
Il you`ie intenuing to poit a Mac OS X uesktop application to the iPau you shoulu uo
something similai.
Inteiestingly theie is now an option loi iOS uevelopeis to poit theii
iPhone anu iPau piojects uiiectly to Mac OS X. The Chameleon Pioject
http://chanc|conprojcct.org is a uiop in ieplacement loi UIKit that iuns
on Mac OS X, allowing iOS applications to Le iun on the uesktop with
little mouilication, in some cases none.
Due to its size anu lunction the iPau is immeuiately associateu in oui minus with othei
moie lamiliai oLjects like a legal pau oi a Look. Holuing the uevice tiiggeis poweilul
associations with these items, anu we`ie mentally willing to accept the iPau has a suc-
cessoi to these oLjects. This is simply not tiue loi the iPhone; the uevice is physically
too small.
The Human Interface Guidelines
Apple has Lecome almost inlamous loi stiict auheience to its Human Inteilace Guiue-
lines. Designeu to piesent useis with a consistent visual anu Lehavioial expeiience
acioss applications anu the opeiating system the inteilace guiuelines mean that (most)
applications iunning on the Mac OS X uesktop have a consistent look anu leel. Vith
the aiiival ol the iPhone anu the iPau, Apple hau to uiaw up new sets ol guiuelines loi
theii moLile platloims, iauically uilleient liom the tiauitional uesktop.
Even loi uevelopeis who aie skeptical aLout whethei they ieally neeueu to stiictly au-
heie to the guiuelines (especially when Apple peiiouically steps outsiue them) the
Human Inteilace Guiuelines have iemaineu a Lenchmaik against which the usei ex-
peiience can Le measuieu.
Copies ol the Human Inteilace Guiuelines loi Loth the iPhone anu the iPau aie availaLle
loi uownloau liom the App Stoie Resouice Centei.
I woulu iecommenu that you ieau the moLile Human Inteilace Guiuelines caielully, il
only Lecause violating them coulu leau to youi application Leing iejecteu Ly the ieview
team uuiing the App Stoie appioval piocess.
Howevei this Look is not aLout how to uesign youi usei inteilace oi manage youi usei
expeiience. Foi the most pait the examples I piesent in this Look aie simple view-Laseu
applications that coulu Le egually wiitten loi the iPhone anu iPou touch oi the iPau.
The usei inteilace is only theie to illustiate how to use the unueilying haiuwaie. This
Look is aLout how to use the collection ol sensois in these moLile uevices.
Differences Between iPhone and iPad | 3
Device Orientation and the iPad
The sliuei Lutton on the siue ol the iPau can, optionally, Le useu to lock the uevice`s
oiientation. This means that il you want the scieen to stay in poitiait moue, it won`t
move when you tuin it siueways il lockeu. Howevei uespite the piesence ol the iotation
lock (anu unlike the iPhone wheie many applications only suppoiteu Poitiait moue)
an iPau application is expecteu to suppoit all oiientations egually.
Apple has this to say aLout iPau applications: An application`s intei-
lace shoulu suppoit all lanuscape anu poitiait oiientations. This Le-
havioi uilleis slightly liom the iPhone, wheie iunning in Loth poitiait
anu lanuscape moues is not ieguiieu.
To implement Lasic suppoit loi all inteilace oiientations, you shoulu implement the
shouldAutorotateToInterfaceOrientation: methou in all ol youi application`s view
contiolleis, ietuining YES loi all oiientations. Auuitionally, you shoulu conliguie the
auto-iesizing maik piopeity ol youi views insiue Inteilace Builuei so that they coiiectly
iesponu to layout changes (i.e. iotation ol the uevice).
Going beyond basic support
Il you want to go Leyonu Lasic suppoit loi alteinative oiientations theie is moie woik
involveu. Fiistly loi custom views, wheie the placement ol suLviews is ciitical to the
UI anu neeu to Le piecisely locateu, you shoulu oveiiiue the layoutSubviews methou
to auu youi custom layout coue. Howevei, you shoulu oveiiiue this methou only il the
autoiesizing Lehaviois ol the suLviews aie not what you uesiie.
Vhen an oiientation event occuis, the UIWindow class will woik with the liont-most
UIViewController to aujust the cuiient view. Theieloie il you neeu to peiloim tasks
Leloie, uuiing, oi altei completing uevice iotation you shoulu use the ielevant iotation
UIViewController notilication methous. Specilically the view contiollei`s willRotate
ToInterfaceOrientation:duration:, willAnimateRotationToInterfaceOrienta
tion:duration:, anu didRotateFromInterfaceOrientation: methous aie calleu at iele-
vant points uuiing iotation allowing you to peiloim tasks ielevant to the oiientation
change in piogiess. Foi instance you might make use ol these callLacks to allow you
to auu oi iemove specilic views anu ieloau youi uata in those views.
Detecting Hardware Differences
Because youi application will likely suppoit multiple uevices, you`ll neeu to wiite coue
to check which leatuies aie suppoiteu anu aujust youi application`s Lehavioi as
appiopiiate.
4 | Chapter 1:The Hardware
Camera Availability
Ve covei the cameia in uetail in Chaptei 2, howevei it is simple mattei to ueteimine
whethei a cameia is piesent in the uevice:
BOOL available = [UIImagePickerController
isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
Once you have ueteimineu that a cameia is piesent you can enguiie whethei it suppoits
viueo Ly making a call to ueteimine the availaLle meuia types the cameia suppoits:
NSArray *media = [UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypeCamera];
Il the kUTTypeMovie meuia type is ietuineu as pait ol the aiiay, then the cameia will
suppoit viueo iecoiuing:
if ( [media containsObject:(NSString *)kUTTypeMovie ] ){
NSLog(@"Camera supports movie capture.");
}
Audio Input Availability
An initial poll ol whethei auuio input is availaLle can Le uone using the AVAudioSes
sion class Ly checking the inputIsAvailable class piopeity:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
BOOL audioAvailable = audioSession.inputIsAvailable;
You will neeu to auu the A\Ioundation.Irancwor| (iight-click/Con-
tiol-click on the Fiamewoiks loluei in Xcoue, then choose
AuuExisting Fiamewoiks). You`ll also neeu to impoit the heauei (put
this in youi ueclaiation il you plan to implement the AVAudioSessionDe
legate piotocol uiscusseu latei):
#import <AVFoundation/AVFoundation.h>
You can also Le notilieu ol any changes in the availaLility ol auuio input, e.g., il a seconu
geneiation iPou touch usei has pluggeu in heauphones with miciophone capaLilities.
Fiist, nominate youi class as a uelegate:
audioSession.delegate = self;
Anu then ueclaie it as implementing the AVAudioSessionDelegate piotocol in the
ueclaiation:
@interface YourAppDelegate : NSObject <UIApplicationDelegate,
AVAudioSessionDelegate >
Then implement the inputIsAvailableChanged: in the implementation:
Detecting Hardware Differences | 5
- (void)inputIsAvailableChanged:(BOOL)audioAvailable {
NSLog(@"Audio availability has changed");
}
GPS Availability
The shoit answei to a commonly askeu guestion is that the Coie Location liamewoik
uoes not pioviue any way to get uiiect inloimation aLout the availaLility ol specilic
haiuwaie such as the GPS at application iun time, although you can check whethei
location seivices aie enaLleu:
BOOL locationAvailable = [CLLocationManager locationServicesEnabled];
Howevei, you can ieguiie the piesence ol GPS haiuwaie loi youi application to loau
(see Setting Reguiieu Haiuwaie CapaLilities).
Magnetometer Availability
Foitunately Coie Location uoes allow you to check loi the piesence ol the magneto-
metei (uigital compass) laiily simply:
BOOL magnetometerAvailable = [[CLLocationManager headingAvailable];
Setting Required Hardware Capabilities
Il youi application ieguiies specilic haiuwaie leatuies in oiuei to iun you can auu a
list ol ieguiieu capaLilities to youi application`s |njo.p|ist lile. Youi application will not
stait unless those capaLilities aie piesent on the uevice.
To uo this, open the pioject anu click on the application`s |njo.p|ist lile to open it in
the Xcoue euitoi. Click on the Lottommost entiy in the list. A plus Lutton will appeai
to the iight-hanu siue ol the key-value paii taLle.
Click on this Lutton to auu a new iow to the taLle, anu scioll uown the list ol possiLle
options anu select Reguiieu uevice capaLilities (the UIRequiredDeviceCapabilities
key). This will auu an (empty) aiiay to the p|ist lile.
The alloweu values loi the keys aie:
telephony
wifi
sms
still-camera
auto-focus-camera
front-facing-camera
camera-flash
6 | Chapter 1:The Hardware
video-camera
accelerometer
gyroscope
location-services
gps
magnetometer
gamekit
microphone
opengles-1
opengles-2
armv6
armv7
peer-peer
A lull uesciiption ol the possiLle keys is given in the Device Suppoit section ol the
iPhone Application Piogiamming Guiue availaLle liom the iPhone Development
Centei.
Persistent WiFi
Il youi application ieguiies a peisistent ViFi connection you can set the Boolean
UIRequiresPersistentWiFi key in the Application`s |njo.p|ist lile to ensuie that ViFi is
availaLle. Il set to YES the opeiating system will open a ViFi connection when youi
application is launcheu anu keep it open while the application is iunning. Il this key is
not piesent, oi is set to NO, the Opeiating System will close the active ViFi connection
altei 30 minutes.
Background Modes
Setting the UIBackgroundModes key in the Application`s |njo.p|ist lile notilies the opei-
ating systems that the application shoulu continue to iun in the Lackgiounu, altei the
usei closes it, since it pioviues specilic Lackgiounu seivices.
Apple has this to say aLout Lackgiounu moues, These keys shoulu Le
useu spaiingly anu only Ly applications pioviuing the inuicateu seivices.
Vheie alteinatives loi iunning in the Lackgiounu exist, those alteina-
tives shoulu Le useu insteau. Foi example, applications can use the sig-
nilicant location change inteilace to ieceive location events insteau ol
iegisteiing as a Lackgiounu location application.
Setting Required Hardware Capabilities | 7
Theie aie thiee possiLle key values: audio, location, anu voip. The audio key inuicates
that altei closing the application will continue to play auuiLle content. The location
key inuicates that the application pioviues location-Laseu inloimation loi the usei us-
ing the stanuaiu Coie Location seivices, iathei than the newei signilicant location
change seivice. Finally, the voip key inuicates that the application pioviues Voice-ovei-
IP seivices. Applications maikeu with this key aie automatically launcheu altei system
Loot so that the application can attempt to ie-estaLlish VoIP seivices.
8 | Chapter 1:The Hardware
CHAPTER 2
Using the Camera
Phones with cameias only staiteu appeaiing on the maiket in late 2001; now they`ie
eveiywheie. By the enu ol 2003 moie cameia phones weie solu woiluwiue than stanu-
alone uigital cameias, anu Ly 2006 hall ol the woilu`s moLile phones hau a Luilt-in
cameia.
The social impact ol this phenomenon shoulu not Le unueiestimateu; the uLiguity ol
these uevices has hau a piolounu allect on society anu on the way that news anu in-
loimation piopagate. MoLile phones aie constantly caiiieu, which means theii cameia
is always availaLle. This constant availaLility has leu to some innovative thiiu paity
applications, especially with the new geneiation ol smait phones. The iPhone has Leen
uesigneu with always-on connectivity in minu.
The Hardware
Until iecently, only the iPhone has leatuieu a cameia in all ol the availaLle mouels.
Howevei the latest geneiation ol Loth the iPou touch anu iPau now also have cameias.
The oiiginal iPhone anu iPhone 3G leatuie a lixeu-locus 2.0-megapixel cameia, while
the iPhone 3GS leatuies a 3.2-megapixel cameia with auto-locus, auto-white Lalance
anu auto-macio locus (up to 10cm). The iPhone 3GS cameia is also aLle ol captuiing
6+0+S0 pixel viueo at 30 liames pei seconu. Although the eailiei mouels aie physically
capaLle ol captuiing viueo, they aie limiteu in soltwaie anu this leatuie is not availaLle
at the usei level. The latest iPhone + leatuies a 5-megapixel cameia with Lettei low-
light sensitivity anu Lacksiue illuminateu sensoi. The cameia has an LED llash anu is
capaLle ol captuiing 720p HD viueo at 30 liames pei seconu. The iPhone + also has a
lowei-iesolution liont-lacing cameia, which is capaLle ol captuiing 360p HD viueo at
30 liames pei seconu.
9
The iPhone 3GS anu iPhone + cameias aie known to sullei liom ro||ing
shuttcr cjjcct when useu to take viueo. This ellect is a loim ol aliasing
that may iesult in uistoition ol last moving oLjects, oi image ellects uue
to lighting levels that change as a liame is captuieu. At the time ol wiit-
ing it`s not cleai whethei the +th geneiation iPou touch anu iPau 2 cam-
eias sullei the same pioLlem.
The latest geneiation ol iPou touch anu iPau also have Loth ieai- anu liont-lacing
cameias, Loth ol which aie lai lowei iesolution than the cameia litteu to the iPhone +,
see TaLle 2-1 loi uetails. You`ll notice the uilleience in sizes Letween still anu viueo
images on the iPou touch anu the iPau 2. It`s uncleai whethei Apple is using a 12S0720
sensoi anu ciopping oll the lelt anu iight siues ol the viueo image loi still images, oi
whethei it is using a 960720 sensoi anu up-scaling it on the siues loi viueo. The latei
woulu Le an unusual appioach loi Apple, Lut is not inconceivaLle.
Tab|c 2-1. Cancra hardwarc support in various iPhonc nodc|s
Model Focus Flash Megapixels Size Video
Original iPhone Fixed No 2.0 16001200 No
iPhone 3G Fixed No 2.0 16001200 No
iPhone 3GS Autofocus No 3.2 20481536 VGA at 30fps
iPhone 4 Autofocus LED flash 5.0 for still 25921944 720p at 30fps
1.4 for video 12801024
Fixed No 1.4 12801024 360p at 30fps
iPod touch (4th Gen) Fixed No 0.69 for still 960720 720p at 30fps
0.92 for video 1280720
Fixed No 1.4 12801024 VGA at 30fps
iPad 2 Fixed No 0.69 for still 960720 720p at 30fps
0.92 for video 1280720
Fixed No 1.4 12801024 VGA at 30fps
All mouels piouuce geocoueu images Ly uelault.
Capturing Stills and Video
The UIImagePickerViewController is an Apple-supplieu inteilace loi choosing images
anu movies, anu taking new images oi movies (on suppoiteu uevices). This class han-
ules all ol the ieguiieu inteiaction with the usei anu is veiy simple to use. All you neeu
to uo is tell it to stait, then uismiss it altei the usei selects an image oi movie.
10 | Chapter 2:Using the Camera
Let`s go aheau anu Luilu a simple application to illustiate how to use the image pickei
contiollei. Open Xcoue anu stait a new pioject. Select a View-Laseu Application loi
the iPhone, anu name it Mcdia when ieguesteu.
The liist thing to uo is set up the main view. This is going to consist ol a single Lutton
that is piesseu to Liing up the Image Pickei contiollei. An UIImageView will uisplay the
image, oi thumLnail ol the viueo, that is captuieu.
Select the Mcdia\icwContro||cr.h inteilace lile to open it in the euitoi anu auu a UIBut
ton anu an associateu methou to the inteilace lile. Flag these as an IBOutletanu IBAction
respectively. You also neeu to auu a UIImageView to uisplay that image ietuineu Ly the
image pickei, which also neeus to Le llaggeu as an IBOutlet. Finally, auu a UIImage
PickerController, anu llag the view contiollei as Loth UIImagePickerControllerDele
gate anu UINavigationControllerDelegate. The coue to auu to the uelault template is
shown in Lolu:
#import <UIKit/UIKit.h>
@interface MediaViewController : UIViewController
<UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
IBOutlet UIButton *pickButton;
IBOutlet UIImageView *imageView;
UIImagePickerController *pickerController;
}
-(IBAction) pickImage:(id) sender;
@end
Both UIImagePickerControllerDelegate anu UINavigationControllerDelegate uec-
laiations aie necessaiy loi the class to inteiact with the UIImagePickerController.
Next, open the Mcdia\icwContro||cr.n implementation lile anu auu a stuL loi the
pickImage: methou. As always, iememLei to ielease the pickButton, imageView anu the
pickerController in the dealloc methou:
-(IBAction) pickImage:(id) sender {
// Code goes here later
}
- (void)dealloc {
[pickButton release];
[imageView release];
[pickerController release];
[super dealloc];
}
Altei saving youi changes (-S) single click on the Mcdia\icwContro||cr.xib NIB lile
to open it in Inteilace Builuei. Diag anu uiop a UIButton anu a UIImageView into the
main View winuow. Go aheau anu change the Lutton text to something appiopiiate,
anu in the Attributcs |nspcctor ol the Utilities panel set the UIImageView`s view moue to
Capturing Stills and Video | 11
Le Aspect Fit. Use the Size inspectoi iesize the UIImageView to a +:3 iatio. I useu
2S0210 points which lits nicely in a Poitiait-moue iPhone scieen.
Next click on File`s Ownei in the main panel. In the Connections inspectoi ol the
Utilities panel, connect Loth the pickButton outlet anu the pickImage: ieceiveu action
to the Lutton you just uioppeu into the View choosing Touch Up Insiue as the action,
see Figuie 2-1.
Iigurc 2-1. Connccting thc U|Button to Ii|c`s Owncr
Then connect the imageView outlet to the UIImageView in oui usei inteilace.
Click on the Mcdia\icwContro||cr.n implementation lile anu uncomment the viewDid
Load: methou. You`ie going to use this to initialize the UIImagePickerController. Make
the changes shown in Lolu:
- (void)viewDidLoad {
[super viewDidLoad];
pickerController = [[UIImagePickerController alloc] init];
pickerController.allowsEditing = NO;
pickerController.delegate = self;
}
12 | Chapter 2:Using the Camera
This allocates anu initializes the UIImagePickerController; uon`t loiget to ielease it
insiue the dealloc methou.
This line pievents the pickei contiollei liom uisplaying the ciop anu iesize tools. Il
enaLleu, the ciop anu iesize stage is shown altei captuiing a still. Foi viueo, the
tiimming inteilace is piesenteu.
This line sets the uelegate class to Le the cuiient class, the MediaViewController.
The UIImagePickerController can Le uiiecteu to select an image (oi viueo) liom thiee
image souices: UIImagePickerControllerSourceTypeCamera, UIImagePickerController
SourceTypePhotoLibrary anu UIImagePickerControllerSourceTypeSavedPhotosAlbum.
Each piesents a uilleient view to the usei allowing hei to take an image (oi a viueo)
with the cameia, liom the image liLiaiy, oi liom the saveu photo alLum.
Now wiite the pickImage: methou that will piesent the image pickei contiollei to the
usei. Theie aie a lew goou ways to uo that, uepenuing on the inteilace you want to
piesent. The liist methou, makes use ol a UIActionSheet to choose the souice type,
piesenting the usei with a list to ueciue whethei they will take a still image oi a viueo:
-(void)pickImage: (id)sender {
UIActionSheet *popupQuery = [[UIActionSheet alloc]
initWithTitle:nil
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Photo",@"Video",nil];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[popupQuery showInView:self.view];
[popupQuery release];
}
Il we`ie going to use this methou we must specily that the view contiollei suppoits the
UIActionSheetDelegate piotocol in the inteilace lile:
@interface MediaViewController : UIViewController
<UIImagePickerControllerDelegate, UINavigationControllerDelegate,
UIActionSheetDelegate> {
In the implementation lile, pioviue an actionSheet:clickedButtonAtIndex: uelegate
methou to hanule piesenting the image pickei inteilace. Il theie is no cameia piesent
the souice will Le set to the saveu photos alLum:
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {

if ([UIImagePickerController
isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
} else {
pickerController.sourceType =
UIImagePickerControllerSourceTypeSavedPhotosAlbum;
Capturing Stills and Video | 13
}
if (buttonIndex == 0) {
pickerController.mediaTypes = [NSArray arrayWithObject: kUTTypeImage];
} else if (buttonIndex == 1) {
pickerController.mediaTypes = [NSArray arrayWithObject: kUTTypeMovie];
}
[self presentModalViewController:pickerController animated:YES];
}
Heie we check whethei the cameia is availaLle; il it is we set the sourceType to Le
the cameia.
Il the cameia is not availaLle, we set the sourceType to Le the Saveu Photo AlLum.
Since we`ve maue use ol the kUTTypeImage anu kUTTypeMovie type coues in this methou
we have to auu the MoLile Coie Seivices liamewoik to oui pioject.
Foi those ol you useu to woiking in Xcoue 3, the way you auu liame-
woiks to youi pioject has changeu. In the past you weie aLle to iight-
click on the Fiamewoik`s gioup anu then select AuuExisting Fiame-
woiks. Unloitunately this is no longei possiLle anu auuing liamewoiks
has Lecome a moie laLoiious piocess.
To auu the liamewoik, select the Meuia pioject lile in the Pioject navigatoi winuow.
You shoulu see a panel as in see Figuie 2-2. Select the Taiget anu click on the Builu
Phases taL. Select the Link with LiLiaiies uiop uown anu use the - Lutton to auu the
Mobi|cCorcScrviccs.jrancwor| liom the list ol availaLle liamewoiks.
Auu the lollowing to the view contiollei inteilace lile:
#import <MobileCoreServices/MobileCoreServices.h>
Altei saving the changes you can click on the Builu anu Run Lutton. You shoulu Le
piesenteu with an inteilace much like Figuie 2-3 (lelt). Clicking on the Go Lutton
you shoulu Le piesenteu with the UIActionSheet that piompts the usei to choose Le-
tween still image anu viueo captuie.
Il you uo go aheau anu test the application in the iPhone Simulatoi you`ll
notice that theie aien`t any images in the Saveu Photos loluei, see Fig-
uie 2-3 (iight). Howevei theie is a way aiounu this pioLlem. In the
Simulatoi, tap on the Salaii Icon anu uiag anu uiop a pictuie liom youi
computei (you can uiag it liom the Finuei oi iPhoto) into the Liowsei.
Fiom the Liowsei you can save the image to the Saveu Photos loluei.
Insteau ol explicitly choosing an image oi viueo via the action sheet, you coulu insteau
allow the usei to pick the souice. The lollowing alteinative coue ueteimines whethei
youi uevice suppoits a cameia anu auus all ol the availaLle meuia types to an aiiay. Il
theie is no cameia piesent the souice will again Le set to the saveu photos alLum:
14 | Chapter 2:Using the Camera
-(void)pickImage: (id)sender {
if ([UIImagePickerController
isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
NSArray* mediaTypes =
[UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypeCamera];
pickerController.mediaTypes = mediaTypes;
} else {
pickerController.sourceType =
UIImagePickerControllerSourceTypeSavedPhotosAlbum;
}
[self presentModalViewController:pickerController animated:YES];
}
Iigurc 2-2. Adding thc Mobi|cCorcScrviccs.jrancwor| to thc projcct
Heie insteau ol piesenting an action sheet anu allowing the usei to choose which souice
type they wish to use we inteiiogate the haiuwaie anu ueciue which souice types aie
availaLle. Ve can see the uilleient inteilaces these two methous geneiate in Fig-
uie 2-+. The lelt inteilace is the still cameia inteilace, the miuule image is the viueo
cameia inteilace anu the linal (iight-hanu) image is the joint inteilace, which allows
the usei to eithei take still image oi viueo.
Capturing Stills and Video | 15
The linal inteilace, wheie the usei may choose to ietuin eithei a still image oi a viueo,
is the one piesenteu Ly the seconu veision ol the pickImage: methou. This coue is also
moie llexiLle as it will iun unmouilieu on any ol the iPhone mouels that have a cameia
uevice. Il youi application ieguiies eithei a still image oi a viueo (anu can not hanule
Loth) you shoulu Le caielul to specily eithei kUTTypeImage oi kUTTypeMovie meuia type
as you uiu in the liist veision ol the methou.
You can choose eithei ol the two uilleient methous I`ve talkeu aLout aLove to piesent
the image pickei contiollei to the usei. In eithei case when the usei has linisheu picking
an image (oi viueo) the lollowing uelegate methou will Le calleu in the view contiollei:
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {

if( [info objectForKey:@"UIImagePickerControllerMediaType"] ==
kUTTypeMovie ) {
// add code here
} else {
imageView.image =
[info objectForKey:@"UIImagePickerControllerOriginalImage"];
}
[self dismissModalViewControllerAnimated:YES];
}
Iigurc 2-3. Thc initia| Mcdia app|ication intcrjacc (|cjt), thc U|ActionShcct that pops up whcn thc
button is prcsscd (nidd|c), and thc Savcd Photos jo|dcr that appcars whcn thc cancra is unavai|ab|c
(right)
16 | Chapter 2:Using the Camera
Ve must uismiss the image pickei inteilace in all cases.
Vhen the UIImagePickerController ietuins it passes an NSDictionary containing a
numLei ol keys, listeu in TaLle 2-2. Use the UIImagePickerControllerMediaType key to
ueciue whethei the image pickei is ietuining a still image oi a movie to its uelegate
methou.
Tab|c 2-2. Kcys jron thc NSDictionary rcturncd by thc inagc pic|cr contro||cr
Key Object type
UIImagePickerControllerMediaType kUTTypeImage or kUTypeMovie
UIImagePickerControllerOriginalImage UIImage
UIImagePickerControllerEditedImage UIImage
UIImagePickerControllerCropRect CGRect
UIImagePickerControllerMediaURL NSURL
Ve can ietiieve the oiiginal image (oi cioppeu veision il euiting is enaLleu) uiiectly
liom the NSDictionary that was passeu into the uelegate methou. This image ieleience
can Le passeu uiiectly to the UIImageView anu uisplayeu, as shown in the coue in the
next section anu Figuie 2-5.
Iigurc 2-1. Thc thrcc dijjcrcnt U||nagcPic|crContro||cr intcrjaccs
Capturing Stills and Video | 17
Video Thumbnails
Theie is no easy way to ietiieve a thumLnail ol a viueo, unlike still photos. This section
illustiates two methous ol giaLLing iaw image uata liom an image pickei.
Video Thumbnails Using the UIImagePicker
One way to giaL a viueo liame loi cieating a thumLnail is to uiop uown to the unuei-
lying Quaitz liamewoik to captuie an image ol the pickei itsell. To uo so, auu the
lollowing highlighteu coue to the image pickei uelegate uesciiLeu pieviously in this
chaptei:
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {

if( [info objectForKey:@"UIImagePickerControllerMediaType"] ==
kUTTypeMovie ) {
CGSize pickerSize = CGSizeMake(picker.view.bounds.size.width,
picker.view.bounds.size.height-100);
UIGraphicsBeginImageContext(pickerSize);
[picker.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageView.image = thumbnail;
Iigurc 2-5. A thunbnai| oj a sing|c jranc oj vidco disp|aycd in a U||nagc\icw
18 | Chapter 2:Using the Camera
} else {
imageView.image = image;
}
[self dismissModalViewControllerAnimated:YES];
}
Since picker.view.layer is pait ol the UIView paient class anu is ol type CALayer, the
compilei uoesn`t know aLout renderInContext: methou unless you impoit the Quaitz-
Coie heauei lile. Auu the lollowing to the implementation lile:
#import <QuartzCore/QuartzCore.h>
Video Thumbnails Using AVFoundation
Anothei methou to oLtain a thumLnail that will iesult in a Lettei image is to use the
AVFoundation liamewoik. Fiist ieplace the coue you auueu in the pievious section with
the highlighteu coue Lelow:
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {

if( [info objectForKey:@"UIImagePickerControllerMediaType"] ==
kUTTypeMovie ) {
AVURLAsset *asset=[[AVURLAsset alloc]
initWithURL:[info objectForKey:UIImagePickerControllerMediaURL]
options:nil];
AVAssetImageGenerator *generator =
[[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform=TRUE;
[asset release];
CMTime thumbTime = CMTimeMakeWithSeconds(0,30);
AVAssetImageGeneratorCompletionHandler handler =
^(CMTime requestedTime, CGImageRef im, CMTime actualTime,
AVAssetImageGeneratorResult result, NSError *error) {
if (result != AVAssetImageGeneratorSucceeded) {
NSLog(@"Error:%@", error);
}
imageView.image = [[UIImage imageWithCGImage:im] retain];
[generator release];
};
CGSize maxSize = CGSizeMake(320, 180);
generator.maximumSize = maxSize;
[generator generateCGImagesAsynchronouslyForTimes:
[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]]
completionHandler:handler];
} else {
imageView.image = image;
Video Thumbnails | 19
}
[self dismissModalViewControllerAnimated:YES];
}
Then make suie to auu the AVFounuation anu CoieMeuia liamewoiks to the pioject
Ly impoiting the heauei liles at the top ol the implementation:
#import <AVFoundation/AVFoundation.h>
#import <CoreMedia/CoreMedia.h>
The only ieal uownsiue ol this methou is that AVAssetImageGenerator makes use ol key
liames, which aie typically spaceu at one seconu inteivals. Hopelully the key liame will
make a goou thumLnail image.
Saving Media to the Photo Album
You can save Loth images anu viueos to the Photo AlLum using the UIImageWriteToSa
vedPhotosAlbum anu UISaveVideoAtPathToSavedPhotosAlbum methous. The methou will
also oLtain a thumLnail image loi the viueo il uesiieu.
The saving lunctions in this example aie asynchionous; il the application is inteiiupteu
(e.g., takes a phone call) oi teiminateu, the image oi viueo will Le lost. You neeu to
ensuie that youi usei is awaie that piocessing is happening in the Lackgiounu as pait
ol youi application inteilace.
The lollowing example save the image to the Photo AlLum Ly auuing a call to UIImage
WriteToSavedPhotosAlbum to the image pickei uelegate. The example will then pioviue
leeuLack when the image has Leen successlully saveu oi an eiioi occuis. Auu the lol-
lowing highlighteu lines to the image pickei contiollei piesenteu eailiei in the chaptei:
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {

if( [info objectForKey:@"UIImagePickerControllerMediaType"] ==
kUTTypeMovie ) {

CGSize pickerSize = CGSizeMake(picker.view.bounds.size.width,
picker.view.bounds.size.height-100);
UIGraphicsBeginImageContext(pickerSize);
[picker.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageView.image = thumbnail;
} else {
UIImage *image =
[info objectForKey:@"UIImagePickerControllerOriginalImage"];
UIImageWriteToSavedPhotosAlbum(
image,
self,
@selector(
imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:),
20 | Chapter 2:Using the Camera
nil);
imageView.image = image;
}
[self dismissModalViewControllerAnimated:YES];
}
Then auu the lollowing methou, which piesents a UIAlertView notilying the usei that
the save has occuiieu:
- (void)imageSavedToPhotosAlbum:(UIImage *)image
didFinishSavingWithError:(NSError *)error
contextInfo:(void *)contextInfo {
NSString *title;
NSString *message;
if (!error) {
title = @"Photo Saved";
message = @"The photo has been saved to your Photo Album";
} else {
title = NSLocalizedString(@"Error Saving Photo", @"");
message = [error description];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
The call to UIImageWriteToSavedPhotosAlbum can typically take up to +
seconus to complete in the Lackgiounu. Il the application is inteiiupteu
oi teiminateu uuiing this time then the image may not have Leen saveu.
You can similaily auu the lollowing highlighteu lines to the uelegate methou to save
captuieu viueo:
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
if( [info objectForKey:@"UIImagePickerControllerMediaType"] == kUTTypeMovie ) {
NSString *tempFilePath =
[[info objectForKey:UIImagePickerControllerMediaURL] path];
if ( UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(tempFilePath) ) {
UISaveVideoAtPathToSavedPhotosAlbum( tempFilePath, self,
@selector(video:didFinishSavingWithError:contextInfo:),
tempFilePath);
}
CGSize pickerSize = CGSizeMake(picker.view.bounds.size.width,
picker.view.bounds.size.height-100);
UIGraphicsBeginImageContext(pickerSize);
Saving Media to the Photo Album | 21
[picker.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageView.image = thumbnail;
} else {
UIImage *image =
[info objectForKey:@"UIImagePickerControllerOriginalImage"];
UIImageWriteToSavedPhotosAlbum(image, self,
@selector(
imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), nil);
imageView.image = image;
}
[self dismissModalViewControllerAnimated:YES];
}
Next auu the lollowing methou to iepoit whethei the viueo has Leen successlully saveu
to the uevice`s Photo AlLum, oi an eiioi occuiieu:
- (void)video:(NSString *)videoPath
didFinishSavingWithError:(NSError *)error
contextInfo:(NSString *)contextInfo {
NSString *title;
NSString *message;
if (!error) {
title = @"Video Saved";
message = @"The video has been saved to your Photo Album";
} else {
title = NSLocalizedString(@"Error Saving Video", @"");
message = [error description];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
Make suie you`ve saveu youi changes, anu click on the Run Lutton in the Xcoue toolLai
to compile anu ueploy the application to youi uevice. Il eveiything is woiking, you will
see a thumLnail altei you take a photo oi viueo. Altei a lew seconus a conliimation
uialog will appeai iepoiting success oi an eiioi. See Figuie 2-6.
22 | Chapter 2:Using the Camera
Iigurc 2-. Saving inagcs (or vidco) to thc Photo A|bun
Video Customization
Il you aie captuiing viueo you can make some viueo-specilic customizations using the
videoQuality anu videoMaximumDuration piopeities ol the UIImagePickerController
class:
pickerController.videoQuality = UIImagePickerControllerQualityTypeLow;
pickerController.videoMaximumDuration = 90; // Maximum 90 seconds duration
TaLle 2-3 illustiates the expecteu sizes ol a typical 90 seconu movie lile loi the thiee
possiLle image guality levels, which uelaults to UIImagePickerControllerQualityType
Medium.
Tab|c 2-3. Sizc oj 90 scconds duration vidco jor dijjcrcnt qua|ity scttings
Quality Size
UIImagePickerControllerQualityTypeLow 1.8 MB
UIImagePickerControllerQualityTypeMedium 8.4 MB
UIImagePickerControllerQualityTypeHigh 32 MB
Video Customization | 23
The maximum, anu uelault, value loi the videoMaximumDuration piopeity is 10 minutes.
Useis aie loiceu to tiim longei viueo to match the uuiation you ieguest.
24 | Chapter 2:Using the Camera
CHAPTER 3
Using Audio
The main classes loi hanuling auuio in the SDK aie in the AVFounuation anu Meuia
Playei liamewoiks. This chaptei will pioviue a Liiel oveiview ol how to play anu iecoiu
auuio using these liamewoiks.
The Hardware
Vhilst most phones have only one miciophone, iPhone + has two. The main micio-
phone is locateu noimally on the Lottom next to the uock connectoi, while the seconu
miciophone is Luilt into the top neai the heauphone jack. This seconu miciophone is
intenueu loi viueo-calling, Lut is also useu in conjunction with the main miciophone
to suppiess Lackgiounu noise.
In compaiison the iPau 2 has a single miciophone, Lut theie is a uilleience Letween
the two mouels which coulu leau to a uilleience in auuio iecoiuing guality Letween
the 3G anu ViFi-only mouels. On the ViFi-only mouel, the miciophone hole is Luilt-
into the Lack ol the uevice, wheieas on 3G mouels, it`s Luilt into the antenna casing.
Theie aie suggestions that this uilleience may leau to cleanei auuio iecoiuings with the
ViFi mouel, with the 3G mouel sounuing mullleu anu echo-pione Ly compaiison.
Both the iPhone + anu the iPau use an Apple Lianueu Ciiius Logic 33SS05S9 loi theii
auuio DAC, with a lieguency iesponse ol 20Hz to 20kHz, anu auuio sampling ol 16-
Lit at ++.1kHz.
All ol the cuiient iPhone, iPau anu iPou touch mouels use a 2.5mm +-pole TRRS (tip,
iing, iing, sleeve) connectoi which has a somewhat unoithouox mapping to the stanu-
aiu RCA connectoi as shown in TaLle 3-1.
Tab|c 3-1. Mapping bctwccn thc iPhonc`s 1-po|c jac| and thc standard RCA conncctor co|ors
Apple RCA
Tip RCA White
1st Ring RCA Yellow
25
Apple RCA
2nd Ring RCA Ground
Sleeve RCA Red
Media Playback
Let`s liist look at playing Lack existing meuia stoieu in the iPou liLiaiy. Apple has
pioviueu convenience classes that allow you to select anu play Lack iPou meuia insiue
youi own application as pait ol the Meuia Playei liamewoik.
The lollowing examples make use ol the iPou liLiaiy; this is not piesent
in the iPhone Simulatoi anu will only woik coiiectly on the uevice itsell.
The appioach uses pickei contiolleis anu uelegates as in the pievious chaptei. In this
example I use an MPMediaPickerController that, via the MPMediaPickerControllerDele
gate piotocol, ietuins an MPMediaItemCollection oLject containing the meuia items the
usei has selecteu. The collection ol items can Le playeu using an MPMusicPlayerControl
ler oLject.
Lets go aheau anu Luilu a simple meuia playei application to illustiate how to use the
meuia pickei contiollei. Open Xcoue anu stait a new View-Laseu Application pioject,
naming it Auuio when ieguesteu. Click on the Auuio pioject lile in the Pioject nav-
igatoi winuow, select the Taiget anu click on the Builu Phases taL. Click on the Link
with LiLiaiies uiop uown anu click on the - Lutton to auu the MeuiaPlayei liamewoik.
Euit the Audio\icwContro||cr.h inteilace lile to impoit the MeuiaPlayei liamewoik anu
ueclaie the class as an MPMediaPickerControllerDelegate. Then auu the IBOutlet in-
stance vaiiaLles anu IBAction methous loi the Luttons we will cieate in Inteilace
Builuei:
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
@interface AudioViewController : UIViewController
<MPMediaPickerControllerDelegate> {
IBOutlet UIButton *pickButton;
IBOutlet UIButton *playButton;
IBOutlet UIButton *pauseButton;
IBOutlet UIButton *stopButton;
MPMusicPlayerController *musicPlayer;
}
- (IBAction)pushedPick:(id)sender;
- (IBAction)pushedPlay:(id)sender;
26 | Chapter 3:Using Audio
- (IBAction)pushedPause:(id)sender;
- (IBAction)pushedStop:(id)sender;
@end
Save youi changes, anu open the Audio\icwContro||cr.n implementation lile. In the
pushedPick: methou, instantiate an MPMediaPickerController oLject. The view will Le
moual, which means that the usei must make a selection to leave picking moue. Ve`ll
link this methou uiiectly to a Lutton in the usei inteilace:
-(IBAction) pushedPick:(id)sender {
MPMediaPickerController *mediaPicker =
[[MPMediaPickerController alloc]
initWithMediaTypes: MPMediaTypeAnyAudio];
mediaPicker.delegate = self;
mediaPicker.allowsPickingMultipleItems = YES;
[self presentModalViewController:mediaPicker animated:YES];
[mediaPicker release];
}
You must now implement the lollowing two uelegate methous, which aie useu to uis-
miss the view contiollei anu hanule the ietuineu items:
- (void) mediaPicker:(MPMediaPickerController *)
mediaPicker didPickMediaItems:(MPMediaItemCollection *)
userMediaItemCollection {

[self dismissModalViewControllerAnimated: YES];
musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
[musicPlayer setQueueWithItemCollection: userMediaItemCollection];
}
- (void) mediaPickerDidCancel: (MPMediaPickerController *) mediaPicker {
[self dismissModalViewControllerAnimated: YES];
}
The MPMusicPlayeiContiollei iesponus to all the messages you might expect, e.g.,
play, pause, stop, volume, etc. These can Le linkeu to Luttons in the usei inteilace
il you want to give useis uiiect contiol ovei these lunctions.
You`ll link the iemaining methous uiiectly to Luttons in the usei inteilace:
-(IBAction) pushedPlay:(id)sender {
[musicPlayer play];
}
-(IBAction) pushedPause:(id)sender {
[musicPlayer pause];
}
-(IBAction) pushedStop:(id)sender {
[musicPlayer stop];
}
Media Playback | 27
RememLei to ielease the instance oLjects in the dealloc methou:
- (void)dealloc {
[pickButton release];
[playButton release];
[pauseButton release];
[stopButton release];
[musicPlayer release];
[super dealloc];
}
Save youi changes, anu click on the Audio\icwContro||cr.xib NIB lile to open it in
Inteilace Builuei. Diag loui UIButton elements liom the LiLiaiy winuow into the View
winuow. DouLle click on each ol them anu change the uelault text to Le Pick, Play,
Pause anu Stop. Then open the Assistant Euitoi (ViewAssistant EuitoiShow
Assistant Euitoi) anu Contiol-Click anu uiag to associate the Luttons with theii ie-
spective IBOutlet anu IBAction outlets anu actions in the Audio\icwContro||cr.h in-
teilace lile, see Figuie 3-1.
Iigurc 3-1. Connccting thc app|ication`s uscr intcrjacc in |ntcrjacc Bui|dcr
Save youi changes anu click on the Run Lutton in the Xcoue toolLai to Luilu anu ueploy
the coue to youi uevice.
28 | Chapter 3:Using Audio
RememLei that you`ll neeu to test the application on youi uevice.
Once the application loaus, tap on the Pick Lutton to Liing up the pickei contiollei,
select some songs, anu tap the Done Lutton.(see Figuie 3-2). Piess the Play Lutton
anu the music you selecteu shoulu stait playing.
Iigurc 3-2. Thc initia| nain vicw (|cjt), thc MPMcdiaPic|crContro||cr (nidd|c), and thc nain
intcrjacc whi|c a song is bcing p|aycd (right)
Once playLack has Legun you neeu to keep tiack ol the cuiiently playing item anu
uisplay that to the usei. At the veiy least you must pioviue some way loi the usei to
pause oi stop playLack, anu peihaps to change theii selection. The MPMusicPlayerCon
troller class pioviues two methous: the beginGeneratingPlaybackNotifications:
methou, anu a coiiesponuing endGeneratingPlaybackNotifications:. Auu the high-
lighteu line Lelow to youi mediaPicker:didPickMediaItems: uelegate methou:
- (void) mediaPicker:(MPMediaPickerController *) mediaPicker
didPickMediaItems:(MPMediaItemCollection *) userMediaItemCollection {

[self dismissModalViewControllerAnimated: YES];
musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
[musicPlayer setQueueWithItemCollection: userMediaItemCollection];
Media Playback | 29
[musicPlayer beginGeneratingPlaybackNotifications];
}
Vhen the Legin methou is invokeu the class will stait to geneiate notilications when
the playei state changes anu when the cuiient playLack item changes. Youi application
can access this inloimation Ly auuing itsell as an oLseivei using the NSNotification
Center class:
- (void) mediaPicker:(MPMediaPickerController *) mediaPicker
didPickMediaItems:(MPMediaItemCollection *) userMediaItemCollection {

[self dismissModalViewControllerAnimated: YES];
musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
[musicPlayer setQueueWithItemCollection: userMediaItemCollection];
[musicPlayer beginGeneratingPlaybackNotifications];
NSNotificationCenter *notificationCenter =
[NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(handleNowPlayingItemChanged:)
name:@"MPMusicPlayerControllerNowPlayingItemDidChangeNotification"
object:musicPlayer];
[notificationCenter addObserver:self
selector:@selector(handlePlaybackStateChanged:)
name:@"MPMusicPlayerControllerPlaybackStateDidChangeNotification"
object:musicPlayer];
}
This will invoke the selectoi methous in the class when the appiopiiate notilication
aiiives. You coulu, loi example, use the liist to upuate a UILabel in the view telling the
usei the name ol the cuiiently playing song.
Foi now let`s just go aheau anu implement these methous to piint messages to the
console log. In the Audio\icwContro||cr.n implementation lile, auu the methou Lelow.
This will Le calleu when the cuiient item Leing playeu changes:
- (void)handleNowPlayingItemChanged:(id)notification {
MPMediaItem *currentItem = [musicPlayer nowPlayingItem];
NSString *title = [currentItem valueForProperty:MPMediaItemPropertyTitle];
NSLog(@"Song title = %@", title);
}
Unusually, the MPMeuiaItem class only has one instance methou, the valueForProp
erty: methou. This is Lecause the class can wiap a numLei ol meuia types, anu each
type can have a laiily wiue iange ol metauata associateu with it. A lull list ol possiLle
keys can Le lounu in the MPMeuiaItem class ieleience, Lut keys incluue MPMediaI
temPropertyTitle, MPMediaItemPropertyArtwork, etc.
You can use this to upuate the usei inteilace, e.g., changing the state ol the play anu
stop Luttons when the music enus:
30 | Chapter 3:Using Audio
- (void)handlePlaybackStateChanged:(id)notification {
MPMusicPlaybackState playbackState = [musicPlayer playbackState];
if (playbackState == MPMusicPlaybackStatePaused) {
NSLog(@"Paused");
} else if (playbackState == MPMusicPlaybackStatePlaying) {
NSLog(@"Playing");
} else if (playbackState == MPMusicPlaybackStateStopped) {
NSLog(@"Stopped");
}
}
Save youi changes, anu click on the Run Lutton in the Xcoue toolLai to Luilu anu
ueploy youi coue onto youi uevice. Once youi application loaus, piess the Pick Lut-
ton to Liing up the pick contiollei again, select some songs, anu piess the Done
Lutton. Piess Play anu the music shoulu stait playing. You shoulu also see something
similai to the log messages Lelow in the DeLuggei Console:
2011-06-01 19:23:07.602 Audio[2844:707] Song title = Affirmation
2011-06-01 19:23:07.617 Audio[2844:707] Playing
You coulu go on to uevelop the application Ly uisplaying inloimation aLout the cui-
iently playing anu gueueu songs. Let`s move on liom playing existing meuia anu look
at how to play anu iecoiu youi own auuio on the uevice.
Recording and Playing Audio
The AVAudioRecorder class is pait ol the AVFounuation liamewoik anu pioviues auuio
iecoiuing capaLilities loi an application. The liamewoik allows you to:
Recoiu until the usei stops the iecoiuing
Recoiu loi a specilieu uuiation
Pause anu iesume a iecoiuing
The coiiesponuing AVAudioPlayer class (also pait ol the AVFounuation liamewoik)
pioviues some laiily sophisticateu lunctionality allowing you to play sounu in youi
application. It can:
Play sounus ol any uuiation
Play sounus liom liles oi memoiy Lulleis
Loop sounus
Play multiple sounus simultaneously (one sounu pei auuio playei) with piecise
synchionization
Contiol ielative playLack level anu steieo positioning loi each sounu you aie
playing
Recording and Playing Audio | 31
Seek to a paiticulai point in a sounu lile, which suppoits such application leatuies
as last loiwaiu anu iewinu
Recording Audio
Lets Luilu a simple application to iecoiu some auuio to a lile anu play it Lack latei.
Open Xcoue anu stait a new View-Laseu Application, naming it Rccordcr when
ieguesteu.
Vhen the Xcoue pioject opens, auu both the AVFounuation anu CoieAuuio liame-
woiks to the pioject in a similai mannei as we auueu the MeuiaPlayei liamewoik to
the Auuio application eailiei in the chaptei.
Click on the Rccordcr\icwContro||cr.h inteilace lile to open it in the Stanuaiu Euitoi
anu make the lollowing changes to the template lile geneiateu loi you Ly Xcoue:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface RecorderViewController : UIViewController
<AVAudioRecorderDelegate> {
IBOutlet UIButton *startStopButton;
NSURL *tmpFile;
AVAudioRecorder *recorder;
BOOL recording;
}
- (IBAction)startStopButtonPressed;
@end
Save youi changes anu open the coiiesponuing RecorderViewController.xib lile in In-
teilace Builuei. Diag anu uiop a UIButton liom the OLject LiLiaiy in the Utilities pane
into the View anu change the title text to Stait Recoiuing. Then connect it to the
IBOutlet anu IBAction in youi inteilace lile using the Assistant Euitoi, as in Figuie 3-3.
Save youi changes anu open the Rccordcr\icwContro||cr.n implementation lile in the
Stanuaiu Euitoi, making the lollowing changes to the uelault template geneiateu Ly
Xcoue:
#import "RecorderViewController.h"
#import <CoreAudio/CoreAudioTypes.h>
@implementation RecorderViewController
- (IBAction)startStopButtonPressed {
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
if (!recording) {
// Add code here...
32 | Chapter 3:Using Audio
} else {
// Add code here...
}
}
- (void)dealloc {
[startStopButton release];
[tmpFile release];
[recorder release];
[super dealloc];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
recording = NO;
Iigurc 3-3. Connccting thc uscr intcrjacc in |ntcrjacc Bui|dcr
Recording and Playing Audio | 33
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
interfaceOrientation {

return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end
Then make the lollowing changes to the startStopButtonPressed methou:
- (IBAction)startStopButtonPressed {
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
if (!recording) {
recording = YES;
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
[audioSession setActive:YES error:nil];
[startStopButton setTitle:@"Stop Recording"
forState:UIControlStateNormal];
NSMutableDictionary* recordSetting =
[[NSMutableDictionary alloc] init];
[recordSetting setValue:
[NSNumber numberWithInt:kAudioFormatAppleIMA4]
forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0]
forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 2]
forKey:AVNumberOfChannelsKey];
tmpFile = [NSURL fileURLWithPath:
[NSTemporaryDirectory() stringByAppendingPathComponent:
[NSString stringWithFormat: @"%.0f.%@",
[NSDate timeIntervalSinceReferenceDate] * 1000.0,
@"caf"]]];
recorder = [[AVAudioRecorder alloc] initWithURL:tmpFile
settings:recordSetting
error:nil];
[recorder setDelegate:self];
[recorder prepareToRecord];
[recorder record];
} else {
recording = NO;
[audioSession setActive:NO error:nil];
34 | Chapter 3:Using Audio
[startStopButton setTitle:@"Start Recording"
forState:UIControlStateNormal];
[recorder stop];
}
}
Il you save youi changes anu click on the Run Lutton to Luilu anu ueploy the application
to youi uevice you shoulu see the Stait Recoiuing Lutton changes to Stop Recoiu-
ing when piesseu. Piessing the Lutton again shoulu change the text Lack to Stait
Recoiuing. In the next section I`ll show you a way to check that the uevice is actually
iecoiuing auuio.
Playing Audio
Open up the Rccordcr\icwContro||cr.h inteilace lile anu auu the lollowing IBOutlet
instance vaiiaLle:
IBOutlet UIButton *playButton;
along with the lollowing IBAction methou:
- (IBAction)playButtonPressed;
Iigurc 3-1. Adding thc P|ay Rccording button to thc uscr intcrjacc
Recording and Playing Audio | 35
Then single click on the Rccordcr\icwContro||cr.xib lile to open it in Inteilace Builuei.
Diag anu uiop anu new UIButton into the view anu change the title text to Le Play
Recoiuing. Use the Assistant Euitoi to connect the new Lutton to the iecently auueu
IBOutlet anu IBAction in the inteilace lile, see Figuie 3-+.
Save youi changes, ietuin to the Rccordcr\icwContro||cr.n implementation lile anu
auu the lollowing methou implementation:
- (IBAction)playButtonPressed {
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
AVAudioPlayer * player =
[[AVAudioPlayer alloc] initWithContentsOfURL:tmpFile error:nil];
[player prepareToPlay];
[player play];
}
Save youi changes anu click on the Run Lutton in the Xcoue toolLai to Luilu anu ueploy
the application to youi uevice. You shoulu see something like Figuie 3-5.
Il you now tap on the Stait Recoiuing Lutton the title ol the Lutton shoulu change
to Stop Recoiuing; speak into the iPhone`s miciophone loi lew seconus anu tap the
Lutton again. Then tap on the Play Recoiuing Lutton anu you shoulu heai youisell
speaking.
Iigurc 3-5. Thc jinishcd Rccordcr app|ication
36 | Chapter 3:Using Audio
CHAPTER 4
Using the Accelerometer
An acceleiometei measuies the lineai acceleiation ol the uevice. The oiiginal iPhone,
anu liist geneiation iPou touch, use the LIS302DL 3-axis MEMS Laseu acceleiometei
piouuceu Ly STMicioelectionics. Latei iPhone anu iPou touch mouels use a similai
LIS331DL chip, also manulactuieu Ly STMicioelectionics.
Both ol these acceleiometeis can opeiate in two moues, allowing the chip to measuie
eithei 2g anu Sg. In Loth moues the chip can sample at eithei 100 Mhz oi +00 Mhz.
Apple opeiates the acceleiometei in the 2g moue (piesumaLly at 100 Mhz) with a
nominal iesolution ol 0.01Sg. In the Sg moue the iesolution woulu Le loui times
coaisei, anu the piesumption must Le that Apple ueciueu Lettei iesolution woulu Le
moie uselul than a wiuei iange. Unuei noimal conuitions the uevice will actually
measuie g-loices to appioximately 2.3g howevei measuiements aLove a 2g aie un-
caliLiateu.
Vhile it shoulu in theoiy Le possiLle to change the opeiating moue ol
the acceleiometei, theie is cuiiently no puLlisheu API that allows you
to uo so within the SDK.
About the Accelerometer
The iPhone`s acceleiometei measuies the lineai acceleiation ol the uevice so it can
iepoit the uevice`s ioll anu pitch, Lut not its yaw. Il you aie uealing with a uevice that
has a uigital compass you can comLine the acceleiometei anu magnetometei ieauings
to have ioll, pitch, anu yaw measuiements (see Chaptei 5 loi uetails on how to access
the magnetometei).
37
Yaw, pitch, anu ro|| ielei to the iotation ol the uevice in thiee axes. Il
you think aLout an aiicialt in the sky, pushing the nose uown oi pulling
it up mouilies the pitch angle ol the aiicialt. Howevei, il you keep the
nose stiaight aheau you can also mouily the ioll ol the aiicialt using the
llaps; one wing will come up, the othei will go uown. By keeping the
wings level you can use the tail llap to change the heauing (oi yaw) ol
the aiicialt, iotating it in a 2D plane.
The acceleiometei iepoits thiee liguies: X, Y, anu Z (see Figuie +-1). Acceleiation
values loi each axis aie iepoiteu uiiectly Ly the haiuwaie as G-loice values. Theieloie,
a value ol 1.0 iepiesents a loau ol appioximately 1-giavity (Eaith`s giavity). X coiie-
sponus to ioll, Y to pitch, anu Z to whethei the uevice is liont siue up oi liont siue
uown, with a value ol 0.0 Leing iepoiteu when the iPhone is euge-on.
Vhen uealing with acceleiation measuiements you must keep in minu that the accel-
eiometei is measuiing just that: the lineai acceleiation ol the uevice. Vhen at iest (in
whatevei oiientation) the liguies iepiesent the loice ol giavity acting on the uevice, anu
coiiesponu to the ioll anu pitch ol the uevice (in the X anu Y uiiections at least). But
while in motion, the liguies iepiesent the acceleiation uue to giavity, plus the accelei-
ation ol the uevice itsell ielative to its iest liame.
Writing an Accelerometer Application
Let`s go aheau anu implement a simple application to illustiate how to appioach the
acceleiometei. Open Xcoue anu stait a new View-Laseu application loi the iPhone, anu
name the pioject Acceleiometei when piompteu loi a lilename.
The iaw acceleiometei uata can also Le accesseu using the Coie Motion
liamewoik, which was new in iOS +.0. I talk aLout how to uo this in
Chaptei 6. It is theieloie possiLle, even likely, that the UIAccelerome
ter class uiscusseu in this chaptei my Le uepiecateu in a lutuie iOS
ielease.
Click on the Accc|cronctcr\icwContro||cr.xib lile to open it into Inteilace Builuei. Since
you want to Loth iepoit the iaw liguies liom the acceleiometei anu also uisplay them
using a piogiess Lai, go aheau anu uiag anu uiop thiee UIProgressView contiols liom
the OLject LiLiaiy into the View winuow. Then auu two UILabel elements loi each
piogiess Lai: one to holu the X, Y, oi Z laLel anu the othei to holu the acceleiometei
measuiements. Altei you uo that, the view shoulu look something a lot like Figuie +-2.
Go aheau anu close the Utilities panel anu click to open the Assistant Euitoi. Then
Contiol-Click anu uiag liom the thiee UIProgressView elements, anu the thiee UILa
bel elements to the Acc|cronctcr\icwContro||cr.h heauei lile. The heauei lile shoulu
38 | Chapter 4:Using the Accelerometer
Le uisplayeu in the Assistant Euitoi on the iight-hanu siue ol the Xcoue + inteilace (see
Figuie +-3).
This will automatically cieate anu ueclaie thiee UILabel anu thiee UIProgressView vai-
iaLles as IBOutlet oLjects. Since they aien`t going to Le useu outsiue the class, theie
isn`t much point in ueclaiing them as class piopeities, which you`u uo Ly Contiol-click
anu uiag liom the element to outsiue the cuily Liace. Altei uoing this the coue shoulu
look like this:
#import <UIKit/UIKit.h>
@interface AccelerometerViewController : UIViewController {
Iigurc 1-1. Thc iPhonc accc|cronctcr axcs
Writing an Accelerometer Application | 39
IBOutlet UIProgressView *xBar;
IBOutlet UIProgressView *yBar;
IBOutlet UIProgressView *zBar;
IBOutlet UILabel *xLabel;
IBOutlet UILabel *yLabel;
IBOutlet UILabel *zLabel;
}
@end
Close the Assistant Euitoi, ietuin to the Stanuaiu Euitoi anu click on the Accc|cronc-
tcr\icwContro||cr.h inteilace lile. Now go aheau anu set up a UIAccelerometer instance.
Also ueclaie the class as a UIAccelerometerDelegate. Heie`s how the shoulu look when
you aie uone:
#import <UIKit/UIKit.h>
@interface AccelerometerViewController :
UIViewController <UIAccelerometerDelegate> {
IBOutlet UILabel *xLabel;
IBOutlet UILabel *yLabel;
IBOutlet UILabel *zLabel;
Iigurc 1-2. Thc Accc|cronctcr app|ication U|
40 | Chapter 4:Using the Accelerometer
IBOutlet UIProgressView *xBar;
IBOutlet UIProgressView *yBar;
IBOutlet UIProgressView *zBar;
UIAccelerometer *accelerometer;
}
@end
Heie we ueclaie that the class implements the UIAccelerometer uelegate piotocol.
Make suie you`ve saveu youi changes anu click on the coiiesponuing Accc|cronctcr-
\icwContro||cr.n implementation lile to open it in the Xcoue euitoi. You uon`t actually
have to uo veiy much heie, as Inteilace Builuei hanuleu most ol the heavy lilting Ly
auuing coue to piopeily hanule the usei inteilace elements. Heie`s what the lile shoulu
look like when you aie uone:
#import "AccelerometerViewController.h"
@implementation AccelerometerViewController
- (void)viewDidLoad {
Iigurc 1-3. Connccting thc U| c|cncnts to your codc in |ntcrjacc Bui|dcr
Writing an Accelerometer Application | 41
accelerometer = [UIAccelerometer sharedAccelerometer];
accelerometer.updateInterval = 0.1;
accelerometer.delegate = self;
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload
{
[xBar release];
xBar = nil;
[yBar release];
yBar = nil;
[zBar release];
zBar = nil;
[xLabel release];
xLabel = nil;
[yLabel release];
yLabel = nil;
[zLabel release];
zLabel = nil;
[super viewDidUnload];
}
- (void)dealloc {
[xLabel release];
[yLabel release];
[zLabel release];
[xBar release];
[yBar release];
[zBar release];
accelerometer.delegate = nil;
[accelerometer release];
[super dealloc];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation {

return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark UIAccelerometerDelegate Methods
- (void)accelerometer:(UIAccelerometer *)meter
didAccelerate:(UIAcceleration *)acceleration
{
xLabel.text = [NSString stringWithFormat:@"%f", acceleration.x];
xBar.progress = ABS(acceleration.x);
42 | Chapter 4:Using the Accelerometer
yLabel.text = [NSString stringWithFormat:@"%f", acceleration.y];
yBar.progress = ABS(acceleration.y);
zLabel.text = [NSString stringWithFormat:@"%f", acceleration.z];
zBar.progress = ABS(acceleration.z);
}
@end
The UIAccelerometer is a singleton oLject, so we giaL a ieleience to the singleton
iathei than allocate anu initialize a new instance ol the class.
Ve set the upuate inteival to 0.1, hence the accelerometer:didAccelerate: methou
will Le calleu 10 times eveiy seconu.
Ve ueclaie that this class is the uelegate loi the UIAccelerometer.
Ve implement the accelerometer:didAccelerate: uelegate methou anu use it to set
the X, Y, anu Z laLels to the iaw acceleiometei ieauings each time it is calleu. The
piogiess Lai values aie set to the aLsolute value (the value without iegaiu to sign)
ol the acceleiometei ieauing.
OK, you`ie uone. Beloie you click the Run Lutton, make suie you`ve conliguieu the
pioject to ueploy onto youi iPhone oi iPou touch to test it. Since this application makes
use ol the acceleiometei, anu iPhone Simulatoi uoesn`t have one, you`ie going to have
to test it uiiectly on the uevice.
Il all goes well, you shoulu see something that looks a lot like Figuie +-+.
Determining Device Orientation
Apple pioviue an easy way ol ueteimining the uevice oiientation, a call to UIDevice will
ietuin the cuiient oiientation ol the uevice:
UIDevice *device = [UIDevice currentDevice];
UIDeviceOrientation orientation = device.orientation;
This call will ietuin a UIDeviceOrientation that can Le: UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait, UIDeviceOrientationPortraitUpsideDown, UIDeviceOr
ientationLandscapeLeft, UIDeviceOrientationLandscapeRight oi UIDeviceOrientation
FaceUp. The sensoi unueilying this call is the acceleiometei, anu you`ll see latei in this
chaptei how to ietiieve the uevice oiientation uiiectly liom the iaw acceleiometei
ieauings.
As ol the time ol wiiting unuei iOS +.3 the uevice uoes not coiiectly
iepoit a piopei oiientation when youi application is liist launcheu, with
UIDevice ietuining null when gueiieu.
Determining Device Orientation | 43
Lets go aheau anu mouily the Acceleiometei application to uisplay the uevice oiienta-
tion. Click on the Accc|cronctcr\icwContro||cr.h inteilace lile to open it in the Stanuaiu
Euitoi anu auu the lollowing coue, highlighteu Lelow, to the class inteilace:
@interface AccelerometerViewController :
UIViewController <UIAccelerometerDelegate> {
IBOutlet UILabel *xLabel;
IBOutlet UILabel *yLabel;
IBOutlet UILabel *zLabel;
IBOutlet UIProgressView *xBar;
IBOutlet UIProgressView *yBar;
IBOutlet UIProgressView *zBar;
IBOutlet UILabel *orientationLabel;
UIAccelerometer *accelerometer;
}
- (NSString *)stringFromOrientation:(UIDeviceOrientation) orientation;
@end
Iigurc 1-1. Thc Accc|cronctcr app|ication running on an iPhonc 1 sitting jacc-up on ny dcs|,
ncasuring a 1-gravity accc|cration straight down
44 | Chapter 4:Using the Accelerometer
Ve`ie going to uisplay the cuiient oiientation using in a UILabel, so we`ie going to have
to wiite a convenience methou stringFromOrienation: to conveit the UIDeviceOrienta
tion type ietuineu Ly the UIDevice to an NSString to uisplay in that laLel.
Make suie you`ve saveu youi changes, anu click on the coiiesponuing Accc|cronctcr-
\icwContro||cr.n implementation lile anu auu the lollowing methou:
- (NSString *)stringFromOrientation:(UIDeviceOrientation) orientation {
NSString *orientationString;
switch (orientation) {
case UIDeviceOrientationPortrait:
orientationString = @"Portrait";
break;
case UIDeviceOrientationPortraitUpsideDown:
orientationString = @"Portrait Upside Down";
break;
case UIDeviceOrientationLandscapeLeft:
orientationString = @"Landscape Left";
break;
case UIDeviceOrientationLandscapeRight:
orientationString = @"Landscape Right";
break;
case UIDeviceOrientationFaceUp:
orientationString = @"Face Up";
break;
case UIDeviceOrientationFaceDown:
orientationString = @"Face Down";
break;
case UIDeviceOrientationUnknown:
orientationString = @"Unknown";
break;
default:
orientationString = @"Not Known";
break;
}
return orientationString;
}
Once you have auueu the stringFromOrienation: methou, auu the lollowing coue,
highlighteu Lelow, to the existing accelerometer:didAccelerate: methou in the same
class:
- (void)accelerometer:(UIAccelerometer *)meter
didAccelerate:(UIAcceleration *)acceleration {
xLabel.text = [NSString stringWithFormat:@"%f", acceleration.x];
xBar.progress = ABS(acceleration.x);
yLabel.text = [NSString stringWithFormat:@"%f", acceleration.y];
yBar.progress = ABS(acceleration.y);
zLabel.text = [NSString stringWithFormat:@"%f", acceleration.z];
zBar.progress = ABS(acceleration.z);
Determining Device Orientation | 45
UIDevice *device = [UIDevice currentDevice];
orientationLabel.text = [self stringFromOrientation:device.orientation];
}
Make suie you`ve saveu youi changes, anu click on the Accc|cronctcr\icwContro|-
|cr.xib lile to open it in Inteilace Builuei. Diag anu uiop a UILabel liom the OLject
LiLiaiy into the View. Go aheau anu iesize anu centei up the text using the AttiiLutes
inspectoi liom the Utilities panel.
Close the Utilities panel anu open the Assistant Euitoi, which shoulu show the coiie-
sponuing inteilace lile loi the view contiollei. Contiol-click anu uiag anu connect the
UILabel element to the orientationLabel outlet in youi coue, as in Figuie +-5.
Save youi changes, anu click Run Lutton in the Xcoue toolLai to compile anu ueploy
youi application to youi uevice. Il all goes well you shoulu see something much like
Figuie +-6. As you move the uevice aiounu, the laLel will upuate itsell to iellect the
cuiient uevice oiientation.
Determining Device Orientation Directly Using the Accelerometer
Insteau ol gueiying UIDevice you can use the iaw acceleiometei ieauings to ueteimine
the uevice oiientation uiiectly using the atan2 lunction as shown Lelow:
Iigurc 1-5. Connccting thc oricntation out|ct to thc U|
46 | Chapter 4:Using the Accelerometer
float x = -[acceleration x];
float y = [acceleration y];
float angle = atan2(y, x);
Foi any ieal aiguments x anu y that aie not Loth egual to zeio, atan2(y,
x) is the angle in iauians Letween the positive x-axis ol a plane anu the
point given Ly the specilieu cooiuinates on it. The angle is positive loi
countei-clockwise angles, anu negative loi clockwise angles.
Let`s go aheau anu mouily the accelerometer:didAccelerate: methou to calculate the
oiientation. Click on the Accc|cronctcr\icwContro||cr.n implementation lile to open
it in the Stanuaiu Euitoi anu ieplace these lines:
UIDevice *device = [UIDevice currentDevice];
orientationLabel.text = [self stringFromOrientation:device.orientation];
with the coue highlighteu Lelow:
- (void)accelerometer:(UIAccelerometer *)meter
didAccelerate:(UIAcceleration *)acceleration {
xLabel.text = [NSString stringWithFormat:@"%f", acceleration.x];
xBar.progress = ABS(acceleration.x);
Iigurc 1-. Thc Accc|cronctcr app|ication rcporting thc dcvicc oricntation
Determining Device Orientation | 47
yLabel.text = [NSString stringWithFormat:@"%f", acceleration.y];
yBar.progress = ABS(acceleration.y);
zLabel.text = [NSString stringWithFormat:@"%f", acceleration.z];
zBar.progress = ABS(acceleration.z);
float x = -[acceleration x];
float y = [acceleration y];
float angle = atan2(y, x);
if(angle >= 2.25 && angle <= 0.75) {
orientationLabel.text =
[self stringFromOrientation:UIInterfaceOrientationPortrait];
} else if(angle >= 0.75 && angle <= 0.75){
orientationLabel.text =
[self stringFromOrientation:UIInterfaceOrientationLandscapeRight];
} else if(angle >= 0.75 && angle <= 2.25) {
orientationLabel.text =
[self
stringFromOrientation:UIInterfaceOrientationPortraitUpsideDown];
} else if(angle <= 2.25 || angle >= 2.25) {
orientationLabel.text =
[self stringFromOrientation:UIInterfaceOrientationLandscapeLeft];
}
}
Il you save youi changes, anu click on the Run Lutton to ieLuilu anu ueploy youi
application onto youi uevice, theie shoulu see little oi no change in the application`s
opeiation. Howevei, having access to each component ol the oiientation opens up
many oppoitunities loi cieating tilt-Laseu contiols.
Obtaining Notifications when Device Orientation Changes
In auuition to uiiectly gueiying the UIDevice oLject loi the cuiient oiientation, a pio-
giam can ieguest to Le notilieu ol changes in the uevice`s oiientation Ly iegisteiing
itsell as an oLseivei.
Ve can once again mouily the Acceleiometei application to make use ol this leatuie.
Open the Accc|cronctcr\icwContro||cr.n lile in the Stanuaiu Euitoi anu uelete the coue
auueu in the pievious section liom the accelerometer:didAccelerate: methou.
Il you guickly ieLuilu the application at this point anu ueploy it to youi uevice you will
see that the UILabel now ieaus LaLel anu will no longei Le upuateu as the uevice
oiientation changes.
Once you`ve conliimeu that, auu the lollowing methou:
-(void) viewWillAppear:(BOOL) animated{
[super viewWillAppear:animated];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

[[NSNotificationCenter defaultCenter]
48 | Chapter 4:Using the Accelerometer
addObserver:self
selector:@selector(receivedRotation:)
name:UIDeviceOrientationDidChangeNotification
object:nil];

}
Heie we ask the UIDevice class to stait geneiating oiientation notilications, anu we
iegistei the view contiollei as an oLseivei. Next auu the selectoi methou, shown Lelow:
-(void) receivedRotatation:(NSNotification*) notification {
UIDevice *device = [UIDevice currentDevice];
orientationLabel.text = [self stringFromOrientation:device.orientation];
}
Heie we simply upuate the UILabel with the uevice oiientation eveiy time a UIDevi
ceOrientationDidChangeNotification event is ieceiveu.
Finally we neeu to iememLei to iemove the piogiam as an oLseivei to stop the genei-
ation ol messages uuiing the teai uown ol oui view contiollei. Auu the lollowing
methou to youi coue:
-(void) viewWillDisappear:(BOOL) animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver: self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}
Il you once again save youi changes anu click on the Run Lutton to ieLuilu anu ueploy
the application to youi uevice, you will again see little oi no change in the application`s
opeiation.
Which Way Is Up?
A uselul thing to know a lot ol the time is the answei to the guestion which way is
up? You can use the same methou useu eailiei to ueteimine the uevice oiientation anu
giaphically show this in the View.
Fiist you`ie going to neeu an image ol an aiiow. Downloau, oi uiaw in the giaphics
package ol youi choice, an image ol an aiiow pointing to the lelt on a tianspaient
Lackgiounu. Save it as, oi conveit it to, a PNG loimat lile. Diag-anu-uiop this into
youi Xcoue Pioject iememLeiing to tick the Copy items into uestination gioup`s loluei
(il neeueu) check Lox in the pop up uialog that appeais when you uiop the liles into
Xcoue (see Figuie +-7).
Click on the Accc|cronctcr\icwContro||cr.xib lile to open it, anu uiag-anu-uiop a UII
mageView liom the OLject LiLiaiy onto youi View. Position it Lelow the thiee UIProg
ressBar elements, anu iesize the Lounuing Lox to Le a sguaie using the Size inspectoi
ol the Utility Pane. In the AttiiLutes inspectoi ol the Utility Pane, change the Image
piopeity to Le the aiiow image that you auueu to youi pioject. Set the View moue to
Le Aspect Fit. Uncheck the Opague Lox in the Diawing section so that the aiiow
Determining Device Orientation | 49
is ienueieu coiiectly with a tianspaient Lackgiounu. Finally, use the Image uiop-
uown to select the aiiow.png image to Le uisplayeu in the UIImageView (see Figuie +-S).
Close the Utility Pane anu open the Assistant Euitoi. Contiol-click anu uiag liom the
UIImageView in youi View to the arrowImage outlet in the Assistant Euitoi, as in Fig-
uie +-9, anu auu an arrrowImage outlet.
Altei uoing so youi inteilace lile shoulu look as Lelow:
@interface AccelerometerViewController :
UIViewController <UIAccelerometerDelegate> {
IBOutlet UILabel *xLabel;
IBOutlet UILabel *yLabel;
IBOutlet UILabel *zLabel;
IBOutlet UIProgressView *xBar;
IBOutlet UIProgressView *yBar;
IBOutlet UIProgressView *zBar;
IBOutlet UIImageView *arrowImage;
IBOutlet UILabel *orientationLabel;
UIAccelerometer *accelerometer;
Iigurc 1-7. Adding an arrow inagc to thc Accc|cronctcr projcct
50 | Chapter 4:Using the Accelerometer
}
Close the Assistant Euitoi anu switch to the Stanuaiu Euitoi. Go aheau anu click on
the Accc|cronctcr\icwContro||cr.n implementation lile. Auu the coue highlighteu Le-
low to the accelerometer:didAccelerate: methou:
- (void)accelerometer:(UIAccelerometer *)meter
didAccelerate:(UIAcceleration *)acceleration {
xLabel.text = [NSString stringWithFormat:@"%f", acceleration.x];
xBar.progress = ABS(acceleration.x);
yLabel.text = [NSString stringWithFormat:@"%f", acceleration.y];
yBar.progress = ABS(acceleration.y);
zLabel.text = [NSString stringWithFormat:@"%f", acceleration.z];
zBar.progress = ABS(acceleration.z);
float x = -[acceleration x];
float y = [acceleration y];
float angle = atan2(y, x);
[arrowImage setTransform:CGAffineTransformMakeRotation(angle)];
}
Iigurc 1-8. Adding thc U||nagc\icw to your intcrjacc
Determining Device Orientation | 51
That`s it. Save youi changes again anu click on the Run Lutton to compile anu ueploy
the application to youi uevice. Keep the uevice lace towaius you anu iotate it in llat
plane, you shoulu see that the aiiow moves as you uo so, keeping its oiientation point-
ing upwaius (see Figuie +-9).
Convenience Methods for Orientation
Apple pioviues convenience methous to ueteimine whethei the cuiient uevice oiien-
tation is poitiait:
UIDevice *device = [UIDevice currentDevice];
UIDeviceOrientation orientation = device.orientation;
BOOL portrait = UIDeviceOrientationIsPortrait( orientation );
oi lanuscape:
BOOL landscape = UIDeviceOrientationIsLandscape( orientation );
These methous ietuin YES il the uevice is in poitiait oi lanuscape moue iespectively;
otheiwise they ietuin NO.
Iigurc 1-9. Adding a out|ct to your codc
52 | Chapter 4:Using the Accelerometer
Detecting Shaking
Apple`s shake-uetection algoiithm analyses eight to ten successive paiis ol iaw accel-
eiometei tiiplet values anu ueteimines the angle Letween these ieauings. Il the change
in angulai velocity Letween successive uata points is laige then the algoiithm uetei-
mines that a UIEventSubtypeMotionShake has occuiieu, anu the motionBegan:withE
vent: uelegate methou is calleu. Conveisely, il the change in angulai velocity is small
anu a shake event has Leen tiiggeieu, the motionEnded:withEvent: uelegate methou is
calleu.
The iPhone is Lettei at uetecting siue-to-siue iathei than liont-to-Lack
oi up-anu-uown motions. Take this into account in the uesign ol youi
application.
Theie aie thiee motion uelegate methous, miiioiing the methous loi gestuie hanuling:
motionBegin:withEvent:, motionEnded:withEvent: anu motionCancelled:withEvent:.
The liist inuicates the stait ol a motion event, the seconu the enu ol this event. You
cannot geneiate a new motion event loi a seconu (oi two) lollowing the liist event. The
Iigurc 1-10. Thc arrow points upwards (dcvicc hc|d vcrtica||y in jront oj thc uscr)
Detecting Shaking | 53
linal uelegate methou is calleu when a motion is inteiiupteu Ly a system event, such
as an incoming phone call.
Let`s go aheau anu auu shake uetection to oui Acceleiometei application. You`ll neeu
to auu anothei UILabel to the UI that will change uepenuing on the motion event status.
Click on the Accc|cronctcr\icwContro||cr.h inteilace lile to open it in the Stanuaiu
Euitoi anu auu anothei UILabel maikeu as an IBOutlet to the class uelinition:
@interface AccelerometerViewController : UIViewController <UIAccelerometerDelegate> {
IBOutlet UILabel *xLabel;
IBOutlet UILabel *yLabel;
IBOutlet UILabel *zLabel;
IBOutlet UIProgressView *xBar;
IBOutlet UIProgressView *yBar;
IBOutlet UIProgressView *zBar;
IBOutlet UILabel *orientationLabel;
IBOutlet UILabel *shakeLabel;
IBOutlet UIImageView *arrowImage;
UIAccelerometer *accelerometer;
}
Save youi changes anu click on the Accc|cronctcr\icwContro||cr.n implementation
lile to open it in the Xcoue euitoi.
The easiest way to ensuie that the view contiollei ieceives motion events is to piomote
it to Fiist Responuei in the viewDidAppear: methou. RememLei to make the contiollei
iesign as liist iesponuei when the view goes away. Auu the viewDidAppear: methou anu
mouily the existing viewWillDisappear: methou as highlighteu Lelow. Use the canBe
comeFirstResponder methou to inuicate that the view contiollei can inueeu Lecome the
Fiist Responuei:
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
-(void) viewWillDisappear: (BOOL) animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver: self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[self resignFirstResponder];
}
54 | Chapter 4:Using the Accelerometer
Save youi changes anu click on the Accc|cronctcr\icwContro||cr.xib lile loi the last
time. Diag-anu-uiop a UILabel into the View liom the OLject LiLiaiy anu connect it
to the shakeLabel outlet as in Figuie +-11.
Save youi changes anu ietuin to the Accc|cronctcr\icwContro||cr.n lile in the euitoi,
anu auu the lollowing uelegate methous to the implementation:
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if ( motion == UIEventSubtypeMotionShake ) {
shakeLabel.text = @"SHAKE";
shakeLabel.textColor = [UIColor redColor];
}
return;
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if ( motion == UIEventSubtypeMotionShake ) {
shakeLabel.text = @"NO SHAKE";
shakeLabel.textColor = [UIColor greenColor];
}
return;
}
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if ( motion == UIEventSubtypeMotionShake ) {
Iigurc 1-11. Connccting thc sha|cLabc| out|ct
Detecting Shaking | 55
shakeLabel.text = @"SHAKE CANCELLED";
shakeLabel.textColor = [UIColor blackColor];
}
return;
}
Save youi changes anu click on the Run Lutton in the Xcoue toolLai. Altei the appli-
cation is Luilt anu ueployeu to youi uevice, tiy shaking the phone. You shoulu see
something veiy much like Figuie +-12.
Iigurc 1-12. Sha|c dctcction on thc iPhonc
56 | Chapter 4:Using the Accelerometer
CHAPTER 5
Using the Magnetometer
The magnetometei is a magnetoiesistive peimalloy sensoi lounu in the iPhone 3GS,
iPhone + anu iPau 2, in auuition to the acceleiometei. The iPhone 3GS uses the AN-203
integiateu ciicuit piouuceu Ly Honeywell, while the iPhone + anu iPau 2 make use ol
the newei AKMS975 piouuceu Ly AKM Semiconuuctoi. The sensoi is locateu towaius
the top iight hanu coinei ol the uevice, anu measuies lielus within a 2 gauss (200
miciotesla) iange, anu is sensitive to magnetic lielus ol less than 100 miciogauss (0.01
miciotesla).
The Eaith`s magnetic lielu is ioughly 0.6 gauss (60 miciotesla). The lielu
aiounu a iaie eaith magnet can Le 1+,000 gauss oi moie.
The magnetometei measuies the stiength ol the magnetic lielu suiiounuing the uevice.
In the aLsence ol any stiong local lielus, these measuiements will Le ol the amLient
magnetic lielu ol the Eaith, allowing the uevice to ueteimine its heauing with iespect
to the geomagnetic Noith Pole anu act as a uigital compass. The geomagnetic heauing
anu tiue heauing ielative to the geogiaphical Noith Pole can vaiy wiuely, Ly seveial
tens ol uegiees uepenuing on youi location.
About the Magnetometer
ComLining the heauing (yaw) inloimation (see Figuie 5-1) ietuineu Ly this uevice with
the ioll anu pitch inloimation ietuineu Ly the acceleiometei will let you ueteimine the
tiue oiientation ol the uevice in ieal time.
As well as iepoiting the cuiient location, the CLLocationManager class can, in the case
wheie the haiuwaie suppoits it, iepoit the cuiient heauing ol the uevice. Il location
upuates aie also enaLleu, the location managei ietuins Loth tiue heauing anu magnetic
heauing values. Il location upuates aie not enaLleu, the location managei ietuins only
the magnetic heauing value.
57
Magnetic heauing upuates aie availaLle even il the usei has switcheu oll
location upuates in the Settings application. Auuitionally, useis aie
QRW piompteu to give peimission to use heauing uata, as it is assumeu
that magnetic heauing inloimation cannot compiomise usei piivacy.
On an enaLleu uevice the magnetic heauing uata shoulu theieloie al-
ways Le availaLle to youi application.
As mentioneu pieviously, the magnetometei ieauings will Le allecteu Ly local magnetic
lielus, so the CLLocationManager may attempt to caliLiate its heauing ieauings Ly uis-
Iigurc 5-1. Using thc nagnctonctcr (a.|.a. thc digita| conpass) in thc iPhonc 3GS you can dctcrninc
thc hcading (yaw) oj thc dcvicc
58 | Chapter 5:Using the Magnetometer
playing a heauing caliLiation panel (see Figuie 5-2) Leloie it staits to issue upuate
messages.
Howevei, Leloie it uoes so it will call the locationManagerShouldDisplayHeadingCali
bration: uelegate methou:
- (BOOL)locationManagerShouldDisplayHeadingCalibration:
(CLLocationManager *)manager {
return YES;
}
Il you ietuin YES liom this methou, the CLLocationManager will pop up the caliLiation
panel on top ol the cuiient winuow. The caliLiation panel piompts the usei to move
the uevice in a liguie-eight pattein so that Coie Location can uistinguish Letween the
Eaith`s magnetic lielu anu any local magnetic lielus. The panel will iemain visiLle until
caliLiation is complete oi until you uismiss it Ly calling the dismissHeadingCalibra
tionDisplay: methou in the CLLocationManager class.
Writing a Magnetometer Application
Let`s go aheau anu implement a simple view-Laseu application to illustiate how to use
the magnetometei. Open Xcoue anu stait a new iPhone pioject, select a View-Laseu
Application template, anu name the pioject Compass when piompteu loi a lilename.
Iigurc 5-2. Thc Hcading Ca|ibration Panc|
Writing a Magnetometer Application | 59
Since you`ll Le making use ol the Coie Location liamewoik, the liist thing you neeu to
uo is auu it to oui new pioject. Click on the Compass pioject lile in the Pioject navigatoi
winuow on the iight in Xcoue, select the Taiget anu click on the Builu Phases taL, click
on the Link with LiLiaiies uiop uown anu click on the - Lutton to open the lile pop-
up winuow. Select CorcLocation.jrancwor| liom the list ol availaLle liamewoiks anu
click the Auu Lutton.
You`ie going to Luilu an application that will act as a compass, so you`ie going to neeu
an image ol an aiiow to act as the compass neeule. Downloau oi uiaw in the giaphics
package ol youi choice, an image ol an aiiow pointing upwaius on a tianspaient Lack-
giounu. Save oi conveit it to, a PNG loimat lile. Diag-anu-uiop this into the Xcoue
Pioject, iememLeiing to tick the Copy items into uestination gioup`s loluei (il nee-
ueu) check Lox in the pop up uialog that appeais when you uiop the liles into Xcoue.
Click on Conpass\icwContro||cr.xib lile to open it in Inteilace Builuei. Diag anu uiop
a UIImageView liom the OLject LiLiaiy into the View, positioning it ioughly in the centei
ol youi winuow, iesizing the Lounuing Lox to Le a sguaie, as in Figuie 5-3. In the
AttiiLutes inspectoi ol the Utilities pane set the View moue to Le Aspect Fit, uncheck
the Opague checkLox in the Diawing section, anu select the aiiow image that you
auueu to youi pioject in the Image uiop uown.
Next uiag-anu-uiop loui UILabel elements liom the OLject LiLiaiy into the View, po-
sition the loui laLels as in Figuie 5-3, anu change the text in the lelt most two to ieau
Magnetic Heauing: anu Tiue Heauing:.
Close the Utility pane anu switch liom the Stanuaiu to the Assistant Euitoi. Contiol-
Click anu uiag liom the two iight most UILabel elements to the assistant euitoi to cieate
a magneticHeadingLabel anu trueHeadingLabel outlet, anu then again loi the UIImage
View to cieate an arrowImage outlet, see Figuie 5-3.
Then click on the Conpass\icwContro||cr.h inteilace lile anu go aheau anu ueclaie the
class as a CLLocationManagerDelegate, iememLeiing to impoit the CorcLocation.h
heauei lile. Altei uoing so the inteilace shoulu look like this:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface CompassViewController : UIViewController
<CLLocationManagerDelegate> {
IBOutlet UIImageView *arrowImage;
IBOutlet UILabel *magneticHeadingLabel;
IBOutlet UILabel *trueHeadingLabel;
}
@end
Save youi changes, anu click on the coiiesponuing Conpass\icwContro||cr.n imple-
mentation lile. Uncomment the viewDidLoad methou anu the lollowing coue to the
60 | Chapter 5:Using the Magnetometer
implementation. This will cieate an instance ol the CLLocationManager class, anu will
senu Loth location anu heauing upuate messages to the uesignateu uelegate class:
- (void)viewDidLoad {
[super viewDidLoad];
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if( [CLLocationManager locationServicesEnabled] &&
[CLLocationManager headingAvailable]) {
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
} else {
NSLog(@"Can't report heading");
}
}
It is moie impoitant to check whethei heauing inloimation is availaLle than it is to
check whethei location seivices aie availaLle. The availaLility ol heauing inloima-
tion is iestiicteu to the latest geneiation ol uevices.
You can (optionally) liltei the heauing upuate messages using an angulai liltei. Changes
in heauing ol less than this amount will not geneiate an upuate message to the uelegate,
loi example:
locationManager.headingFilter = 5; // 5 degrees
Iigurc 5-3. Connccting thc out|cts to thc U| c|cncnts in |ntcrjacc Bui|dcr
Writing a Magnetometer Application | 61
The uelault value ol this piopeity is kCLHeadingFilterNone. You shoulu use this value
il you want to Le notilieu ol all heauing upuates. In this example, leave the liltei set to
the uelault value. Howevei il you want to liltei messages liom Coie Location this way,
auu the aLove line to youi viewDidLoad methou insiue the il-Llock:
if( [CLLocationManager locationServicesEnabled] &&
[CLLocationManager headingAvailable]) {
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];
locationManager.headingFilter = 5; // 5 degrees
} else {
... code ...
}
The CLLocationManagerDelegate piotocol calls the locationManager:didUpdateHead
ing: uelegate methou when the heauing is upuateu. You`ie going to use this methou
to upuate the usei inteilace. Auu the lollowing coue to youi view contiollei:
- (void)locationManager:(CLLocationManager*)manager
didUpdateHeading:(CLHeading*)newHeading {
if (newHeading.headingAccuracy > 0) {
float magneticHeading = newHeading.magneticHeading;
float trueHeading = newHeading.trueHeading;
magneticHeadingLabel.text =
[NSString stringWithFormat:@"%f", magneticHeading];
trueHeadingLabel.text =
[NSString stringWithFormat:@"%f", trueHeading];
float heading = 1.0f * M_PI * newHeading.magneticHeading / 180.0f;
arrowImage.transform = CGAffineTransformMakeRotation(heading);
}
}
Il location upuates aie also enaLleu, the location managei ietuins Loth tiue heauing
anu magnetic heauing values. Il location upuates aie not enaLleu, oi the location ol
the uevice is not yet known, the location managei ietuins only the magnetic heauing
value anu the value ietuineu Ly this call will Le -1.
Save youi changes, then click on the Run Lutton in the Xcoue toolLai to ueploy youi
new application to youi uevice. Il you holu the uevice in Face Up oi Poitiait moue
you shoulu see something veiy similai to Figuie 5-+ Lelow.
As it stanus oui application has a ciitical llaw. Il the usei oiientates the uevice into
Lanuscape Moue, the iepoiteu heauings will Le incoiiect, oi at least look incoiiect to
the usei.
Determining the Heading in Landscape Mode
The magnetic anu tiue heauings aie coiiect when the iPhone uevice is helu like a tia-
uitional compass, in poitiait moue, il the usei iotates the uevice, the heauing ieauings
62 | Chapter 5:Using the Magnetometer
will still Le in the oiiginal liame ol ieleience. Even though the usei has not changeu
the uiiection they aie lacing the heauing values iepoiteu Ly the uevice will have
changeu. You`ie going to have to coiiect loi oiientation Leloie iepoiting heauings Lack
to the usei, see Figuie 5-5.
In the Pioject navigatoi, click on the Conpass\icwContro||cr.xib lile to open it in In-
teilace Builuei, then uiag-anu-uiop anothei UILabel liom the OLject LiLiaiy in the
Utility pane into the View winuow. Use the Assistant Euitoi connect the laLel to a new
outlet in the Conpass\icwContro||cr.h inteilace lile, as in Figuie 5-6.
Altei uoing so, the inteilace lile shoulu look as Lelow:
@interface CompassViewController :
UIViewController <CLLocationManagerDelegate> {
IBOutlet UILabel *trueHeadingLabel;
IBOutlet UILabel *magneticHeadingLabel;
IBOutlet UILabel *orientationLabel;
IBOutlet UIImageView *arrowImage;
}
Ve`ie going to use this to iepoit the cuiient uevice oiientation as we uiu in the Accel-
eiometei application in Chaptei +.
Iigurc 5-1. Thc Conpass app|ication running on thc iPhonc 3GS
Writing a Magnetometer Application | 63
Close the Assistant Euitoi anu ieopen the Conpass\icwContro||cr.h inteilace lile in the
Stanuaiu Euitoi. Go aheau anu auu the lollowing convenience methous to the class
uelinition:
- (float)magneticHeading:(float)heading
fromOrientation:(UIDeviceOrientation) orientation;
- (float)trueHeading:(float)heading
fromOrientation:(UIDeviceOrientation) orientation;
- (NSString *)stringFromOrientation:(UIDeviceOrientation) orientation;
Save youi changes, anu open the Conpass\icwContro||cr.n implementation lile. Since
the CLHeading oLject is ieau only anu you can`t mouily it uiiectly, you`l neeu to auu the
lollowing methou to coiiect the magnetic heauing loi the uevice oiientation:
- (float)magneticHeading:(float)heading
fromOrientation:(UIDeviceOrientation) orientation {
Iigurc 5-5. Thc rca| hcading oj thc uscr whcn thcy arc ho|ding thc dcvicc in Landscapc nodc is thc
rcportcd hcading - 90 dcgrccs
64 | Chapter 5:Using the Magnetometer
float realHeading = heading;
switch (orientation) {
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
realHeading = realHeading + 180.0f;
break;
case UIDeviceOrientationLandscapeLeft:
realHeading = realHeading + 90.0f;
break;
case UIDeviceOrientationLandscapeRight:
realHeading = realHeading - 90.0f;
break;
default:
break;
}
while ( realHeading > 360.0f ) {
realHeading = realHeading - 360;
}
return realHeading;
}
Iigurc 5-. Connccting thc oricntation |abc| in |ntcrjacc Bui|dcr
Writing a Magnetometer Application | 65
The UIDeviceOiientationFaceUp anu UIDeviceOiientationFaceDown oiientation
cases aie unuelineu anu the usei is piesumeu to Le holuing the uevice in UIDevi-
ceOiientationPoitiait moue.
You will also neeu to auu a coiiesponuing methou to coiiect the tiue heauing:
- (float)trueHeading:(float)heading
fromOrientation:(UIDeviceOrientation) orientation {
float realHeading = heading;
switch (orientation) {
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
realHeading = realHeading + 180.0f;
break;
case UIDeviceOrientationLandscapeLeft:
realHeading = realHeading + 90.0f;
break;
case UIDeviceOrientationLandscapeRight:
realHeading = realHeading - 90.0f;
break;
default:
break;
}
while ( realHeading > 360.0f ) {
realHeading = realHeading - 360;
}
return realHeading;
}
Finally, auu the stringFromOrientation: methou liom the pievious section Chap-
tei 5. Ve`ll use this to upuate the orientationLabel outlet:
- (NSString *)stringFromOrientation:(UIDeviceOrientation) orientation {
NSString *orientationString;
switch (orientation) {
case UIDeviceOrientationPortrait:
orientationString = @"Portrait";
break;
case UIDeviceOrientationPortraitUpsideDown:
orientationString = @"Portrait Upside Down";
break;
case UIDeviceOrientationLandscapeLeft:
orientationString = @"Landscape Left";
break;
case UIDeviceOrientationLandscapeRight:
orientationString = @"Landscape Right";
break;
case UIDeviceOrientationFaceUp:
orientationString = @"Face Up";
break;
case UIDeviceOrientationFaceDown:
orientationString = @"Face Down";
66 | Chapter 5:Using the Magnetometer
break;
case UIDeviceOrientationUnknown:
orientationString = @"Unknown";
break;
default:
orientationString = @"Not Known";
break;
}
return orientationString;
}
Retuin to the locationManager:didUpdateHeading: uelegate methou anu mouily the
lines highlighteu Lelow to use the new methous anu upuate the heauings uepenuing
on the uevice oiientation:
- (void)locationManager:(CLLocationManager*)manager
didUpdateHeading:(CLHeading*)newHeading {
UIDevice *device = [UIDevice currentDevice];
orientationLabel.text = [self stringFromOrientation:device.orientation];
if (newHeading.headingAccuracy > 0) {
float magneticHeading = [self magneticHeading:newHeading.magneticHeading
fromOrientation:device.orientation];
float trueHeading = [self trueHeading:newHeading.trueHeading
fromOrientation:device.orientation];
magneticHeadingLabel.text =
[NSString stringWithFormat:@"%f", magneticHeading];
trueHeadingLabel.text = [NSString stringWithFormat:@"%f", trueHeading];
float heading = 1.0f * M_PI * newHeading.magneticHeading / 180.0f;
arrowImage.transform = CGAffineTransformMakeRotation(heading);
}
}
You shoulu still use the uiiectly iepoiteu newHeading.magneticHeading loi the com-
pass neeule iathei than the aujusteu heauing. Otheiwise the compass will not point
coiiectly.
Make suie you`ve saveu all the changes to the implementation lile anu click on the Run
Lutton in the Xcoue toolLai to ueploy the application onto the uevice. Il all goes well
you shoulu see the same compass uisplay as Leloie. Howevei this time il you iotate the
uisplay, sees Figuie 5-7, the heauing values shoulu Le the same iiiespective ol the uevice
oiientation.
Although I have not uiscusseu oi implementeu it heie, il the CLLocationManager oLject
encounteis an eiioi, it will call the locationManager:didFailWithError: uelegate
methou:
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {

if ([error code] == kCLErrorDenied) {
Writing a Magnetometer Application | 67
// User has denied the application's request to use location services.
[manager stopUpdatingHeading];
} else if ([error code] == kCLErrorHeadingFailure) {
// Heading could not be determined
}
}
Measuring a Magnetic Field
To use the uevice to measuie a magnetic lieluloi instance that ol a small Lai magnet,
oi the lielu geneiateu Ly an electiic cuiient in a wiieyou shoulu liist make a zeio-
point measuiement ol the amLient magnetic lielu ol the Eaith. Fuithei ieauings shoulu
suLtiact this zeio-point measuiement.
Vhen measuiing, move the magnet to the uevice iathei than moving the uevice to the
magnet. Moving the uevice will cause the magnetic lielu ol the Eaith acioss the meas-
uiing sensoi to change, which will spoil the zeio point caliLiation you took eailiei. Il
the uevice must Le moveu, only small movements shoulu Le attempteu.
You can ietiieve the iaw magnetic lielu measuiements along the X, Y anu Z-axes Ly
gueiying the CLHeading oLject passeu to the locationManager:didUpdateHeading:
methou:
Iigurc 5-7. Hcading va|ucs arc now thc sanc irrcspcctivc oj oricntation
68 | Chapter 5:Using the Magnetometer
- (void)locationManager:(CLLocationManager *)manager
didUpdateHeading:(CLHeading *)heading {
double x = heading.x;
double y = heading.y;
double z = heading.z;
double magnitude = sqrt(x*x + y*y + z*z);
... code ...
}
The values ietuineu aie noimalizeu into a 12S iange, measuieu in miciotesla (T),
iepiesenting the ollset liom the magnetic lielu lines measuieu Ly the magnetometei.
Apple pioviues sample coue that uisplays the iaw x, y, anu z magneto-
metei values, a plotteu histoiy ol those values, anu a computeu
magnituue (size oi stiength) ol the magnetic lielu. The coue can Le
uownloaueu liom the iPhone uevelopei weLsite at http://dcvc|opcr.app|c
.con/|ibrary/ios/=sanp|ccodc/Tcs|anctcr.
Measuring a Magnetic Field | 69
CHAPTER 6
Using Core Motion
The iPhone +, latest geneiation iPou touch, anu the iPau have a viLiational gyioscope
in auuition to an acceleiometei anu a magnetometei. The MicioElectioMechanical
(MEMs) gyioscope insiue the iPhone + anu the +th geneiation iPou touch is the AGDS
2032, neaily iuentical to an oll-the-shell STMicioelectionics L3G+200D uevice The
iPau 2 uses an AGDS 2103 sensoi, also liom STMicioelectionics. These mouels opeiate
Ly making use ol a plate calleu a piool mass that oscillates when a uiive signal is
applieu to capacitoi plates. Vhen the usei iotates the phone, the piool mass is uisplaceu
in the X, Y anu Z uiiections anu an ASIC piocessoi measuies the capacitance change
ol the plates. The capacitance vaiiation is useu to uetect the angulai iate applieu to the
package.
An acceleiometei pioviues measuiement ol loices in the X, Y anu Z-axes Lut it cannot
measuie iotation. On the othei hanu, since a gyioscope is a iate ol change uevice, you
aie aLle to measuie the change in iotations aiounu an axis. By using Loth sensois in
comLination you can measuie the movement ol the uevice in a six uegiees-ol-lieeuom
ineitial system, allowing you to use ueau ieckoning to linu the physical location (anu
oiientation ol the uevice) ielative to an initial staiting position.
All ineitial systems have an inheient uiilt, so ueau ieckoning shoulu not
Le iegaiueu as Leing staLle ovei the long teim.
Core Motion
The aiiival ol iOS + Liought with it the new Coie Motion liamewoik; this new liame-
woik allows youi application to ieceive motion uata liom Loth the acceleiometei anu
(on the latest geneiation ol uevices) the gyioscope.
71
Theie is no suppoit loi Coie Motion in the iOS Simulatoi, theieloie all
testing ol youi Coie Motion ielateu coue must Le uone on the uevice.
The coue in this chaptei will only woik on uevices that have a gyioscope,
see Chaptei 1 loi moie inloimation.
Vith the CMMotionManager class you can stait ieceiving acceleiometei, gyioscope, anu
comLineu uevice motion events at a iegulai inteival, oi you can poll them peiiouically:
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
if (!motionManager.isDeviceMotionAvailable) {
NSLog(@"Device supports motion capture.");
}
RememLei to ielease the managei altei you`ie uone with it:
[motionManager release];
The CMMotionManager class olleis Loth the iaw acceleiometei anu gyioscope uata sep-
aiately as well a comLineu CMDeviceMotion oLject that encapsulates the piocesseu uevice
motion uata liom Loth the acceleiometei anu the gyioscope. Vith this comLineu mo-
tion measuiement Coie Motion pioviues highly accuiate measuiements ol uevice at-
tituue, the (unLiaseu) iotation iate ol a uevice, the uiiection ol giavity on a uevice, anu
the acceleiation that the usei is giving to a uevice.
The iotation iate iepoiteu Ly the CMDeviceMotion oLject is uilleient than
that iepoiteu uiiectly Ly the gyioscope. Even il the uevice is sitting llat
on the taLle the gyio will not ieau zeio. It will ieau some non-zeio value
that uilleis liom uevice to uevice anu ovei time uue to changes in things
like uevice tempeiatuie. Coie Motion actively tiacks anu iemoves this
Lias liom the gyio uata.
Pulling Motion Data
The CMMotionManager class olleis two appioaches to oLtaining motion uata. The sim-
plest way is to pull the motion uata. Youi application will stait an instance ol the
managei class anu peiiouically ask loi measuiements ol the comLineu uevice motion:
[motionManager startDeviceMotionUpdates];
CMDeviceMotion *motion = motionManager.deviceMotion;
Although il you aie only inteiesteu in the iaw gyioscope uata (oi acceleiometei uata)
you can also ask loi those uiiectly:
CMGyroData *gyro = motionManager.gyroData;
CMAccelerometerData *accel = motionManager.accelerometerData;
This is the most ellicient methou ol oLtaining motion uata. Howevei, il theie isn`t a
natuial timei in youi applicationsuch as a peiiouic upuate ol youi main viewthen
72 | Chapter 6:Using Core Motion
you may neeu an auuitional timei to tiiggei youi upuate ieguests. RememLei to stop
the upuates anu ielease the motion managei altei you`ie uone with them:
[motionManager stopDeviceMotionUpdates];
[motionManager release];
Youi application shoulu cieate only a single instance ol the CMMotion
Manager class. Multiple instances ol this class can allect the iate at which
an application ieceives uata liom the acceleiometei anu gyioscope.
Pushing Motion Data
Insteau ol using this simple pull methouology, you can specily an upuate inteival anu
implement a Llock ol coue loi hanuling the motion uata. The managei class can then
Le askeu to uelivei upuates using the NSOperationsQueue, which allows the hanulei to
push the measuiements to the application. Foi example:
motionManager.deviceMotionUpdateInterval = 1.0/60.0;
[motionManager startDeviceMotionUpdatesToQueue: queue withHandler: handler];
oi similaily loi the inuiviuual acceleiometei anu gyioscope uata:
[motionManager startAccelerometerUpdatesToQueue:queue withHandler: handler];
[motionManager startGyroUpdatesToQueue:queue withHandler:handler];
Vith this seconu methouology you`ll get a continuous stieam ol motion uata, Lut theie
is a laige incieaseu oveiheau associateu with implementing it (see TaLle 6-1). Youi
application may not Le aLle to keep up with the associateu uata iate especially il the
uevice is in iapiu motion.
Tab|c -1. Exanp|c CPU usagc jor Corc Motion push updatcs at 100 and 20Hz
a
At 100Hz At 20Hz
Total Application Total Application
DeviceMotion 65% 20% 65% 10%
Accelerometer 50% 15% 46% 5%
Accel + Gyro 51% 10% 50% 5%
a
Figures for an application running on an iPhone 4 running iOS 4.0 (Reproduced with permission. Credit: Jeffrey Powers, Occipital)
Using Coie Motion`s comLineu CMDeviceMotion oLject, as opposeu to accessing the iaw
CMAccelerometer oi CMGyroData oLjects, consumes ioughly 15 moie total CPU ie-
gaiuless ol the upuate iate. The goou news is that is not Lecause ol the gyioscope itsell;
ieauing Loth the acceleiometei anu gyioscope uiiectly is not noticeaLly slowei than
ieauing the acceleiometei on its own.
Because ol this associateu CPU oveiheaus push is ieally only iecommenueu loi uata
collection applications wheie the point ol the application is to oLtain the motion uata
itsell. Howevei il youi application neeus to Le iapiuly upuateu as to uevice motion you
can uo this easily:
Core Motion | 73
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
motionManager.deviceMotionUpdateInterval = 1.0/60.0;
if (motionManager.deviceMotionAvailable ) {
queue = [[NSOperationQueue currentQueue] retain];
[motionManager startDeviceMotionUpdatesToQueue:queue
withHandler:^ (CMDeviceMotion *motionData, NSError *error) {

CMAttitude *attitude = motionData.attitude;
CMAcceleration gravity = motionData.gravity;
CMAcceleration userAcceleration = motionData.userAcceleration;
CMRotationRate rotate = motionData.rotationRate;
// handle data here......
}];
} else {
[motionManager release];
}
Il we weie inteiesteu solely in the iaw gyioscope uata we coulu uo the lollowing:
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
motionManager.gyroUpdateInterval = 1.0/60.0;
if (motionManager.gyroAvailable) {
queue = [[NSOperationQueue currentQueue] retain];
[motionManager startGyroUpdatesToQueue:queue
withHandler: ^ (CMGyroData *gyroData, NSError *error) {

CMRotationRate rotate = gyroData.rotationRate;
NSLog(@"rotate x = %f, y = %f, z = %f", rotate.x, rotate.y, rotate.z);
// handle rotation-rate data here......
}];
} else {
[motionManager release];
}
Il we want Loth the iaw anu gyioscope anu acceleiometei ieauings outsiue ol the
CMDeviceMotion oLject, we coulu mouily the aLove coue as highlighteu:
CMMotionManager *motionManager = [[CMMotionManager alloc] init];
motionManager.gyroUpdateInterval = 1.0/60.0;
motionManager.accelerometerUpdateInterval = 1.0/60.0;
if (motionManager.gyroAvailable && motionManager.accelerometerAvailable) {
queue = [[NSOperationQueue currentQueue] retain];
[motionManager startGyroUpdatesToQueue:queue
withHandler: ^ (CMGyroData *gyroData, NSError *error) {
CMRotationRate rotate = gyroData.rotationRate;
NSLog(@"rotate x = %f, y = %f, z = %f", rotate.x, rotate.y, rotate.z);
// handle rotation-rate data here......
}];
[motionManager startAccelerometerUpdatesToQueue:queue
withHandler: ^ (CMAccelerometerData *accelData,
NSError *error) {
CMAcceleration accel = accelData.acceleration;
74 | Chapter 6:Using Core Motion
NSLog( @"accel x = %f, y = %f, z = %f", accel.x, accel.y, accel.z);
// handle acceleration data here......
}];
} else {
[motionManager release];
}
Accessing the Gyroscope
Let`s go aheau anu implement a simple view-Laseu application to illustiate how to use
the gyioscope on its own Leloie looking again at Coie Motion anu CMDeviceMotion.
Open Xcoue anu stait a new View-Laseu Application iPhone pioject anu name it Gy-
ioscope when piompteu loi a lilename.
Since we`ll Le making use ol the Coie Motion liamewoik, the liist thing we neeu to uo
is auu it to oui new pioject. Click on the pioject lile at the top ol the Pioject navigatoi
winuow on the iight in Xcoue, select the Taiget anu click on the Builu Phases taL, click
on the Link with LiLiaiies uiop uown anu click on the - Lutton to open the lile pop-
up winuow. Select CorcMotion.jrancwor| liom the list ol availaLle liamewoiks anu
click the Auu Lutton.
Now go aheau anu click on the Gyroscopc\icwContro||cr.xib lile to open it in Inteilace
Builuei. As you uiu loi the acceleiometei Lack in Chaptei +, you`ie going to Luilu a
simple inteilace to iepoit the iaw gyioscope ieauings. Go aheau anu uiag anu uiop
thiee UIProgressView liom the OLject LiLiaiy into the View winuow, then auu two
UILabel elements loi each piogiess Lai: one to holu the X, Y, oi Z laLel anu the othei
to holu the iotation measuiements. Altei you uo that, the view shoulu look something
a lot like Figuie 6-1.
Go aheau anu close the Utilities panel anu click to open the Assistant Euitoi. Then
Contiol-Click anu uiag liom the thiee UIProgressView elements, anu the thiee UILa
bel elements that will holu the measuieu values, to the Gyroscopc\icwContro||cr.h
heauei lile which shoulu Le uisplayeu in the Assistant Euitoi on the iight-hanu siue ol
the inteilace (see Figuie 6-2).
This will automatically cieate anu ueclaie thiee UILabel anu thiee UIProgressView vai-
iaLles as an IBOutlet. Since they aien`t going to Le useu outsiue the class, theie isn`t
much point in ueclaiing them as class piopeities, which you`u uo with a Contiol-click
anu uiag liom the element to outsiue the cuily Liace. Altei uoing this, the coue shoulu
look like this:
#import <UIKit/UIKit.h>
@interface GyroscopeViewController : UIViewController {
IBOutlet UIProgressView *xBar;
IBOutlet UIProgressView *yBar;
IBOutlet UIProgressView *zBar;
Accessing the Gyroscope | 75
IBOutlet UILabel *xLabel;
IBOutlet UILabel *yLabel;
IBOutlet UILabel *zLabel;
}
@end
Close the Assistant Euitoi, ietuin to the Stanuaiu Euitoi anu click on the Gyroscopc-
\icwContro||cr.h inteilace lile. Go aheau anu impoit the Coie Motion heauei lile, anu
ueclaie a CMMotionManager anu NSOperationQueue instance vaiiaLles. Heie`s how the
shoulu look when you aie uone:
#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>
@interface GyroscopeViewController : UIViewController {
IBOutlet UIProgressView *xBar;
IBOutlet UIProgressView *yBar;
IBOutlet UIProgressView *zBar;
IBOutlet UILabel *xLabel;
IBOutlet UILabel *yLabel;
IBOutlet UILabel *zLabel;
Iigurc -1. Thc Gyroscopc U|
76 | Chapter 6:Using Core Motion
CMMotionManager *motionManager;
NSOperationQueue *queue;
}
@end
Make suie you`ve saveu youi changes anu click on the coiiesponuing Gyroscopc\icw-
Contro||cr.n implementation lile to open it in the Xcoue euitoi. You uon`t actually have
to uo veiy much heie, as Inteilace Builuei hanuleu most ol the heavy lilting with iespect
to the UI, you just neeu to go aheau an implement the guts ol the application to monitoi
the gyioscope upuates:
@implementation GyroscopeViewController
- (void)dealloc {
[xBar release];
[yBar release];
[zBar release];
[xLabel release];
[yLabel release];
[zLabel release];
[queue release];
[super dealloc];
}
Iigurc -2. Connccting thc U| c|cncnts to your codc in |ntcrjacc Bui|dcr
Accessing the Gyroscope | 77
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
motionManager = [[CMMotionManager alloc] init];
motionManager.gyroUpdateInterval = 1.0/2.0; // Update every 1/2 second.
if (motionManager.gyroAvailable) {
NSLog(@"Gyroscope avaliable");
queue = [[NSOperationQueue currentQueue] retain];
[motionManager startGyroUpdatesToQueue:queue
withHandler: ^ (CMGyroData *gyroData,
NSError *error) {
CMRotationRate rotate = gyroData.rotationRate;
xLabel.text = [NSString stringWithFormat:@"%f", rotate.x];
xBar.progress = ABS(rotate.x);
yLabel.text = [NSString stringWithFormat:@"%f", rotate.y];
yBar.progress = ABS(rotate.y);
zLabel.text = [NSString stringWithFormat:@"%f", rotate.z];
zBar.progress = ABS(rotate.z);
}];
} else {
NSLog(@"Gyroscope not available");
[motionManager release];
}
}
- (void)viewDidUnload {
[motionManager stopGyroUpdates];
[motionManager release];
[xBar release];
xBar = nil;
[yBar release];
yBar = nil;
[zBar release];
zBar = nil;
[xLabel release];
xLabel = nil;
[yLabel release];
yLabel = nil;
[zLabel release];
zLabel = nil;
[super viewDidUnload];
}
78 | Chapter 6:Using Core Motion
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation {

return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end
The CMRotationRate uata stiuctuie pioviues the iate ol iotations aiounu X-, Y-, anu
Z-axes in units ol iauians pei seconu. Vhen inspecting the stiuctuie iememLei the
iight-hanu iule to ueteimine the uiiection ol positive iotation. Vith youi thumL in the
positive uiiection on an axis, youi lingeis cuil will give the positive iotation uiiection
aiounu that axis (see Figuie 6-3). A negative iotation goes away liom the tips ol those
lingeis.
Let`s test that: click on the Run Lutton in the Xcoue toolLai to Luilu anu ueploy the
application to youi uevice (iememLei you can`t test this coue in the iOS Simulatoi). Il
all goes well you shoulu see something much like Figuie 6-+ as you ioll the uevice
aiounu the Y-axis.
As mentioneu Leloie the measuiement ol iotation iate encapsulateu Ly
a CMGyroData oLject is Liaseu Ly vaiious lactois. You can oLtain a much
moie accuiate (unLiaseu) measuiement Ly accessing the iotationRate
piopeity ol CMDeviceMotion il that is neeueu Ly youi application.
Measuring Device Motion
Let`s go aheau anu Luilu a similai application to the one aLove, Lut this time iepoiting
the uata exposeu Ly the CMDeviceMotion oLject:
CMAttitude *attitude = motionData.attitude;
CMAcceleration gravity = motionData.gravity;
CMAcceleration userAcceleration = motionData.userAcceleration;
CMRotationRate rotate = motionData.rotationRate;
Open Xcoue anu stait a new iPhone pioject, select a View-Laseu Application template,
anu name the pioject Motion when piompteu loi a lilename. As Leloie, impoit the
Coie Motion liamewoik into the pioject anu then click on the Motion\icwContro|-
|cr.xib lile to open it in Inteilace Builuei, anu then pioceeu to uiag-anu-uiop UIProg
ressBar anu UILabel elements into youi View in a similai mannei as you uiu loi the
Gyioscope application eailiei in the chaptei. You`ll neeu laLels loi the yaw, pitch anu
ioll values, along with piogiess Lais anu laLels loi the usei acceleiation, giavity anu
iotation values.
Once you`ve uone this, go aheau anu connect the vaiious Lais anu laLels as IBOutlet
using the Assistant Euitoi into the Motion\icwContro||cr.h inteilace lile as in Fig-
uie 6-5.
Measuring Device Motion | 79
Once you`ve uone this, save youi changes anu open up the Motion\icwContro||cr.h
inteilace lile in the Stanuaiu Euitoi. Go aheau anu impoit the Coie Motion liamewoik:
#import <CoreMotion/CoreMotion.h>
Foi this example you`ie going to pull the uevice motion upuates iathei than push them
using the NSOperationQueue anu a hanulei Llock. Auu the lollowing instance vaiiaLles
to the view contiollei class:
CMMotionManager *motionManager;
NSTimer *timer;
Then in the coiiesponuing Motion\icwContro||cr.n implementation lile, mouily the
viewDidLoad methou as lollows:
Iigurc -3. Thc iPhonc gyroscopc axcs
80 | Chapter 6:Using Core Motion
- (void)viewDidLoad {
[super viewDidLoad];
motionManager = [[CMMotionManager alloc] init];
motionManager.deviceMotionUpdateInterval = 1.0 / 10.0;
[motionManager startDeviceMotionUpdates];
if (motionManager.deviceMotionAvailable ) {
timer = [NSTimer scheduledTimerWithTimeInterval:0.2f
target:self
selector:@selector(updateView:)
userInfo:nil
repeats:YES];
} else {
[motionManager stopDeviceMotionUpdates];
Iigurc -1. Mcasuring rotation on thc iPhonc 1 whi|st ro||ing it around thc Y-axis
Measuring Device Motion | 81
[motionManager release];
}
}
This will stait the motion managei anu Legin polling loi uevice motion upuates. Auu
the lollowing lines to the viewDidUnload methou to coiiesponuing stop the timei anu
upuates:
[timer invalidate];
[motionManager stopDeviceMotionUpdates];
[motionManager release];
Once you have uone this you shoulu go aheau anu implement the updateView: methou
that will Le calleu Ly the NSTimer oLject:
-(void) updateView:(NSTimer *)timer {
CMDeviceMotion *motionData = motionManager.deviceMotion;
CMAttitude *attitude = motionData.attitude;
CMAcceleration gravity = motionData.gravity;
CMAcceleration userAcceleration = motionData.userAcceleration;
CMRotationRate rotate = motionData.rotationRate;
yawLabel.text = [NSString stringWithFormat:@"%2.2f", attitude.yaw];
Iigurc -5. Thc Motion app|ication U| with thc |BOut|ct conncctcd in |ntcrjacc Bui|dcr to thc
Motion\icwContro||cr.h intcrjacc ji|c
82 | Chapter 6:Using Core Motion
pitchLabel.text = [NSString stringWithFormat:@"%2.2f", attitude.pitch];
rollLabel.text = [NSString stringWithFormat:@"%2.2f", attitude.roll];
accelIndicatorX.progress = ABS(userAcceleration.x);
accelIndicatorY.progress = ABS(userAcceleration.y);
accelIndicatorZ.progress = ABS(userAcceleration.z);
accelLabelX.text = [NSString stringWithFormat:@"%2.2f",userAcceleration.x];
accelLabelY.text = [NSString stringWithFormat:@"%2.2f",userAcceleration.y];
accelLabelZ.text = [NSString stringWithFormat:@"%2.2f",userAcceleration.z];
gravityIndicatorX.progress = ABS(gravity.x);
gravityIndicatorY.progress = ABS(gravity.y);
gravityIndicatorZ.progress = ABS(gravity.z);
gravityLabelX.text = [NSString stringWithFormat:@"%2.2f",gravity.x];
gravityLabelY.text = [NSString stringWithFormat:@"%2.2f",gravity.y];
gravityLabelZ.text = [NSString stringWithFormat:@"%2.2f",gravity.z];
rotIndicatorX.progress = ABS(rotate.x);
rotIndicatorY.progress = ABS(rotate.y);
rotIndicatorZ.progress = ABS(rotate.z);
rotLabelX.text = [NSString stringWithFormat:@"%2.2f",rotate.x];
rotLabelY.text = [NSString stringWithFormat:@"%2.2f",rotate.y];
rotLabelZ.text = [NSString stringWithFormat:@"%2.2f",rotate.z];
}
Save youi changes anu hit the Run Lutton in the Xcoue toolLai to Luilu anu ueploy the
application to youi uevice. Il all goes well you shoulu see something much like Fig-
uie 6-6.
Comparing Device Motion with the Accelerometer
At this stage we can illustiate the uilleience Letween giavity anu usei-contiiLuteu ac-
celeiation values iepoiteu Ly Coie Motion to the iaw acceleiation values iepoiteu Ly
the UIAccelerometer, uiscusseu Lack in Chaptei +.
Re-open the Motion\icwContro||cr.xib lile in Inteilace Builuei anu auu anothei section
to the UI, which will iepoit the iaw ieauings liom the UIAccelerometer oLject. Go aheau
anu connect these thiee Lais to IBOutlet instance vaiiaLles in the Motion\icwContro|-
|cr.h inteilace lile using the Assistant Euitoi as Leloie, see Figuie 6-7.
As you can see liom Figuie 6-7, I`ve changeu the UIProgressView style liom Delault
to Bai using the AttiiLutes inspectoi in the Utility pane. This will help uilleientiate
this sectionuata iepoiteu liom the UIAccelerometerliom the othei sections whose
values aie iepoiteu Ly the CMMotionManager.
Once that is uone, close the Assistant Euitoi anu open the Motion\icwContro||cr.h
inteilace lile using the Stanuaiu Euitoi. Go aheau anu ueclaie the view contiollei as a
UIAccelerometerDelegate anu auu a UIAccelerometer instance vaiiaLle as shown heie:
@interface MotionViewController : UIViewController <UIAccelerometerDelegate> {
Measuring Device Motion | 83
...
UIAccelerometer *accelerometer;
}
@end
Leloie opening the coiiesponuing implementation lile. In the viewDidLoad methou, auu
the lollowing coue to initialize the UIAccelerometer oLject. You shoulu see Chaptei +
loi moie uetails on the UIAccelerometer class anu associateu methous:
- (void)viewDidLoad {
[super viewDidLoad];
motionManager = [[CMMotionManager alloc] init];
motionManager.deviceMotionUpdateInterval = 1.0 / 10.0;
[motionManager startDeviceMotionUpdates];
if (motionManager.deviceMotionAvailable ) {
timer = [NSTimer scheduledTimerWithTimeInterval:0.2f
target:self
selector:@selector(updateView:)
userInfo:nil
repeats:YES];
} else {
[motionManager stopDeviceMotionUpdates];
[motionManager release];
Iigurc -. Thc Motion app|ication running on an iPhonc 1 sitting j|at on thc dcs|, with gravity in
thc ncgativc Z-dircction without any rotation or uscr accc|cration
84 | Chapter 6:Using Core Motion
}
accelerometer = [UIAccelerometer sharedAccelerometer];
accelerometer.updateInterval = 0.2f;
accelerometer.delegate = self;
}
Altei uoing this all you neeu to uo is auu the accelerometer:didAccelerate: uelegate
methou:
- (void)accelerometer:(UIAccelerometer *)meter
didAccelerate:(UIAcceleration *)acceleration {

rawAccelLabelX.text =
[NSString stringWithFormat:@"%2.2f", acceleration.x];
rawAccelIndicatorX.progress = ABS(acceleration.x);
rawAccelLabelY.text =
[NSString stringWithFormat:@"%2.2f", acceleration.y];
rawAccelIndicatorY.progress = ABS(acceleration.y);
rawAccelLabelZ.text =
[NSString stringWithFormat:@"%2.2f", acceleration.z];
rawAccelIndicatorZ.progress = ABS(acceleration.z);
}
Iigurc -7. Thc additiona| U|Progrcss\icw and U|Labc| c|cncnts to rcport thc raw U|Accc|cronctcr
rcadings to thc uscr
Measuring Device Motion | 85
Click on the Run Lutton in the Xcoue toolLai to Luilu anu ueploy the application to
the uevice as Leloie. Il all goes well you shoulu see something much like Figuie 6-S.
Move the uevice aiounu anu you can see how the iaw acceleiometei values anu the
ueiiveu giavity anu usei acceleiation values coiiesponu to each othei.
Iigurc -8. Thc Motion app|ication running on an iPhonc 1 sitting j|at on thc dcs|
86 | Chapter 6:Using Core Motion
CHAPTER 7
Going Further
I`ve coveieu a laii amount ol giounu in the last lew chapteis, anu you shoulu now have
a soliu giasp ol the Lasics ol hanuling the sensoi uata piouuceu Ly the haiuwaie.
The iPhone SDK
PieuictaLly in a Look talking aLout sensois I`ve locuseu on the paits ol the SDK that
will Le most helplul, anu allow you to use the Lasic sensoi haiuwaie in youi own
applications. But even theie I`ve lelt out a lot in an attempt to simplily anu get you
staiteu guickly, especially when it comes to auuio. A moie in-uepth look at the iPhone
SDK is availaLle in Progranning iOS 1, Ly Matt NeuLuig (O`Reilly).
Geolocation and Maps
The iPhone is one ol the most populai uevices loi geolocation: useis use it loi eveiything
liom uiiving uiiections to linuing a iestauiant close to them. As a uevelopei, you can
get in on the geolocation game Ly using the Coie Location liamewoik, one ol the most
poweilul anu inteiesting liamewoiks in the iPhone SDK. It aLstiacts the uetails ol
ueteimining a usei`s location, anu uoes all the heavy lilting loi you Lehinu the scenes.
Fiom theie you can use the MapKit liamewoik to emLeu maps uiiectly into youi views,
anu then go aheau anu annotate those maps. I`ll ueep-uive into Loth these topics in
upcoming title Gco|ocation in iOS, Ly Alasuaii Allan (O`Reilly).
Third-Party SDKs
The same Look will investigate thiiu-paity geo-SDKs such as the Skyhook Viieless
Local Faves anu Spot Rank SDKs, along with coveiage ol SimpleGeo anu SG Context
anu Places.
87
Speech Recognition
I coveieu Lasic manipulation ol the auuio haiuwaie, Lut moving on liom this you might
Le thinking aLout integiating speech iecognition into youi application. At least until
Apple gets iounu to auuing this to the ollicial iOS SDK, the Lest way to uo this is
pioLaLly using the CMU Pocketsphinx anu CMU Flite liLiaiies. Theie aie actually two
laiily goou OLjective-C wiappeis to the liLiaiies, these aie VocalKit anu OpenEais. Ol
the two, at least at the time ol wiiting, OpenEais pioLaLly has is the Lest uocumentation
which may Le a ueciuing lactoi il you`ie not a expeit in speech iecognition.
Computer Vision
The Open Souice Computei Vision (OpenCV) LiLiaiy is a collection ol ioutines in-
tenueu loi ieal-time computei vision, ieleaseu unuei the BSD License, liee loi Loth
piivate anu commeicial use. The liLiaiy has a numLei ol uilleient possiLle applications
incluuing oLject iecognition anu tiacking. Ve uelve into computei vision anu lace
iecognition in the upcoming title Augncntcd Rca|ity in iOS, Ly Alasuaii Allan
(O`Reilly).
Vhile you wait you might want to take a look at some ol the sample coue liom this
title which is alieauy on the weL at http://progranningiphoncscnsors.con/pagcs/oscon
.htn|.
Augmented Reality
Unsuipiisingly peihaps, the same title will also take a close look at Augmenteu Reality,
which has Lecome one ol the killei applications loi the iOS platloim. The Look walks
you thiough Luiluing a simple location-awaie AR toolkit, anu some ol the sample coue
is alieauy online at http://progranningiphoncscnsors.con/nastcrc|ass/thcc|ass.htn|.
Il you`ie inteiesteu in AR you might also want to take a look at the associateu viueo
masteiclass on iOS Sensois which leatuies me, amongst othei things, walking you
thiough the AR toolkit coue.
The viueo masteiclass Ma|ing usc oj iPhonc and iPad Location Scnsors
was lilmeu using Xcoue 3 anu iOS +.0. Vhile the coue is still line, the
step-Ly-step walkthioughs in Xcoue aie somewhat out ol uate.
External Accessories
Vhile the iOS platloim comes with a giowing iange ol sensois; GPS, acceleiometeis,
magnetometeis anu most iecently gyioscopes. They also have a (neai-)uLiguitous uata
connection, whethei via a local wiieless hotspot oi via caiiiei uata, anu usei positioning
88 | Chapter 7:Going Further
via multiple methous incluuing GPS. The uevice makes an excellent huL loi a uistiiL-
uteu sensoi netwoik.
Howevei until iecently it was actually guite uillicult to inteilace these otheiwise intei-
esting uevices into a stanuaiu seiial inteilace, as the iPhone`s piopiietaiy uock
connectoi is a majoi stumLling Llock.
All this has changeu. In the upcoming title iOS and Scnsor Nctwor|s Ly Alasuaii Allan
(O`Reilly) we`ll uiscuss using the MFi appioveu Reupaik Seiial CaLle. This is an olli-
cially Apple appioveu ioute, anu makes use ol Apple`s own Exteinal Accessoiy Fiame-
woik to connect youi uevice to any stanuaiu seiial (RS-232) capaLle uevice. In auuition
to this we will go on to uiscuss othei methous to use the phone as the huL ol a sensoi
netwoik, anu pait ol the Inteinet ol Things.
External Accessories | 89
About the Author
$ODVGDLU$OODQ is the authoi ol Lcarning iPhonc Progranning, Progranning iPhonc
Scnsors, Basic Scnsors in iOS, Gco|ocation iOS, iOS Scnsor Apps with Arduino, anu
Augncntcd Rca|ity in iOS, all puLlisheu Ly O`Reilly Meuia. He is a senioi ieseaich
lellow in Astionomy at the Univeisity ol Exetei. As pait ol his woik theie, he is Luiluing
a uistiiLuteu peei-to-peei netwoik ol telescopes which, acting autonomously, will ie-
actively scheuule oLseivations ol time-ciitical events. NotaLle successes incluue con-
tiiLuting to the uetection ol the most uistant oLject yet uiscoveieu, a gamma-iay Luistei
at a ieushilt ol S.2. Alasuaii also iuns a small technology consulting Lusiness wiiting
Lespoke soltwaie, Luiluing open haiuwaie, anu pioviuing tiaining. He wiites loi
O`Reilly Rauai, anu spoiauically wiites in his own Llog, The Daily ACK, aLout things
that inteiest him, oi moie lieguently pioviues commentaiy in 1+0 chaiacteis oi less
on Twittei.
Colophon
The animal on the covei ol Basic Scnsors in iOS is a Malay lox-Lat.
The covei image is liom Lyuekkei`s Roya| Natura| History. The covei lont is AuoLe
ITC Gaiamonu. The text lont is Linotype Biika; the heauing lont is AuoLe Myiiau
Conuenseu; anu the coue lont is LucasFont`s TheSansMonoConuenseu.