iPhone SDK Programming Maher Ali
WILEY w iley.com
ПРОГРАММИРОВАНИЕ
для iPhone Разработка мобильных приложений с пом...
8 downloads
985 Views
25MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
iPhone SDK Programming Maher Ali
WILEY w iley.com
ПРОГРАММИРОВАНИЕ
для iPhone Разработка мобильных приложений с помощью iPhone SDK
Махер Али
эксмо
Москва 2010
УДК 004.42 ББК 32.973.26 М36
Махер А.
М 36
Программирование для iPhone / Махер Али; | пер. с англ. ]. — М .: Эксмо. 2010. —368 с. ISBN 978-0-470-74282-2 (англ.) ISBN 978-5-699-40764-4 Книга предназначена для профессиональных программистов, желающих создавать приложения для iPhone 3G и iPod Touch с помощью Apple SDK. Освоение материала не требует предварительного изучения языка Objective-C - его основы даются и начале кни ги. В книге подробно описываются основы iPhone SDK. Значительная часть материала по священа разработке пользовательских интерфейсов, .механизму баз данных SQLite и биб лиотеке обработки XML libxml2. Большое внимание уделено возможностям iPhone как GPS-навигатора. УДК 004.42 ББК 32.973.26
Все налшиия программных м|>одуктон являю тся аарегистрнрогсшными торговыми марками сооттлгтвую ш их фирм. Никакая часть настоящего нидання ми в каких целях не может быть воспроизведена а кикой 6и то ми было форме и какими бы ю >ш было сродстппми, будь то электронные или механические, иключам фотокопирование и запись на магнитный носитель, если м а л о нет письменной» разрешения налатольСТШ1 «Эксмо».
ISBN 978-0-470-74282-2 (англ.) ISBN 978-5-699-40764-4
€> 2009, John Wiley & Sons, Ltd. All rights reserved. Authorised translation from the English language edition published by John Wiley & Sons, Ltd. No part of this book may be reproduced in any fomi without the written permission of the original copyright holder, John Wiley & Sons Limited. О Перевод на русский язык, ЧП «Айдиономнкс», 2010 О Издание па русском языке, оформление. ООО «Издательство «Эксмо*, 2010
Содержание
Введение................................................................................................................ .. 11 Д ля кого предназначена книга....................................................................... .. 12 Что вам н еоб ходи м о............................................................................................ 13 Структура книги....................................................................................................14 Глава 1. Objective-C и Cocoa ..........................................................................
17
1.1. К лассы ....................................................................................................... 18 1.1.1. Объявление класса....................................................................... ...18 1.1.2. Как использовать другие объявления..................................... .. 19 1.1.3. Определение класса..................................................................... .. 20 1.1.4. Определение и вызов методов..................................................... 20 1.1.5. Важные типы....................................................................................21 1.1.6. Важные классы Cocoa....................................................................22 1.2. Управление памятью............................................................................. ..23 1.3. П ротоколы ............................................................................................... ..26 1.4. С войства.....................................................................................................28 1.5. Категории................................................................................................. ..34 1.6. П озиционирование................................................................................ ..35 1.7. Исключения и ош ибки......................................................................... ..36 1.7.1. Исключения...................................................................................... 36 1.7.2. О ш ибки........................................................................................... .. 40 1.8. Кодирование «ключ-значение».......................................................... ..42 1.9. Многопотоковость.................................................................................. ..50 1.10. Резюме.....................................................................................................
54
Задачи......................................................................................................... 54
5
Глава 2. Коллекции......................................................................................... .. 58 2.1. М ассивы....................................................................................................... ..58 2.1.1. Неизменяемое копирование........................................................ ..62 2.1.2. Изменяемое копирование............................................................. ..64 2.1.3. Расширенное копирование........................................................... ..65 2.1.4. Сортировка м ассива....................................................................... ..69 2.2. М нож ества.................................................................................................. ..74 2.2.1. Неизменяемые множества............................................................ ..74 2.2.2. Изменяемые м нож ества................................................................ ..75 2.2.3. Дополнительные важные м етоды.................................................77 2.3. С ловари........................................................................................................ ..78 2.4. Резю м е.............................................................................................................80
Глава 3. Анатомия iPhone-приложения.....................................................
82
3.1. Приложение H elloW orld.........................................................................
82
3.2. Создание приложения H elloW orld.....................................................
85
Глава 4. Представление..................................................................................
90
4.1. Геометрия представления.......................................................................
90
4.1.1. Определения полезных геометрических типов д а н н ы х .......90 4.1.2. Класс U lS creen...................................................................................91 4.1.3. Атрибуты frame и c e n te r................................................................ ..93 4.1.4. Атрибут bounds...................................................................................94 4.2. Иерархия представлений........................................................................ ..96 4.3. M ultitouch-ин терф ейс............................................................................. ..96 4.3.1. Класс U IT ouch.................................................................................. 97 4.3.2. Класс UI E v e n t.................................................................................. 98 4.3.3. Класс U IR esponder.......................................................................... 98 4.3.4. Обработка скольж ений.................................................................. 104 4.3.5. Более совершенное распознавание жестов..............................108 4.4. А нимация..................................................................................................... 113 4.4.1. Использование поддержки анимации в классе U lV iew
113
4.4.2. Анимация перехода.........................................................................117 4.5. Рисование.................................................................................................... 120
6
Глава 5. Элементы управления..................................................................122 5.1. Основа всех элементов управления...................................................122 5.1.1. Атрибуты U lC ontrol..................................................................... 123 5.1.2. Механизм «цель-действие».........................................................123 5.2. U IT extField...............................................................................................126 5.2.1. Взаимодействие с клавиатурой.................................................128 5.2.2. Д елегат.............................................................................................131 5.2.3. Создание и работа с U IT extField.............................................. 132 5.3. Слайдеры.................................................................................................. 133 5.4. Переключатели........................................................................................ 134 5.5. Кнопки....................................................................................................... 135 5.6. Сегментированные элементы управления...................................... 136 5.7. Страничные элементы управления....................................................140 5.8. Элементы выбора даты ..........................................................................141 5.9. Резю ме....................................................................................................... 142
Глава 6. Контроллеры представлений.......................................................143 6.1. Простейший контроллер представления......................................... 143 6.1.1. Контроллер представления.........................................................143 6.1.2. Представление............................................................................... 146 6.1.3. Делегат приложения.....................................................................146 6.1.4. Резюме..............................................................................................148 6.2. Радиоинтерфейсы................................................................................... 149 6.2.1. Детальный пример........................................................................150 6.2.2. Некоторые комментарии к контроллерам панелей закладок
155
6.3. Контроллеры навигации.......................................................................160 6.3.1. Пример поведения класса навигации.......................................160 6.3.2. Настройка........................................................................................166 6.4. Модальные контроллеры представления.........................................170 6.5. Резю м е....................................................................................................... 176
Глава 7. Специализированные представления........................................ 177 7.1. Представления подбора значений......................................................177 7.1.1. Д елегат....................................................................... ..................... 177
7
7.1.2. П рим ер............................................................................................... 179 7.2. Представления индикаторов деятельн ости ..................................... 183 7.3. Текстовое представление........................................................................186 7.3.1. Д ел егат............................................................................................... 186 7.3.2. П ри м ер............................................................................................... 187 7.4. Представление предупреждения.......................................................... 190 7.5. Списки действий....................................................................................... 192 7.6. Веб-представления....................................................................................193 7.6.1. Простое приложение с веб-представлением...........................194 7.6.2. Просмотр локальных ф ай лов...................................................... 197 7.6.3. Выполнение Jav aS crip t.................................................................. 202 7.6.4. Делегат веб-представления.......................................................... 208 Глава 8. Табличное п редставлен ие..................................................................214 8.1. О бзор............................................................................................................. 214 8.2. Простейшее приложение с табличным представлением
215
8.3. Табличное представление, содержащее изображения и текст
219
8.4. Табличное представление с верхним и нижним колонтитулами секции
220
8.5. Табличное представление с возможностью удалять строки
222
8.6. Табличное представление с возможностью вставки с т р о к
229
8.7. Упорядочивание табличных строк...................................................... 235 8.8. Вывод иерархической инф орм ации.................................................... 240 8.9. Сгруппированные табличные представления..................................249 8.10. Индексированные табличные представления................................252 8.11. Резю м е........................................................................................................ 257 Глава 9. У правление ф айлам и........................................................................... 258 9.1. Домаш няя директория.............................................................................258 9.2. Поиск в директории..................................................................................259 9.3. Создание и удаление директории........................................................ 260 9.4. Создание ф а й л о в ...................................................................................... 262
8
9.5. Считывание и изменение атрибутов.................................................. 265 9.6. Работа с ресурсами и низкоуровневый доступ к ф айлам
269
9.7. Резю ме....................................................................................................... 272 Глава 10. Работа с базами данны х..................................................................273 10.1. Основные операции с базой данных................................................ 273 10.2. Обработка результирующих строк .................................................. 277 10.3. Подготавливаемые вы раж ения.........................................................279 10.3.1. Подготовка.................................................................................... 279 10.3.2. Выполнение.................................................................................. 280 10.3.3. Ф инализация................................................................................280 10.4. Пользовательские ф ункции ...............................................................282 10.5. Хранение BLOB-значений................................................................. 286 10.6. Получение BLOB-значений...............................................................289 10.7. Резюме......................................................................................................291 Глава 11. О бработка X M L ................................................................................ 292 11.1. XML и R S S ............................................................................................. 292 11.1.1. X M L ................................................................................................292 11.1.2. R S S ..................................................................................................294 11.2. Объектная модель документа............................................................296 11.3. Простой интерфейс для X M L............................................................302 11.4. Приложение для чтения RSS.............................................................310 11.5. Резюме......................................................................................................313 Задачи................................................................................................................ 315 Глава 12. И нформация о местоположении..................................................317 12.1. Фреймворк Core Location.................................................................. 317 12.2. Простейшее приложение, предоставляющее информацию о местоположении
321
12.3. Google Maps A PI....................................................................................326 12.4. Отслеживающее приложение с картами местности....................331 12.5. Работа с почтовыми индексами.........................................................336 12.6. Резюме......................................................................................................339
9
Глава 13. Работа с устройствами..................................................................340 13.1. Работа с акселером етром...................................................................... 340 13.2. А удио........................................................................................................... 345 13.3. Видео............................................................................................................347 13.4. Информация об устройстве................................................................. 347 13.5. Производство и
просмотр
снимков....................................................348
13.5.1. Общий подход................................................................................ 349 13.5.2. Подробный пример....................................................................... 349 13.6. Резю ме......................................................................................................... 357
Приложение А. Сохранение и восстановление состояния программы...................................................... 358 Приложение Б. Запуск внешних программ.............................................. 361 Ссылки и библиография.................................................................................. 363 Алфавитный указатель.....................................................................................364
Введение
Добро пожаловать в программирование в iPhone SDK — введение в разработку мобильных приложений для iPhone и iPod Touch. В этой книге рассматриваются следующие темы: х язык программирования Object-C; * коллекции; * Cocoa T ouch; ^разработка многофункциональных мобильных пользовательских ин терфейсов; л основы анимации и Quartz 2D; л шаблоны типа «модель-представление-коитроллер» (M odel-viewcontroller, MVC); * табличное представление данных;
х управление файлами; Асинтаксический анализ XML-документов с использованием SAX и DOM; * работа с Google Maps API; л использование веб-сервисов RESTful;
х разработка многофункциональных программ, основанных на анализе местоположения; * создание приложений баз данных, используя механизм SQLite; * разработка мультимедиа-приложений.
Для кого предназначена книга
Основная читательская аудитория данной книги — это разработчики приложений, владеющие основами языка С и концепциями объектноориентированного программирования, такими как инкапсуляция и поли морфизм. Чтобы читать книгу, не нужно быть экспертом-программистом на С — достаточно базовых знаний о структурах, указателях и функциях. Рассматриваемые в книге общие темы, такие как базы данных и обработка XML, раскрыты из расчета, что у читателя минимальные знания по этой теме.
Что вам необходимо
Чтобы овладеть программированием в iPhone SDK, вам потребуется следующее: * компьютер на платформе Intel с установленной операционной систе мой Mac OS X Leopard; * iPhone SDK (доступен по адресу http://developer.apple.com/iphone); * членство в программе iPhone Developer Program (необязательно); чтобы использовать ваше устройство для разработки, вы должны оплатить взнос за членство в iPhone Developer Program; * исходные коды (приведенные в книге исходные коды приложений доступны по адресу http://code.google.com/p/iphone-sdk-programming-bookcode-samples/down loads/l ist) .
Структура книги
Глава 1. Описывает основные свойства язы ка Objective-C в среде Cocoa. Вы ознакомитесь с основными идеями в управлении классами в O bjective-C и научитесь объявлять, определять и использовать новый класс. Вас также познакомят с основными классами и типами данных Cocoa, Еще вы узнаете об управлении памятью в iPhone OS, научитесь создавать и удалять новые объекты и изучите правила применения объек тов из Сосоа-платформы или других платформ. Вы ознакомитесь с темой протоколов в O bjective-C, научитесь использовать существующие прото колы и объявлять новые. Эта глава также описывает такие свойства язы ка, как атрибуты, категории и позиционирование. Здесь же представлены исключения и техники обработки ошибок. Еще вы ознакомитесь с кон цепцией программирования «ключ-значение» (key-value coding, KVC) и научитесь использовать многопоточность в вашем iPhone-приложении. Глава 2. Посвящена коллекциям в Cocoa. В ней рассматриваются мас сивы, множества и словари. Вы узнаете о неизменяемых и изменяемых коллекциях, различных подходах, используемых для наполнения коллек ций, а также некоторых методах сортировки. Глава 3. В ней рассматриваются основные шаги при построении про стейшего iPhone-приложения — описана основная структура просто го iPhone-приложения и этапы разработки программы с применением Xcode. Глава 4. Здесь разъясняются основные концепции видов. Вы узнаете о геометрии и иерархии видов, m ultitouch-интерфейсе, анимации и осно вах рисования в Q uartz 2D. Глава 5. Из нее вы узнаете о базовом классе для всех элементов управле ния — UlControl — и важном механизме «цель-действие» (target-action). Эта глава также представит некоторые важные графические элементы управления, которые можно использовать для построения интересных iPhone-пршюжений. Глава 6. Описывает доступные контроллеры представлений, име ющиеся в iPhone SDK. Можно создать iPhone-приложение, не исполь зуя этих контроллеров, однако делать этого не стоит — контроллеры представлений упрощают приложение. Эта глава предлагает введение в использование контроллеров представлений и подробное описание применения контроллеров панелей закладок, контроллеров навигации и модальных контроллеров. 14
Глава 7. Познакомит вас с несколькими важными подклассами класса Uiview. Вы узнаете об элементах выбора и их использовании для выбора каких-либо значений. Мы рассмотрим компоненты отображения прогрес са, компоненты индикации деятельности и текстовые компоненты, при меняемые для отображения многострочного текста. Вы узнаете, как ис пользовать компоненты уведомлений для отображения уведомительных сообщений пользователю. Будут также рассмотрены диалоговые окна.
Глава 8. Эта глава шаг за шагом проведет вас через мир таблиц. Мы начнем с обзора основных концепций табличных представлений данных, затем рассмотрим простейшее приложение с таблицей и обязательные методы накопления и обработки данных взаимодействия пользователя с таблицей. Вы узнаете, как добавлять изображения в строки таблицы, и ознакомитесь с концепцией секций и приложением с таблицей, содер жащей секции с собственными заголовками и подвалами. В этой главе такж е представлен метод редактирования таблиц и описана программа, позволяю щ ая удалять строки в таблице. Мы обратимся к способам встав ки новых строк в таблицу и обсудим приложение, дающее возможности просмотра отдельной записи данных и добавления в таблицу новых зап и сей. Мы продолжим обсуждение режима редактирования и рассмотрим приложение с возможностью перестановки записей в таблице. Затем об судим механизм отображения пользователю информации в иерархиче ском виде, а также приложение, использующее таблицу для представле ния трех уровней иерархии. На примерах займемся сгруппированными таблицами, а затем ознакомимся с основными идеями касательно индек сированных таблиц. Глава 9. Эта глава раскрывает тему управления файлами. Вы научитесь использовать высоко- и низкоуровневые методы сохранения и извлече ния данных из файлов. Мы поговорим о домашнем каталоге приложения, а затем вы научитесь перечислять содержимое директории, используя вы сокоуровневые методы файлового менеджера NSFileManager. Вы узнаете больше о структуре домашнего каталога и местах возможного хранения файлов. Вы научитесь создавать и удалять каталоги, ознакомитесь с ме тодами создания файлов и изучите атрибуты файлов и каталогов. В этой главе мы расскажем, как считывать и устанавливать атрибуты, а также ис пользовать пакеты приложений и низкоуровневого доступа к файлам. Глава 10. В ней рассматриваются основы механизма баз данных SQLite, доступного в iPhone SDK. SQLite является встроенной базой дан ных, то есть отдельно работающего сервера нет — весь механизм баз дан ных встроен в ваше приложение. Вы изучите основные выражения языка SQL, их реализацию с использованием вызовов функций SQLite и обра ботку результирующих множеств, генерируемых выражениями SQL. Мы также обратимся к темам предкомпилированных выражений, расширений SQLite API на примере пользовательских функций и хранения и считыва ния BLOB-полей из базы данных. 15
Глава 11. Здесь вы научитесь эффективному использованию XML в вашем iPhone-приложонии. Глава развивает предшествующую тематику и описывает принципы работы iPhone-приложения для чтения RSS-ленты. Мы рассмотрим синтаксический анализ DOM и SAX, табличное прило жение для чтения RSS-ленты, а в качестве итога будут описаны основные этапы, которые нужно пройти для эффективного использования XML в вашем iPhone-приложении. Глава 12. В ней мы обратимся к теме определения местоположения — рассмотрим технологию Core Location и ее использование для постро ения приложений, определяющих местоположение, и обсудим простейшее приложение с определением местности. Затем вы ознакомитесь с геокоднрованием. Вы научитесь переводить почтовые адреса в географические, определять движение устройства и отражать эту информацию на картах и узнаете о способах соотношения почтовых индексов и географической информации. Глава 13. В этой главе вы ознакомитесь с использованием некоторых внутренних устройств iPhone. Вы узнаете, как применять акселерометр, проигрывать небольшие звуковые и видеофайлы, получать техническую информацию об устройстве iPhone/iPod Touch и использовать встроен ную камеру и фотобиблиотеку. Приложение А. В нем описано использование списков свойств для сохранения и восстановления состояния приложения. Это создает види мость, что ваше приложение не завершается, когда пользователь нажимает кнопку Ноте (Домой). Приложение Б. Здесь вы научитесь программно вызывать приложе ния iPhone из вашего собственного и публиковать службы, которые могут быть использованы другими приложениями iPhone.
Глава 1 Objective-C и Cocoa
Эта глава представляет основные свойства языка программирования O bject-C в среде Cocoa. Структура данной главы следующая. В разд. 1.1 описывается основная концепция классов в Objective-C. Вы научитесь объявлять, определять и использовать новый класс, а также ознакомитесь с наиболее важными классами и типами данных Cocoa. В разд. 1.2 вы изучите управление памятью в ОС iPhone. Вы научитесь создавать и удалять объекты, а также узнаете правила использования объ ектов платформы Cocoa и других платформ. Разд. 1.3 раскрывает тему протоколов Objective-C. Вы научитесь при менять существующие протоколы и объявлять новые. Из разд. 1.4 вы узнаете об отличительной черте языка Objective-C, ко торая позволяет получать доступ к переменным экземпляра класса через точку (dot notation). Концепция категорий — предмет изучения в разд. 1.5. Категории по зволяют расширять существующие классы посредством добавления но вых методов. Позиционирование — это метод, незначительно отличающийся от ка тегорий. Оно позволяет замещать класс одним из его потомков. Это об суждается в разд. 1.6. Исключения и обработка ошибок присущи любому современному язы ку программирования. Разд. 1.7 описывает эти обе техники и их использо вание. В разд. 1.8 освещена концепция программирования «ключ-значение» (key-value coding, KVC). KVC — это важный и широко используемый в Cocoa метод. KVC позволяет получить непрямо!! доступ к свойствам объекта. Затем вы научитесь использовать многопоточность в вашем iPhoneприложении (разд. 1.9). Cocoa упрощает применение многопоточности, и шаг за шагом вы узнаете, как выполнять задачу в фоновом режиме. Итоги этой главы будут подведены в разд. 1.10. Нам предстоит изучить многое, поэтому давайте начнем.
17
1.1. Классы В объскгно-ориентированных языках, таких как Java, объект инкап сулирует атрибуты и предоставляет методы. Эти методы могут использо ваться окружающей средой (например, другими объектами), чтобы изме нить состояние объекта или взаимодействовать с ним, чего можно достичь, не раскрывая окружающей среде настоящей реализации поведения объекта. В O bjective-C для создания нового класса его сначала нужно объявить, используя ключевое слово interface, а затем — определить посредством ключевого слова implementation. Объявление и определение обычно описываются в двух разных файлах. Объявление, как правило, содерж ит ся в файле с расширением Н и названием, совпадающим с именем клас са. а реализация (также имеющая то же название, что и класс) - в файле с расширением М. Части, отвечающие за объявление и определение, исполь зуют директивы компилятора. Директива компилятора - эго инструкция компилятору Objective-C; она предваряется знаком О бъявление поме чается для компилятора директивой @interface, а определение класса — днрективой @imp 1emen ta tion.
1.1.1. Объявление класса Чтобы объявить класс MyClassName в качестве наследника класса My Ра rent Name, вы можете написать следующее: (3 interface MyClassName : МуРаrent Name i объявление атрибутов объявление методов
^end Здесь мы говорим компилятору, что объявляется новый тип класса
MyClassName. Он является наследником класса MyParentName. Мы так же приводим список всех переменных экземпляра класса внутри ф игур ных скобок. Методы объявляются после закрывающей фигурной скобки перед директивой компилятора ©end. Существует несколько важных аспектов объявления ©interface. 1. Атрибуты, стоящие внутри фигурных скобок, являю тся переменны ми экземпляра класса. В процессе выполнения каждый класс имеет уни кальный объект класса и ноль или более экземпляров. Каждый экземпляр (объект) MyClassName имеет собственные значения этих атрибутов. У ни кальный объект класса доступа к этим переменным экземпляра не имеет. 2. Объявленные методы могут быть методами экземпляра либо класса. Метод экземпляра вызывается отправлением сообщения фактическому
18
экзем пляру (объекту) класса. Метод класса не требует наличия экзем пля ра объекта. Вы вызываете метод класса, посылая сообщение уникальному объекту класса. В Objective-C каждый класс в ходе выполнения програм мы имеет только один объект. Метод экземпляра объявляется/определя ется посредством префикса «-», а метод класса объявляется/определяется с помощью префикса «+». Например, - (Address *) get Address; является методом экзем пляра, а + ( i d ) getANewInstance; — методом класса. 3. O bjective-C не поддерживает переменных класса, однако вы можете использовать уже знакомое вам ключевое слово static в файле реализа ции данного класса. Это позволит методам экземпляра (с префиксом « -» в определении) получать доступ к единственному значению переменной, общей для всех экземпляров данного класса. Если вы определите статиче скую переменную внутри метода, то этот метод будет единственным, им е ющим доступ к этой переменной. Если вы поместите определение статиче ской переменной снаружи реализации класса, то все методы будут иметь доступ к данной переменной.
1.1.2. Как использовать другие объявления Как Cocoa-разработчику вам понадобится возможность использования классов, написанных другими разработчиками. К тому же, если объявле ние и определение ваших классов находятся в разных файлах, вам потре буется проинформировать компилятор о местонахождении объявления класса внутри файла реализации. Если вы используете имя класса без доступа к его методам или пере менным экземпляра, вы можете просто применить директиву ©class. Это дает компилятору достаточно информации, чтобы успешно создать код. Обычно директива @class используется в объявлениях класса. Н ап ри мер, взгляните на следующее объявление: -(id) init{ sel f = [super init]; keys = [ [NSMutableArray arrayWithCapacity:1] retain] ; r e t u r n self;
) - (void)dealloc { [keys release]; [super dealloc];
) @end
Листинг 12.5 демонстрирует объявление класса делегата приложен ния. Как уже было сказано, делегат приложения будет создавать главное окно и присоединять к нему текстовое представление. Затем он исполь зует класс GoogleMapsWrapper для нахождения расстояния между дву мя адресами и вывода информации пользователю в текстовом представ лении (рис. 12 6). Класс оперирует ссылками на классы UITextView и GoogleMapsWrapper.
329
7:35 AM
„iisil Carrier 9
The distance between: 1600 Pennsylvania Ave NW, Washington, DC 20S00 and Army Navy Dr & Fern St, Arlington, VA
22202 is: 5269.55 m eters
Рис. 12.6. Снимок экрана геокодирующего приложения, показывающего расстояние
между двумя почтовыми адресами Листинг 12.5. Объявление класса делегата приложения, используемого в про грамме для геокодинга #i m p o r t < U I K i t / U I K i t . h > #i m p o r t < C o r e L o c a t i o n / C o r e L o c a t i o n .h > ftimport ' G o o g l e M a p s W r a p p e r .h * ^interface Location2AppDelegate : NSObject U l W i n d o w *window; U I T e x t V i e w *textView; G o o g l e M a p s W r a p p e r *gWrapper;
{
) @property
@end
(nonatomic,
retain)
U l W i n d o w ^window;
Л и сти н г 12.6 показы вает реализац ию класса делегата прилож ения. М етод a p p l i c a t i o n D i d F i n i s h L a u n c h i n g : настраи вает п ользова тельски й и н терф ейс и вы зы вает м етод f in d D is t a n c e F r o m A d d r e s s : t o A d d r e s s : , чтобы най ти расстояние м еж ду Б ел ы м дом ом и П ентагоном. Затем результат ф орм ати руется и св язы в ается со свойством t e x t объекта текстового представления. Листинг 12.6. Реализация класса делегата приложения, используемого в про грамме для геокодинга # i m p o r t "L o c a t i o r i2AppDelega t e .h ■ S i m p o r t ■G o o g l e M a p s W r a p p e r .h" #d e f i n e FROM__ADDRESS @ " 1 6 0 0 P e n n s y l v a n i a A v e NW, W a s h i n g t o n , D C 2 0 5 0 0 е # d e f i n e T O ^ A D D R E S S @ " A r m y N a v y D r & F e r n St, A r l i n g t o n , V A 22202'’ ^implementation Location2AppDelegate ^ s y n t h e s i z e window; -(double) findDistanceFromAddress:(NSString*) from t o A d d r e s s : ( N S S t r i n g *) to{ f l o a t lat. Ion; CLLocation *fromLocation; C L L o c a t i o n *toLocation; i f ([gWrapper f i n d G e o I n f o F o r A d d r e s s : f r o m a n d R e t u r n L a t i t u d e :& l a t a n d L o n g i t u d e : & l o n ] s = 0){ f r o m L o c a t i o n = [ [ [C L L o c a t i o n alloc) initWithLatitude:lat longitude:lon) a utorelease]; if ([g W r a p p e r f i n d G e o I n f o F o r A d d r e s s : t o a n d R e t u r n L a t i t u d e : & l a t
330
andLongitude:&lon] == 0}{ toLocation = I [{CLLocation alloc] initWithLatitude:lat longitude:Ion] autorelease]; return [toLocation getDistanceFrom: fromLocation);
) )
return -1;
re t u r n -1;
)
-(void) applicationDidFinishLaunching: (UIApplication ^ a p p l i c a t i o n ( win daw = [[UlWindow alloc] initWithFrame: [[UlScreen mainScreen] bounds]]; CGRect reetFrame = [UlScreen mainScreen] .applicationFrame; textView = [ [UITextView alloc] initWithFrame:reetFrame) ; textView.editable = NO; gWrapper = [ [GoogleMapsWrapper alloc) init]; (gWrapper addKey:@"ABQIAAAAERNgBiSqUogvAN307LdVDx* -SkQMtcTv7 5TNSQ97 Pe jimT5pm-MAxSTQGma_Y ■ "CBaUccn3pRis8XjkxM8W]; NSMutableString *outStr = [ [NSMutableString alloc] initWithFormat:@"The distance between: \n %S \n and" "\n %@ \n is:\n \t \t %.2f meters\n", FROMJTCDRESS, TOJ0DRESS, (self findDistanceFromAddress:FROM_ADDRESS toAddress:TO_ADDRESS]); textView.text = outStr; (window addSubview: textView]; [window makeKeyAndVisible];
-(void) dealloc { (gWrapper release] ; (textView release); [window release) ; [super dealloc];
) ©en d
12.4. Отслеживающее приложение с картами местности Многие iPhone-приложения требуют отображения карты местности. Если вы столкнулись с задачей разработки подобной программы, можете использовать Google Maps API и класс UlWebView. В этом разделе мы разработаем отслеживающее приложение. Сначала программа будет отслеживать и накапливать настраиваемое количество дви жений устройства. Пользователь может прервать отслеживание или подо ждать, пока не запишется заданное количество передвижений. В ином случае пользователь сможет пройтись по записям передвижений и визуализировать (на карте) географическое положение и время каждой записи передвижения. Листинг 12.7 показывает объявление класса делегата приложения. Д е легат приложения будет иметь контроллер навигации для пользователького интерфейса и» таким образом, будет оперировать ссылками на пред* ставление и контроллер навигации. Листинг 12.7. Объявление класса делегата отслеживающего приложения # import # import "LocationsViewController.h*
331
@ interface L o c a t i o n 3 A p p D e l e g a t e : N S O b j e c t U l W i n d o w *window; L o c a t i o n s V i e w C o n t r o l l e r *ctrl; UINavigationController * n avCtrl; ©property
(nonatomic,
retain)
{
U l W i n d o w * window;
@end
Л и сти н г 12.8 дем онстрирует реал и зац и ю класса делегата прилож ения. М етод a p p l i c a t i o n D i d F i n i s h L a u n c h i n g : просто создает контроллер представления ти п а L o c a t i o n s V i e w C o n t r o l l e r и и сп о л ьзу ет его в ка честве корневого д л я контроллера навигации. З атем п редставлен и е кон троллера н авигации д об ав л яется в качестве дочернего к главн ом у окну, после чего последнее делается видимы м. Листинг 12.8. Реализация класса делегата отслеживающего приложения #import " L o c a t i o n 3 A p p D e l e g a t e . h " @ implementation L o c a t i o n 3 A p p D e l e g a t e ©synthesize window; - (void)a p p l i c a t i o n D i d F i n i s h L a u n c h i n g : (UIApplication ♦^application { w i n d o w = [(UlWindow alloc] i n i t W i t h F r a m e : [( U l S c r e e n m a i n S c r e e n ] b o u n d s ] ]; C trl = ( [ L o c a t i o n s V i e w C o n t r o l l e r a l l o c ] initWithNibName:nil bundle:nil]; n a v C t r l = [ ( U I N a v i g a t i o n C o n t r o l l e r alloc] i n i t W i t h R o o t V i e w C o n t r o l l e r : c t r l ]; [window a d d S u b v i e w : n a v C t r l . v i e w ] ; [window m a k e K e y A n d V i s i b l e ] ;
) — (void)d e a lloc { [ctrl r e l e a s e ] ; [navCtrl r e l e a s e ] ; [window r e l e a s e ] ? [super d e a l l o c ] ;
) @end
В ли сти н ге 12.9 объявлен наш к онтроллер представлен и я. О н заи м ствует C L L o c a t io n M a n a g e r D e le g a t e , так к ак будет делегатом создан ного им дисп етчера локаций. О н объ явл яет две к н о п ки н а п ан ели навига ц ии д л я остановки отсл еж и ван и я передвиж ен ий — перехода к следую щ ей и преды дущ ей запи сям . П равая кн оп ка панели нави гац и и будет исполь зоваться как д л я остановки отслеж и вания, так и в качестве киопки Next (Д алее). В дополнение кон троллер представления опери рует ссы лкой на веб-представление д л я визуал и зац и и отслеж енны х локаци й . Листинг 12.9. Объявление класса контроллера представления LocationsViewControDer, используемого в отслеживающем приложении # import < U I K i t / U I K i t . h > # import < C o r e L o c a t i o n / C o r e L o c a t i o n .h> @ interface L o c a t i o n s V i e w C o n t r o l l e r : UlViewController CLLocationManager *locationMgr; NSUInteger noUpdates;
332
{
N SMutabl e A r r a y *locations; U l W ebView *webview ; UI BarButtonltem *rightButton, NSUInteger current;
*leftButton;
} ©end
Л истинг 12.11 показывает реализацию контроллера представления. В методе инициализации in itW ith N ib N am e:b u n d le : мы создаем две кнопки. Правая кнопка называется Stop (Стоп), левая — Previous (Предыду щ ий). Л евая кнопка сделана недоступной. Метод lo a d v ie w создает и настраивает диспетчер локаций. Расстояние, которое требуется обновить, устанавливается равным MIN_DI STANCE. В до полнение создается веб-представление. Оно шшциализируется с помощью содержимого HTM L-файла, который хранится в упаковке приложения. Файл шарЗ . h tm l показан в листинге 12.10. Этот файл — один из многих файловпримеров, которые демонстрируют использование Google Maps API, предо ставленных Google. Как вы увидите далее, мы будем использовать JavaScript для динамической модификации внешнего вида карты местности. Листинг 12.10. HTML-страиица, используемая для отображения карты Google для приложения геослежения < 1D O C TY P E html PUBLIC "- //W3C//DTD XHTML 1.0 Strict//EN“ "http://www.w3 .org/ TR/xhtmll/DTD/xhtmll-strict .dtd"> chtml x m l n e = Bhttp: //www.w3 .org/1999/xhtml" x m l n s :v= " u r n :schemas-micros of t -com: vml ■> <meta http-equiv=*content-type" content^-text/html; charset=utf-8"/> Geo-tracking Example < s cript erc= "http:/ /maps.go o g l e .com/maps?fi le-api&v = 2 & a m p ;key=K* type= "t ex t /Ja v aScript"> < scr i p t t y p e s "text /JavaScript ■> function initialize() {) < b o d y onload = " i n i t i a l i z e () • o n u n l o a d-'GUnloadO ■> < d i v id="map_canvas" etyle-"width: 500px; height: 50 0 p x “>
П олучая обновления информации о местоположении, мы сохраняем эти локации в массиве. Получив NO_OF_LOCATlONS, мы делаем доступ ной левую кнопку панели, изменяем ее заголовок иа Next (Далее) и указы ваем первую локацию на карте. М етод c e n te r M a p : используется для отображения локации на карте. В качестве входных параметров методу передается порядковый номер лока ции в массиве отслеженных местоположений. Он извлекает информацию о широте и долготе, устанавливает центр карты в этой точке и центриру ет карту. В дополнение он открывает информационное окно, отображаю щее время, когда местоположение было отслежено. Все это делается с по мощью JavaScript, как показано ниже. Наконец, мы выполняем код
333
Jav aS crip t посредством метода веб-представления s t г in g B y E v a lu a t in g J a v a S c r i p t F r o m S t r i n g :. var map = new GMap2(document.getElementById(" map_canvas")); map.secMapType(G_HYBRID_MAP); map. setiCenter (new GLatLng (37 .331689 , -122.030731), 18); m ap.panTo(map.getCenter{)); map.openInfoWindow(map.getCenter(), d o c u m e n t .crea с e T e x t N o d e ("L o c : (1/1), Time: 2008-08-06 19:51:27 -0500"));
Н и ж е изображ ен сним ок экран а отслеж иваю щ его прил о ж ен и я во вре мя записи передвиж ений (рис. 12.7), а такж е во врем я п росм отра одной из записанны х л окаци й (рис. 12.8). -iiiCarrier ^
pTeviEHii
7:59 A M
L o c a t io n s : 2 0
GS
stop
Р и с . 1 2 .7 . С нимок экрана отслеж и ваю щ его п ри л ож ен и я во врем я за п и си п ередв иж ен и й
..■aCarrier ^
Previous
8:00AM
В
Locations; 20
Loc: (1/1), Time: 2010-01-22 07:59:29 -080^
Р и с . 1 2 .8 . С н и м ок экрана отслеж и ваю щ его п р и л ож ен и я во врем я п росм отр а локации
334
Приложение сталкивается с некоторыми этическими проблемами, а может, и вопросами легальности. Если вы захотите запустить данное приложение и спрятать устройство в чьей-нибудь сумке или автомобиле, лишний раз подумайте* Незаконная слежка не только неэтична, но и мо жет привести к серьезным последствиям вплоть до тюрьмы. Можно моди фицировать приложение и добавить формирующиеся в реальном времени отчеты о передвижениях, доставляемые заинтересованным лицам. Оста вим это вам в качестве упражнения. Листинг 12.11. Реализация класса контроллера представления LocationsViewController, используемого в отслеживающем приложении i i m p o r t "Locat ionsViewCont rol ler. h “ tidefine NO_OF_LOCATIONS 100 #define MIN_DISTANCE 100 Qimpleinentat ion Loca t ions Vi ewCon t го 1 ler — (void) locationManager: (CLLocationManager *)m anager d idU p d a t e T o L o c a t i o n : (CLLocation *) newLocat ion f r omLocation: (CLLocation *) oldLocation( noUpdates++; [locations addObject :newLocation] ; sel f . t i t l e = [NSString stringWithFormat:®"Locations: % i “ , noUpdates]; i f ( n o U p d a t e s == 1) { [self c e n t e rMa p : 0 1 ;
) if
}
(noUjpdates >= NOjOF_LOCATIONS) { [locationMgr stopUpdatingLoeation] ? l eftButton.enabled = YES; rightButton.title = @"Next“ ; current = 0; [self cent e rMa p :current];
)
— (void) cent erMap: (NSUInteger) index{ CLLoca t i o n *loc - [locations objectAtlndex:index]; N S S t r i n g *js = [NSString stringWithFormat: @"var map = " "n e w GMap2 (d oc u m e n t .get El ement By Id (\ "map_canvas \ ■)); “ “m a p .setMapType (G_HYBRID_MAP); ■ “map.setCenter(new GLatLngltlf, % l f ) , 18);" “m a p .panTO (map.getCenter ());" ’’m a p .openlnf owindow (map.getCenter (J, ■ "document ^createTextNode (\ “L o c : (% i / % i ), T i m e : %G\ *)),;“ , [loc coordinate]'.latitude, [loc c o o r d i n a t e ] .longitude, index+1, (locations count], [loc t i m estamp]]; [webview stringByEvaluatingJavaScriptFroiitStrlng: j s ] ;
} — (id) i n i t W i t h N i b N a m e : (NSString *) nibNameOrNil b undle: (NSBundle *)nibBundleOrNil ( if (eelf= [super initWithNifcNaime: nibNameOrNil Ь ш к Ц е : nibBundleOrNil]) { rightButton * [ [UIBarButtonltem alloc] initWithTitle:0*Stop" s t y l e :U I B a r B u t t o n l t e m S t y l e D o n e target:self a c t i o n :© s e l e c tor(stopOrNext)]; s e l f .navigat i o n l t e m .rightBarBut tonl t em = r i g h t B u t t o n ? leftButton - [[UIBarButtonltem alloc] i n i t w ithTitl e :@ "Pre v i o u s ■ sty l e :UIBarButtonltemStyleDone target reelf act i o n :^selector (preV) ] ; s e l f .navigationl tem. le ftBarBut t on 11 e m = lef t B u t t o n ; l eftButton.enabled - NO;
} return- s e l f ;
335
} -(void) s t o p O r N e x t { i f ([ r i g h t B u t t o n . t i t l e i s E q u a l T o S t r i n g : @ " S t o p " ] == Y E S > { [locationMgr stopUpdatingLocationJ ? l e f t B u t t o n . e n a b l e d = YES; rig h t B u t t o n . t i t l e = ©"Next"; cu r r e n t = 0; [self c e n t e r M a p :c u r r e n t ];
) else i f (current < ([loc a t i o n s c o u n t ] - l ) ) { [self c e n t e r M a p : + + c u r r e n t ] ;
}
}
-(void)prev{ i f (current > 0 & &
(current < c u r r e n t = c u r r e n t -1; [self c e n t e r M a p :c u r r e n t ];
)
[locations
c o u n t ) ) ){
}
-(void) l o a d V i e w { locations = [[NSMutableArray arrayWithCapacity:10] retain]; l o c a t i o n M g r = [ [ C L L o c a t i o n M a n a g e r a l l o c ] init]; locationMgr.distanceFilter = M I N _ D I S T A N C E ; l o c a t i o n M g r . d e l e g a t e - self; n o U p d a t e s = 0; CG R e c t r e e t F r a m e = [Ul S c r e e n m a i n S c r e e n ] .a p p l i c a t i o n F r a m e ; w e b V i e w = [ [ U l W e b V i e w alloc] i n i t W i t h F r a m e :r e e t F r a m e ] ; NSString *htmlFilePath = [ [ NSBundle m a i n B u n d l e ] pathForResource:@"map3" ofType:@"html"] ; NSData * d a t a = [NSData d a t a W i t h C o n t e n t s O f F i l e : h t m l F i l e P a t h ] ; [webView l o a d D a t a s d a t a M I M E T y p e : @ " t e x t / h t m l " t e x t E n c o d i n g N a m e :@ "ut f -8" b a s e U R L : [ N S U R L U R L W i t h S t r i n g : ® " h t t p : / / m a p s . g o o g l e . c o m / "]]; [locationMgr startUp d a t i n g L o c a t i o n ] ; self. v i e w = webView;
} -(void) d e a l l o c
{ [rightButton r e l e a s e ] ; [leftButton r e l e a s e ] ; [ l o c a t i o n M g r r e l ease]; [locations release]; [super d e a l l o c ] ;
} @end
12.5. Работа с почтовыми индексами П очтовая служ ба С оединенны х Ш татов (U n ite d S ta te s P o stal Service (U S P S )) исп ользует кодирую щ ую систему д л я эф ф ек ти вн о й доставки по чты в пределах СШ А . П одразумевается, что к аж ды й п отен ц и альн ы й по лучатель почты ж ивет в определенной зоне, представл ен н о й почтовым индексом (рис. 12.9). Т еоретически почтовы е и н дексы п р и вязан ы к гео граф ическом у местоположению . Сущ ествую т различны е доступны е базы дан н ы х п очтовы х индексов. О н и отличаю тся точностью и ценой. М ож но представи ть базы данны х, со относящ ие ш ироту и долготу к данном у почтовом у индексу, к ак описы ваю щ ие центр области, обслуж иваю щ ей дан ны й почтовы й индекс. Суще-
336
ствует несколько мест, где вы можете приобрести базу данных почтовых индексов Соединенных Штатов. Вы даже можете бесплатно загрузить акутальную базу с сайта [1]. Содержимое файла почтовых индексов США [1] разделено запятыми. На пример, последние несколько записей в файле выглядят следующим образом: 89508, Reno, NV, 39. 5296329,-119.8138027,Washoe 91008 ,Duarte, СА, 34 .1394513 ,-117 .9772873,Los Angeles 92058, Oceanside, CA, 33.1958696,-117.3794834, San Diego 94 50 5, Discovery Bay, CA, 37.9085357, -121.6002291 rContra Costa 95811, Sacr ament о tCA,38.5815719,-121.4943996, Sacramento
Ч тобы ответить на запросы типа «получить почтовые индексы в радиу се 10 м иль от 68508», необходимо выполнить следующие действия.
Р и с . 1 2 .9 . Зоны почтовых индексов Соединенных Штатов [2 |
1. С оздайте SQ L ite-таблицу z ip c o d e s . Для эффективного поиска ре комендуется поместить данные в базу. Для хранения почтовых индексов мож но использовать следующую таблицу: TABLE zipcodes < zipcode int N O T NULL PRIMARY KEY, latitude longitude float(10,8), state v a r c h a r ( 2 ) , city varchar{128) , county v a r c h ar3); B O O L y _ b i g _ d i f f e r e n c e = ( f a b s ( y — a c c e l e r a t i o n V a l u e s [1]) >3); B O O L z _ b i g _ d i f f e r e n c e = (f a b s ( z - a c c e l e r a t i o n V a l u e s 12]) >3); int a x e s = x _ b i g _ d i £ f e r e n c e + y _ b i g _ d i f f e r e n c e + z _ b i g _ d i f f e r e n c e ;
i f (axes>= 2){ N S L o g (@ "i P h o n e S h a k e n
19 );
} //ориентация i f {B E T W E E N (X , -0.0 5 , 0.05) && B E T W E E N ( y , -1, - 0 . 9 5 ) & & BETWEEN(z, -0.05, 0 . 0 5 Ж N S L o g ( @ " i P h o n e p e r p e n d i c u l a r to g r o u n d # H o m e b u t t o n d o w n " ) ?
> if (BETWEEN (X, -0. 05', 0.05)
&& B E T W E E N (y, 0.95, BETWEEN{z, -0.05, 0.05)){ N S L o g ( @ “i P h o n e p e r p e n d i c u l a r t o g r o u n d ,
1)
&&
H o m e b u t t o n up " ) ;
} // п р и ж а т и е / т о л ч о к B O O L x _ c h a n g e = ( f a b s ( x - a c c e l e r a t i o n V a l u e s [ 0 J ) < 1); B O O L y ^ c h a n g e = (f a b s ( y - a c c e l e r a t i o n V a l u e s [1]) < 1); B O O L z ^ c h a n g e = (fabs(z — a c c e l e r a t i o n V a l u e s [2J ) > = 3)? if (x _ c h a n g e & & y _ c h a n g e && z _ c h a n g e ) { if (z > a c c e l e r a t i o n V a l u e s [2)) NSLog(G"hug");
else N S L o g (@ Ho u n c h ");
) a c c e l e r a t i o n V a l u e s [0] a c c e l e r a t i o n V a l u e s (1] a c c e l e r a t i o n V a l u e s [2]
= x; = y; = z;
} - (void) a p p l i c a t i o n D i d F i n i s h L a u n c h i n g ; ( U I A p p l i c a t i o n * ) a p p l i c a t i o n CGRect fullscreen = [[UlScreen mainScreen] bounds]; w i n d o w - [ [ U l W i n d o w all o c ] i n i t W i t h F r a m e :f u l l s c r e e n ] ; UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer]; a c c e l e r o m e t e r . u p d a t e l n t e r v a l = 0.1; // 10Hz a c c e l e r o m e t e r . d e l e g a t e = self; [w i n d o w m a k e K e y A n d V i s i b l e ] ;
) - void) d e a l l o c { [window r e l e a s e ] ; [super d e a l l o c ] ;
) @end
344
{
13.2. Аудио В этом разделе мы рассмотрим проигрывание коротких звуковых фай лов ( продолжительностью менее 30 секунд). Чтобы воспроизвести корот кий звуковой файл, необходимо зарегистрировать файл как системный звук и получить его дескриптор. После этого, используя дескриптор, вы можете проиграть этот звук. Если вы закончили работу и не хотите вопроизводить его снова, нужно высвободить этот системный звук. Чтобы зарегистрировать звуковой файл в качестве системного звука, используйте функцию A u d ioS ervicesC reateS ystem S ou n d ID (), объ явленную следующим образом: OSStatus AudioServicesCreateSystemSoundID( CFURLRef inFileURL, SystemSoundlD *outSystemSoundID)
Первый параметр - это CFURLRef (или его аналог, экземпляр NSURL), а второй — ссылка SystemSoundlD. Эта переменная, 32-битное беззна ковое целое, будет хранить ID системного звука. Возвращаемое значение должно быть 0, что означает успешную регистрацию системного звука. Чтобы воспроизвести системный звук, используйте функцию A u d io S e r v ic e sP la y S y s te m S o u n d ( ) , объявленную как void AudioServicesPlaySystemSound(SystemSoundlD ip.SystemSoundlD)
Вы передаете дескриптор системного звука, полученный от предыду щей функции. Чтобы включить вибрацию, можете использовать предо пределенный системный идентификатор k System SoundID _V ibrate. Д ля высвобождения системного звука используйте функцию A u d io S e r v ic e s D is p o s e S y s te m S o u n d lD O , объявленную следую щим образом: OSStatus AudioServicesDisposeSystemSoundID(SystemSoundlD inSystemSoundID)
В качестве параметра передается дескриптор системного звука, полу ченный от функции регистрации. П ример. Создадим приложение, проигрывающее звуковой файл каж дую минуту. Листинг 13.3 показывает объявление класса делегата прило жеиия. Обратите внимание на директиву #in c lu d e для файла заголовка . Вам также нужно добавить библио теку A u d io T o o lb o x . framework к проекту в XCode. Листинг 13.3. Объявление класса делегата приложения, демонстрирующего проигрывание небольших звуковых файлов Кimport include
345
©interface A u d i o A p p D e l e g a t e
: NSObject
{
UlWindow *window; SystemSoundlD audi o S I D ;
} @end
Л и сти н г 13.4 дем онстрирует реали зац и ю класса делегата п р и ло жения. Звуковой ф ай л хран и тся в упаковке при лож ен и я. В методе a p p l i c a t i o n D i d F i n i s h L a u n c h i n g : м ы сн ачала получаем абсолю тны й путь к ф ай лу s o u n d , c a f . Затем д л я этого пути создается объект NSURL, используя м етод f i l e U R L W i t h P a t h : i s D i r e c t o r y П осле этого р е гистрируется систем ны й звук. Т и п ы CFURL и NSURL взаимозаменяемы» поэтом у мы передаем объект NSURL вм есто ссы лки н а CFURL, CFURLRef. Если не возн икло ош ибок, зв у к воспроизводится. М етод p l a y : проигры вает звук, после чего н астраивает тай м ер на соб ственны й вы зов раз в минуту. Листинг 13.4. Объявление класса делегата приложения, демонстрирующего проигрывание небольших звуковых файлов timport " A u d i o A p p D e l e g a t e . h " @ implementation A u d i o A p p D e l e g a t e
-(void) a p p l i c a t i o n D i d F i n i s h L a u n c h i n g : ( U I A p p l i c a t i o n * ) a p p l i c a t i o n { CG R e c t
screenFrame *
window =
[[ U l S c r e e n
[ [ U l W i n d o w alloc]
NSString *filePath =
mainScreen]
[ [NS B u n d l e m a i n B u n d l e ]
pathForResource:®"sound" NSURL
*aFileURL =
OSStatus
bounds];
i n i t W i t h F r a m e :s c r e e n F r a m e ] ;
o f T y p e : @ Hc a f "];
[NSURL f i l e U R L W i t h P a t h : f i l e P a t h i s D i r e c t o r y :N O ] ;
error =
AudioServicesCreateSystemSoundlD( (CFURLRef)aFileURL,
&audioSID);
i f (error == 0) [self p l a y i n i l ] ; [ window m a k e K e y A n d V i s i b l e ] ;
) -(void) play: (NSTimer*) theTim e r { AudioServicesPlaySystemSound(audioSID) ; // н а с т р а и в а е м е ж е м и н у т н о е в о с п р о и з в е д е н и е [ NSTimer s c h e d u l e d T i m e r W i t h T i m e l n t e r v a l :60.0 t a r g e t :s e l f s e l e c t o r :© s e l e c t o r ( p l a y :) u s e r l n f о :n i l
repeats:N0];
1 -(void) d e a l l o c
{
AudioServicesDisposeSystemSoundXD (audioSID); [ w i ndow r e l e a s e ] ;
[super d e a l l o c ] ;
} @end
346
13.3. Видео Чтобы воспроизвести видео в вашем приложении, используйте класс
MPMoviePlayerController. Создайте и инициализируйте его экзем пляр, после чего запросите воспроизвести видео. Этот контроллер про игрывает видео в полноэкранном режиме. Когда воспроизведение закон чено, экран приложения снова становится видимым. Следующий код воспроизводит файл MyMovie.m4v, хранящийся в упаковке приложения. NSString *filePath = [ [NSBundle main.Bundle] pathForResource:@"MyMovie* of Type:8"m4v"]; NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; MPMoviePlayerController *movieController = [[MPMoviePlayerController alloc] initWithContentURL:fileUrl]; movieController. backgroundColor = [UlColor grayColor]; movieController .movieControlMode = MPMovieControlModeVolumeOnly; [movieController play];
Данный код сначала находит полный путь к видеофайлу в упаковке и использует его для создания экземпляра NSURL. Затем создается экзем пляр MPMoviePlayerController, инициализирующийся посредством метода initWithContentURL:, которому передается экземпляр NSURL. Опционально мы можем установить цвет фона и режим управления. Д ля свойства movieControlMode можно определить (или принять значение по умолчанию) MPMovieControlModeDefault для появ ления стандартных элементов управления (кнопок начала и остановки воспроизведения, временной шкалы и т. д.). Чтобы скрыть все элемен ты управления, используйте MPMovieControlModeHidden. Метод MPMovieControlVolumeOnly используется для отображения только ре гулятора громкости. После фазы инициализации контроллер воспроизводит видео с по мощью метода p la y .
13.4. Информация об устройстве Класс UlDevice используется для предоставления информации о вашем iPhone/iPod Touch. Существует единственный экземпляр класса, который можно получить с помощью метода класса currentDevice. Рас смотрим фрагменты информации, которые вы можете получить посред ством данного экземпляра. • Уникальный идентификатор. Вы можете получить строку, уникаль но идентифицирующую ваш iPhone, с помощью u n i q u e l d e n t i f i e r , объявленного следующим образом: ©property(nonatomic,
readonly, retain) NSString *uniqueIdentifier
347
• О перационная система. П олучить им я оп ерацион ной систем ы м ож но посредством свойства sy stem N a m e , объявл ен н ого как ©property(nonatomic,
readonly,
ret a i n )
NSString
*uniqueldenti£ier
• Версия операционной системы. Вы м ож ете п олучить версию о п ера ционной систем ы с пом ощ ью свойства s y s t e m V e r s i o n . О н о о б ъ яв лено следую щ им образом: 8property(nonatomic.
readonly,
retain)
NSString
*systemVersion
• М одель. О п ред елить разли ч и е м еж ду iP h o n e и iP o d T o u ch м ож но по средством свойства m o d e l, объявленного как ©property(nonatomic,
readonly,
r etain)
NSString
*model
• О риентация. О риентацию устройства м ож но у стан ови ть с помощ ью свойства o r i e n t a t i o n . С войство объявлен о следую щ им образом: S p r o p e r t y ( n o n a t o m i c , readonly)
UIDeviceOrientation
orientation
Возмож ные значения: • U ID e v i с e O r i e n t a t i onU nknow n; ^ U I D e v ic e O r ie n ta tio n P o r tr a it; * U I D e v ic e O r ie n ta tio n P o r tr a itU p s id e D o w n ; AU ID e v i с eO r i e n t a t i o n L a n d sс a p e L e f t ; * U I D e v ic e O r ie n t a t i o n L a n d s c a p e R ig h t ; ^ U I D e v ic e O r ie n t a t io n F a c e U p ; a UIDe v i c e O
r i e n t a t io n F a c e D o w n .
13.5. Производство и просмотр снимков В этом разделе вы научитесь и сп ользовать кам еру д л я производства снимков. Вы узнаете, что прям ой доступ к кам ере ил и би б ли отеке ф ото граф ий отсутствует, поэтом у требуется использовать предоставленны й контроллер, которы й обрабаты вает взаим одействи е с пользователем при производстве и редактировании сним ков. К онтроллер предоставляет ко нечный вари ант изображ ения. Т от ж е контроллер м ож но и сп ользовать при просм отре сним ков, хранящ ихся в пользовательской библиотеке. С трук тура раздела следую щ ая. В подразд. 13.5.1 будут рассм отрен ы основные ш аги, необходим ы е д л я обеспечения доступа к кам ере и фотобиблиотеке, а в подразд. 13.5.2 — подробны й пример, дем онстрирую щ ий производство и просм отр сним ков.
348
13.5.1. Общий подход Чтобы получить доступ к камере или просмотреть снимки из пользова тельской библиотеки, необходимо использовать предоставляемый вам си стемой интерфейс. Главный класс, используемый для производства сним ков и просмотра уже существующих, - UllmagePickerController. Для производства или просмотра снимков выполните следующие действия. 1. П роверьте доступность действия. Хотите ли вы сделать новый сни мок или просмотреть уже существующий, необходимо проверить, доступ на ли данная функция. Метод класса UllmagePickerController, ис пользуемый для этих целей, - isSourceTypeAvailable:. 2. Создайте экземпляр контроллера. Если заданное действие доступ но, необходимо создать экземпляр UllmagePickerController, ини циализировать его и настроить на нужную функцию. Если тип источника недоступен, создавать контроллер не требуется. 3. Н астройте делегат. Метод UllmagePickerController будет обе спечивать взаимодействие с пользователем во время производства и про смотра снимков. Нужно настроить делегат на объект и реализовать спе циальные методы, чтобы получить результат. Делегат реализует протокол
UIImagePickerControllerDelegate. 4. О тобразите контроллер. Контроллер модально отображается поль зователю с помощью dspjdf метода presentModalViewController: animated: для существующего контроллера представления, передавая экземпляр UllmagePickerController в качестве первого параметра. 5. Обработайте выбор изображения. Когда пользователь выбира ет снимок, вызывается метод делегата imagePickerController :did FinishPickingMediaWithlnfo:. Вам нужно извлечь изображения из словаря и скрыть контроллер, который был модально отображен на экране. 6. Обработайте отмену. Если пользователь отменяет операцию, вызы вается метод делегата imagePickerControllerDidCancel:. Вам тре буется скрыть контроллер, который был модально отображен на экране.
13.5.2. Подробный пример Рассмотрим приложение, демонстрирующее использование класса
UllmagePickerController. Программа предоставляет пользователю два действия на выбор - сделать новый снимок или выбрать уже суще ствующий. В зависимости от выбора пользователя приложение настраи вает экземпляр класса UllmagePickerController и отображает его. Когда пользователь справится с задачей, результат (если он есть) станет фоном основного окна.
349
П рограм м а реали зует два класса — класс делегата п ри л о ж ен и я и про стой контроллер представления. Л и сти н г 13.5 п оказы вает объявлен и е класса делегата при лож ения C a m e r a A p p D e le g a te . Д ел егат п р и лож ен и я использует экзем п л яр класса M a i n C o n t r o l l e r д л я уп р ав л ен и я пользо вательским интерф ейсом. Листинг 13.5. Объявление делегата приложения для работы с камерой # import < U I K i t / U I K i t . h> # import "MainController.h" @ interface CameraAppDelegate : NSObject U l W i n d o w * wind o w ; MainController * viewController;
{
} ©property
(nonatomic,
retai n )
UlW i n d o w * window;
@end
Л и сти н г 13.6 дем онстрирует реализаци ю делегата п ри л о ж ен и я. М етод a p p l i c a t i o n D i d F i n i s h L a u n c h i n g : создает главное окн о и экзем п л яр контроллера представления M a i n C o n t r o lle r . Затем он д о б авл яет пред ставление данного кон троллера в качестве дочернего к главн ом у окну, по сле чего делает главное окно клю чевы м и видимым* Листинг 13.6. Реализация делегата приложения для работы с камерой #import ■CameraAppDelegate.h" @implementation C a m e r a A p p D e l e g a t e ©synthesize wi n d o w ; — (void) a p p l i c a t i o n D i d F i n i s h L a u n c h i n g : ( U I A p p l i c a t i o n *) a p p l i c a t i o n { win d o w = [[UlWindow alloc] i n i t W i t h F r a m e : [ [UlScreen mainScreen] viewController = [MainController alloc]; [w i n d o w addSubview:viewController.view]; [w i ndow makeKeyAndVisible];
bounds]];
) -(void) d e a l l o c [window
[euper
{ release]; dealloc];
) ©end
Л и сти н г 137 показы вает объ явлен и е к о н тро л л ер а пред ставления M a i n C o n t r o lle r . О н заи м ствует д в а п ротокола — U I I m a g e P i c k e r C o n t r o l l e r D e l e g a t e д л я обработки взаи м одей стви я с экземпляром U llm a g e P ic k e r C o n t r o lle r и U I A c t io n S h e e t D e le g a t e , обрабатываю щ ий взаимодействие со списком действий. Листинг 13.7. Объявление класса MainController приложения для работы с камерой ^import < U I K i t / U I K i t . h > в interface M a i n C o n t r o l l e r : UlViewController {
) Send
350
Л истинг 13.8 демонстрирует метод loadView класса Main Controller. Этот метод просто создает полноэкранное представление, на страивает его и связывает со свойством view контроллера представления. Листинг 13.8. Метод loadView класса MainController приложения для работы с камерой -(void)loadView { CGRect reetFrame = (UlScreen mainScreen].applicationFrame; U l V i e w * theView = [[UlView alloc] initWithFrame:reetFrame]; theView.backgroundColor - [UlColor darkGrayColor]; theView.autoresizingMask - UIViewAutoresizingFlexibleHeight UIViewAutoresizingFlexibleWidth; self. v i e w = theView; ItheView release]?
I
) Когда представление завершает загрузку, метод viewDidLoad вызы вается автоматически. В этом методе мы создаем список действий, предла гающий пользователю выбрать, делать новый снимок или выбрать уже су ществующий. Метод устанавливает контроллер представления в качестве делегата и показывает список действий в представлении (листинг 13.9). Листинг 13.9. Метод viewDidLoad контроллера представления -(void) v i e wDidLoad { UIActionSheet * actionSheet = [[UIActionSheet alloc] initwithTitle:§"Choose an option:" delegate:self cancelButton Tit l e :nil destructiveButtonTitle:nil otherButtonTitles :@’New Picture’ , ©■Select a Picture", nil]; [act ionSheet showlnview:self«view] ;
} Л истинг 13.10 показывает метод actionSheet iclickedButtonAt Index:, обрабатывающий нажатия кнопок списка действий. Если была нажата первая кнопка, мы проверяем, доступна ли камера. Д ля этого используется метод isSourceTypeAvailable: класса UllmagePickerController. Метод объявлен как +
(BOOL) isSourceTypeAvailable: (UI ImagePi ckerCon troll er Sour с eType)sour ceType
Единственный параметр типа UllmagePickerControllerSource Туре может принимать следующие значения:
• UIImagePickerControllerSourceTypePhotoLibrary — задает в качестве источника фотобиблиотеку; • UIImagePickerControllerSourceTypeSavedPhotosAlbum — в качестве источника определяет альбом камеры; • UIImagePickerControllerSourceTypeCamera — задает как ис точник встроенную камеру. 351
М етод возвращ ает YES, если заданны й источник доступен, и N0 в противном случае. Е сли кам ера доступна, м етод создает новы й экзем п л яр класса U l l m a g e C o n t r o l l e r и устан авли вает свойство источн и ка s o u r c e T y p e в значен ие U I I m a g e P ic k e r C o n t r o lle r S o u r c e T y p e Camera. С войство s o u r c e T y p e объявлено следую щ им образом: ©property
(nonatomic)
UIImagePickerControllerSourceType sourceType
Если наж ата вторая кнопка, мы повторяем предыдущ ие ш аги с тем исключением, что в качестве источника будем использовать U llm a g e P ic k e r C o n t r o lle r S o u r c e T y p e P h o t o L ib r a r y . После этого мы устанав ливаем делегат контроллера выбора и зображ ения в экзем пляр контроллера представления, устанавливаем свойство a llo w s I m a g e E d it i n g в YES и ото бражаем контроллер выбора изображ ения посредством вы зова метода кон троллера представления p r e s e n t M o d a l V i e w C o n t r o l l e r : a n im a t e d :. Свойство a llo w s I m a g e E d it i n g используется д л я определения, разреш е но ли пользователю редактировать изображ ение перед его возвратом. Листинг 13.10. Метод actionSheetxlickedButtonAtlndex:, обрабатывающий на жатия пользователем списка действий приложения для работы с камерой - ( v o i d ) a c t i o n S h e e t : ( U I A c t i o n S h e e t *) a c t i o n S h e e t clickedButtonAtIndex:(NSInteger)buttonlndex
{ [ac t i o n S h e e t re l e a s e ] ; UllmagePickerController *picker; if ( b u t t o n l n d e x == 0){ if ((J [ U l l m a g e P i c k e r C o n t r o l l e r i s S o u r c e Ty p e A v a i l a b l e : U I I m a g e P i c k e r C o n t r o l l e r S o u r c e T y p e C a m e r a ])
){ return;
} p i c k e r = [ [ U l l m a g e P i c k e r C o n t r o l l e r a l l o c ] init]; picker.sourceType UIImagePickerControllerSourceTypeCamera;
} else
{ if
((![UllmagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypePhotoLibrary])
H return;
> p i c k e r - [ [ U l l m a g e P i c k e r C o n t r o l l e r a l l o c ] i n it]; picker.sourceType = UllmagePickerCo ntrollerSourceTypePhotoLibrary;
} p i c k e r . d e l e g a t e - self; p i c k e r , a l l o w s I m a g e E d i t i n g = YES; [self p r e s e n t M o d a l V i e w C o n t r o l l e r :p i c k e r a n i m a t e d
: YES];
} К ак уж е бы ло сказано, контроллер вы бора изображ ен и й и н ф о р м и р у ет, что пользователь выбрал изображение посредством вызова метода im a g e P i c k e r C o n t r o l l e r : d i d F i n i s h P i c k i n g l m a g e : e d i t i n g l n f о : сво его делегата. М етод объявлен следую щ им образом: - (void) imagePickerController: (UllmagePickerController
352
*)p i c k e r
didF in ishPi eking Image: (Ullmage *) image editinglnfo:(NSDictionary *)editinglnfo
Первый параметр, p ic k e r — это объект, контролирующий интерфейс выбора изображений. Второй параметр — изображение, выбранное поль зователем (возможно, после редактирования), а третий — это словарь, используемый для хранения информации о редактировании (если оно доступно). Для извлечения соответствующей информации из словаря применяются два кл юча: • U llm a g e P ic k e r C o n tr o lle r O r ig in a lIm a g e — для извлечения оригинального изображения (экземпляра U llm age) перед редакти рованием пользователя; • U IIm a g eP ick erC o n tro llerC ro p R ect — для получения объек та N SValue, содержащего значение типа CGRect (прямоугольника, по контуру которого было обрезано изображение). Листинг 13.11 показывает реализацию метода im a g eP ic k e r C o n t r o l le r id id F in is h P ic k in g lm a g e : e d it i n g ln f o : . Метод про сто создает представление с переданным изображением и добавляет это представление в качестве дочернего к представлению главного контрол лера. Он также скрывает контроллер представления выбора изображения с помощью вызова метода d ism issM o d a lV iew C o n tro llerA n im a ted :. Листинг 13.11. Обработка успешного выбора изображения в приложении для работы с камерой -
(void) imagePickerController:(UllmagePickerController *■)picker d idFinis’ n Pickinglmage: (Ullmage *)image editinglnfo:(NSDictionary *)editinglnfo
{ UllmageView *imgView = [[UllmageView alloc} initwithlmage:image]; [eel£.view addSubview:imgView] ; [self dismissModalViewControllerAnimatedrYES] ; (picker release]; (imgView release];
) Листинг 13.12 демонстрирует обработку события, при котором пользо ватель отменяет выбор изображения. Мы просто скрываем представление выбора изображения и высвобождаем его. Листинг 13.12. Обработка пользовательской отмены выбора изображения в при ложении для работы с камерой - (void) imagePiс kerCont rollerDidCancel: (UllmagePickerController *)picker
{ [self dismissModalViewControllerAriimated:YE$]; (picker release];
) @end
353
Ниже изображен главный экран, который пользователь видит сразу после запуска приложения (рис. 13.4), а также представление, где пользо ватель делает снимок (рис. 13.5). j _AT&T
7:59 РМ
‘
|
•
-
i
New Picture Select a Picture
Р и с . 1 3 .4 . Главный экран, которы й видит пользователь при за п у ск е п ри л ож ен и я с п оддерж к ой камеры
Р и с . 1 3 .5 . П редставл ен и е, где п ользователь н аходи тся в п р о ц ессе п рои зв одства снимка
354
Далее приведено представление, где пользователь только что сделал сни мок и представление выбора изображения все еще активно (рис. 13.6). Поль зователь может подтвердить, устраивает ли его данный снимок (после чего изображение сохранится, а пользователь увидит главное окно приложения (рис. 13.7)), или нажать Retake (Переснять), чтобы сделать другой снимок. ^АТ?