Хочу поделиться своими знаниями и методами создания интерактивных журналов для iPad из личного опыта.
Где-то в конце 2010 года ко мне обратились с заказом реализовать приложение, которое позволило бы конвертировать печатную продукцию издательств (журналы, книги, брошюры) в электронный формат для удобного чтения на iPad. После долгих разговоров и уточнений итоговое задание технического задания было сформулировано следующим образом: Создайте приложение для iPad, представляющее собой магазин электронных журналов.
Пользователь, пройдя простую регистрацию и пополнив баланс на необходимую сумму, мог скачать доступный электронный журнал и просмотреть его.
Журнал должен быть интерактивным, то есть иметь функции просмотра набора слайдов, вращения, видео, аудио, увеличения шрифта, добавления закладок, красивую анимацию перелистывания страниц и список других вещей в том же духе.
Оригинальный журнал представлял собой чистый PDF-файл, исходивший непосредственно от издательства.
Чтобы долго не говорить и не вникать во все проблемы, отбросим реализацию серверной части, регистрацию пользователей, пополнение баланса, синхронизацию.
Перейдем непосредственно к классу, который должен был отвечать за просмотр и взаимодействие с журналом.
Я взял проект за основу анимации github.com/brow/leaves , который до сих пор является одним из самых известных двигателей в этом направлении.
Мне очень понравилась реализация эффектов складывания и перелистывания страниц.
Первоначальный вид двигателя показан на рисунке ниже.
После того, как я поменял движок под себя, сделал функции отображения превью, добавления страниц в закладки и прочие нюансы, получил от издательства pdf-версию 40-страничного журнала, который весил 144МБ и залил ее на реальное устройство, я столкнулся с фатальной проблемой.
При перелистывании случайной страницы журнал просто вылетал.
При доступе к журналам я столкнулся с ошибкой: форматировщики данных временно недоступны По сути, на iPad закончилась виртуальная оперативная память, которая позволяет использовать приложение.
Копнув гораздо глубже, используя инструменты - выделение памяти, я заметил, что при рендеринге очередной pdf-страницы выделенная память накапливается и не освобождается.
Вы, конечно, можете подумать, что я неправильно использовал CGPDFPageRelease и другие операции, связанные с освобождением и очисткой памяти.
Но после более чем месяца тестирования приложения, изучения сотен сообщений в Интернете, проблем и решений, единственным разумным объяснением по теме «Рендеринг больших PDF-файлов» является то, что iOS sdk при вызове метода CGPDFPageRelease фактически не уничтожает память.
.
Как было написано на официальном сайте Apple (к сожалению, ссылку мне не удалось найти), CGPDF кэширует тайлы страниц в памяти, чтобы при следующем обращении к ним рендеринг происходил быстрее.
То есть была проблема с этим внутренним механизмом кэширования от Apple, который стабильно мешал читать тяжелые pdf-журналы.
В холодном поту, скорбя о сроках, я начал искать оптимальные решения сложившейся проблемы.
Дополнительно заказчику не очень понравилась медленная отрисовка CATiledLayer, хотя ему было сложно объяснить, что одна страница весит не менее 7МБ.
Я попробовал загрузить в UIWebView свой чудо PDF-файл от издателя, но в итоге идея потерпела полное фиаско.
Веб-компонент падал даже быстрее, чем мой движок, и без того полный костылей.
Перейдем к решению проблемы : В результате мне захотелось написать парсер pdf, который бы извлекал из файла все картинки и текст. Затем я конвертировал их в свой формат и отображал в приложении стандартными средствами (например, UIImageView, UITextView или CoreText).
Мне не удалось прочитать массу мануалов от Adobe, хотя я все равно считаю это перспективной идеей.
Нормального парсера пдф в интернете тоже найти не удалось - все выдирали изображения либо коряво, либо вообще делали не так.
Про получение текстов из pdf я вообще молчу хотя бы в формате .
doc или .
html. Моей окончательной реализацией был следующий механизм.
С помощью издательской программы Quark Xpress я вырезал из pdf все тяжелые картинки, дополнительно сжал их, изменил размер и цветовое пространство.
Затем я разработал свой собственный псевдоязык сценариев (с использованием html-подобных тегов), например: (номер страницы = 1) (pdf)1(/pdf) (изображение)0,0,768,1024,first_page_image.png(/image) (текст).
(текст) (видео).
(видео) (слайд).
(слайд) (3д).
(3д) (/страница) Затем для каждой страницы были созданы легкие превью в формате jpg. Когда на превью закончился эффект переворачивания, был добавлен CATiledLayer который начал рисовать pdf с вырезанными картинками (то есть только текст и простые элементы).
При этом файл с тегами разбирался, и все интерактивные элементы добавлялись на задний или передний план, к ним прикреплялись обработчики, в нужных местах начиналась анимация, а поверх них добавлялись специальные элементы «активаторы» для взаимодействовать с интерактивными элементами.
В результате мое приложение не вылетело, работало довольно быстро и соответствовало всем требованиям технического задания.
Около месяца назад вновь поступило аналогичное предложение по внедрению электронного журнала.
Но я был вынужден отказаться, так как не хотел снова проходить через все эти хлопоты.
Но ради собственного любопытства я проанализировал в Интернете новые стабильные бесплатные движки.
Новые понравились github.com/vfr/Reader Но как только я загрузил в него тот самый pdf, с которым так долго мучился год назад, он тоже вылетел.
Все официальные движки от Apple тоже крашатся.
Если кто хочет поделиться опытом, или уверить, что их движок решает проблему чтения гигантских pdf, пишите, буду рад поделюсь более подробными советами и скину тот самый вредоносный pdf, который скорее всего крашит ваш движок.
Теги: #электронные журналы #электронные книги #журналы #iOS #разработка под iOS #ipad #разработка под iOS
-
Илон Маск – Это Не Будущее
19 Oct, 24 -
Новый Блог С Переводами
19 Oct, 24 -
Google Adsense 10 Лет!
19 Oct, 24 -
Подкаст Appleinsider.ru [21]
19 Oct, 24