Автор: Дамиан Мэйерс, создатель клиента Evernote для WP7
В предыдущей части была описана предыстория создания клиента Evernote для Windows Phone 7, дан обзор платформы с точки зрения разработчика и описаны кое-какие проблемы, с которыми автору пришлось столкнуться. Ниже мы продолжаем его рассказ про разработку Evernote для WP7.
Откладываемая загрузка элементов панелей
Evernote для WP7 изначально имеет несколько панелей в панорамном интерфейсе. Первая панель, которую вы видите, когда начинаете работу, содержит список всех ваших заметок. Далее идут списки блокнотов, меток и недавних заметок.
Чтобы оптимизировать загрузку при открытии приложения, я откладываю загрузку всех элементов панелей кроме списка всех заметок. XAML-контент в других панелях отсутствует, но когда загружаемые события требуют соответствующих панельных элементов, я динамически подгружаю контрол, содержащий элементы интерфейса для нужной панели с анимацией загрузки, чем избегаю ощущения заторможенности интерфейса.
Связки Run при работе с текстом
В списке заметок я хотел показывать жирным шрифтом дату, а затем другим цветом текстовый фрагмент — все в едином текстовом блоке.
Чтобы создать форматированный текст, вы должны определить TextBlock с помощью дочерних элементов Run. Каждый Run определяет форматирование текста внутри соответствующего Run.
Вся работа с XAML осуществляется через выстраивание связей. Вы определяете пользовательский интерфейс с помощью декларативного языка разметки и связываете свойства элементов интерфейса со свойствами объектов .NET. Например, свойство Text элемента TextBlock связывается с Title в .NET-объекте Note.
Суть проблемы вкратце состоит в том, что вы не можете связать данные элементов Run в TextBlock, так что у меня не было возможности просто привязать текст первого Run к свойству даты заметки, а второй — к свойству ее фрагмента.
В итоге я написал свой механизм привязки, который, как выяснилось, стал достаточно популярным на Stack Overflow, но это, конечно, не та вещь, которой хочется уделять при разработке столько времени.
Заголовок аудиофайла
Запись через Microphone в WP7 получается довольно приличной, но если вы хотите что-то сделать с записанным потоком данных, например, сохранить его в виде файла, то вам не повезло. Простое сохранение даст вам файл с сырым потоком данных и больше ничего.
Для воспроизведения этих данных каким-либо приложением понадобится соответствующий заголовок. Видимо, поэтому пост в моем блоге, объясняющий, как добавить заголовок к WAV, является одним из самых популярных.
Производительность изолированного хранилища
Хотя я храню метаданные (заголовок, дату и т. д.) для всех заметок, блокнотов, меток и пр. в едином файле «базы данных», фактически контент расположен в отдельных файлах. В них включены тело заметки и связанные с ней “ресурсные” данные, такие как вложенные файлы, изображения и аудиозаписи.
Я также кэширую содержимое заметки, которое конвертирую в HTML для локального просмотра. Таким образом, для заметки с тремя прикрепленными изображениями потребуется шесть файлов в изолированном хранилище:
Скорость открытия файла из изолированного хранилища существенно снижается, если много файлов располагается в одной папке. Так что вместо хранения файлов всех заметок в единой папке с идентификатором заметки в качестве имени файла я размещаю контент в подпапке, название которой определяется двухзначным хэшем идентификатора заметки.
Другой проблемой, с которой я столкнулся, стало то, что при выходе пользователя из аккаунта встает задача удалить тысячи разных файлов в изолированном хранилище. Не хочется заставлять пользователя ждать, пока это происходит, тем более что процесс может занять часы. Дело в том, что в API отсутствует вызов ‘удалить папку’ и приходится прибегать к рекурсивному удалению — нужно пройтись по дереву папок и удалить каждый файл в отдельности.
Мое решение заключалось в хранении всех данных под корневой папкой с уникальным идентификатором (Guid) и обращении к этой папке в словаре настроек. Когда вы выходите из аккаунта, я очищаю эту ссылку, а при повторной авторизации вы получаете новый идентификатор (и соответствующую папку). У меня есть фоновой поток, который удаляет все файлы, не соответствующие текущему идентификатору пользователя. Он может стараться себе потихоньку в фоновом режиме, ликвидируя все следы прежней авторизации.
Википедия уверяет, что манго — наиболее широко употребляемый в мире фрукт, и хотя я не уверен, что следующий релиз Windows Phone под кодовым именем Mango обеспечит платформе безоговорочный успех, он очевидно станет значительным событием не только для пользователей, но и для разработчиков.
Помимо решения большинства — если не всех — проблем, описанных выше, обновление привнесет ряд возможностей, которые не только упросят жизнь разработчикам, но и помогут нам обеспечить функциональность и удобство использования на уровне, значительно превышающим сегодняшний.
Вот некоторые из вещей, которые я жду с нетерпением:
База данных
Это нововведение практически незаметно для пользователя, но для меня появление нативной поддерживаемой базы данных имеет значение. Я с удовольствием заменю большие куски кода парой строчек: меньше кода — меньше потенциальных багов.
Silverlight 4
Многие проблемы, которые мне пришлось обойти в текущей версии Windows Phone, могут быть учтены в Silverlight 4, такие, например, как невозможность связывания данных элементов Runs в TextBlock. Соответственно разработчик избавится от множества неудобств, которые вообще-то должны решаться элементарно.
Встроенный поиск
Одним из непонятных моментов для пользователей приложения Evernote на Windows Phone является тот факт, что при нажатии на кнопку поиска на самом телефоне при запущенном клиенте Evernote они переходят к Bing вместо собственного поиска Evernote. А для доступа ко второму нужно нажать на специальную кнопку в интерфейсе приложения.
Ситуация может измениться в Mango, когда приложения смогут указывать, что они являются операторами того или иного вертикального поиска (продукты, фильмы, места или события). Наиболее очевидным выбором для Evernote являются места, так как заметки можно снабжать геометками. Когда вы ищете информацию о том, где провести выходные, и на ум вам приходит одно проверенное местечко, то с помощью поиска вы сможете найти список заметок, созданных там в последний раз.
Глубокая интеграция
Для того чтобы создать новую заметку прямо сейчас с помощью Evernote, вам нужно сначала запустить приложение, а затем нажать на кнопку “New Note”. Этот процесс можно укоротить до одного нажатия, используя глубокую интеграцию. Она позволит создавать тайлы (плитки-виджеты основного экрана), связанные с определенной функцией (например, сделать фотозаметку) или с определенным контентом (отдельный блокнот или заметка).
Тайлы
Мы будем изучать возможности применения нового функционала тайлов в Mango, возможно, для того чтобы показывать с их помощью несинхронизированный контент или выводить число нерешенных вопросов в списках дел.
Фоновая синхронизация
Текущая версия Windows Phone не позволяет запускать приложения в фоне, и хотя в Mango предприняты определенные шаги в этом направлении, Microsoft скромно умалчивает о том, как долго приложение можно будет держать работающим в фоновом режиме. Тем не менее, при наличии телефона и Wi-Fi нет ни одной реальной причины, которая бы помешала вам использовать мощное соединение для синхронизации аккаунта Evernote в фоне.
Windows Phone 7 во многом является отличной платформой для программирования, сочетая использование фреймворка .NET и C# с возможностями Silverlight. Тем не менее, она показалась достаточно сложной для создания приложения, ориентированного на работу с данными, с тысячами взаимосвязанных сущностей и без базовых возможностей, свойственных ОС, таких как база данных.
Я уже предвкушаю потенциал следующей версии Windows Phone Mango, которая откроет гораздо больше возможностей для нас, как разработчиков и как дизайнеров, упростив процесс воплощения в жизнь наших идей и задумок.
В предыдущей части была описана предыстория создания клиента Evernote для Windows Phone 7, дан обзор платформы с точки зрения разработчика и описаны кое-какие проблемы, с которыми автору пришлось столкнуться. Ниже мы продолжаем его рассказ про разработку Evernote для WP7.
Решаемые сложности
Откладываемая загрузка элементов панелей
Evernote для WP7 изначально имеет несколько панелей в панорамном интерфейсе. Первая панель, которую вы видите, когда начинаете работу, содержит список всех ваших заметок. Далее идут списки блокнотов, меток и недавних заметок.
Чтобы оптимизировать загрузку при открытии приложения, я откладываю загрузку всех элементов панелей кроме списка всех заметок. XAML-контент в других панелях отсутствует, но когда загружаемые события требуют соответствующих панельных элементов, я динамически подгружаю контрол, содержащий элементы интерфейса для нужной панели с анимацией загрузки, чем избегаю ощущения заторможенности интерфейса.
Связки Run при работе с текстом
В списке заметок я хотел показывать жирным шрифтом дату, а затем другим цветом текстовый фрагмент — все в едином текстовом блоке.
Чтобы создать форматированный текст, вы должны определить TextBlock с помощью дочерних элементов Run. Каждый Run определяет форматирование текста внутри соответствующего Run.
Вся работа с XAML осуществляется через выстраивание связей. Вы определяете пользовательский интерфейс с помощью декларативного языка разметки и связываете свойства элементов интерфейса со свойствами объектов .NET. Например, свойство Text элемента TextBlock связывается с Title в .NET-объекте Note.
Суть проблемы вкратце состоит в том, что вы не можете связать данные элементов Run в TextBlock, так что у меня не было возможности просто привязать текст первого Run к свойству даты заметки, а второй — к свойству ее фрагмента.
В итоге я написал свой механизм привязки, который, как выяснилось, стал достаточно популярным на Stack Overflow, но это, конечно, не та вещь, которой хочется уделять при разработке столько времени.
Заголовок аудиофайла
Запись через Microphone в WP7 получается довольно приличной, но если вы хотите что-то сделать с записанным потоком данных, например, сохранить его в виде файла, то вам не повезло. Простое сохранение даст вам файл с сырым потоком данных и больше ничего.
Для воспроизведения этих данных каким-либо приложением понадобится соответствующий заголовок. Видимо, поэтому пост в моем блоге, объясняющий, как добавить заголовок к WAV, является одним из самых популярных.
Производительность изолированного хранилища
Хотя я храню метаданные (заголовок, дату и т. д.) для всех заметок, блокнотов, меток и пр. в едином файле «базы данных», фактически контент расположен в отдельных файлах. В них включены тело заметки и связанные с ней “ресурсные” данные, такие как вложенные файлы, изображения и аудиозаписи.
Я также кэширую содержимое заметки, которое конвертирую в HTML для локального просмотра. Таким образом, для заметки с тремя прикрепленными изображениями потребуется шесть файлов в изолированном хранилище:
- превью заметки для показа в списке заметок;
- содержимое заметки;
- содержимое заметки, конвертированное в HTML;
- файлы трех изображений.
Скорость открытия файла из изолированного хранилища существенно снижается, если много файлов располагается в одной папке. Так что вместо хранения файлов всех заметок в единой папке с идентификатором заметки в качестве имени файла я размещаю контент в подпапке, название которой определяется двухзначным хэшем идентификатора заметки.
Другой проблемой, с которой я столкнулся, стало то, что при выходе пользователя из аккаунта встает задача удалить тысячи разных файлов в изолированном хранилище. Не хочется заставлять пользователя ждать, пока это происходит, тем более что процесс может занять часы. Дело в том, что в API отсутствует вызов ‘удалить папку’ и приходится прибегать к рекурсивному удалению — нужно пройтись по дереву папок и удалить каждый файл в отдельности.
Мое решение заключалось в хранении всех данных под корневой папкой с уникальным идентификатором (Guid) и обращении к этой папке в словаре настроек. Когда вы выходите из аккаунта, я очищаю эту ссылку, а при повторной авторизации вы получаете новый идентификатор (и соответствующую папку). У меня есть фоновой поток, который удаляет все файлы, не соответствующие текущему идентификатору пользователя. Он может стараться себе потихоньку в фоновом режиме, ликвидируя все следы прежней авторизации.
Ждем Mango
Википедия уверяет, что манго — наиболее широко употребляемый в мире фрукт, и хотя я не уверен, что следующий релиз Windows Phone под кодовым именем Mango обеспечит платформе безоговорочный успех, он очевидно станет значительным событием не только для пользователей, но и для разработчиков.
Помимо решения большинства — если не всех — проблем, описанных выше, обновление привнесет ряд возможностей, которые не только упросят жизнь разработчикам, но и помогут нам обеспечить функциональность и удобство использования на уровне, значительно превышающим сегодняшний.
Вот некоторые из вещей, которые я жду с нетерпением:
База данных
Это нововведение практически незаметно для пользователя, но для меня появление нативной поддерживаемой базы данных имеет значение. Я с удовольствием заменю большие куски кода парой строчек: меньше кода — меньше потенциальных багов.
Silverlight 4
Многие проблемы, которые мне пришлось обойти в текущей версии Windows Phone, могут быть учтены в Silverlight 4, такие, например, как невозможность связывания данных элементов Runs в TextBlock. Соответственно разработчик избавится от множества неудобств, которые вообще-то должны решаться элементарно.
Встроенный поиск
Одним из непонятных моментов для пользователей приложения Evernote на Windows Phone является тот факт, что при нажатии на кнопку поиска на самом телефоне при запущенном клиенте Evernote они переходят к Bing вместо собственного поиска Evernote. А для доступа ко второму нужно нажать на специальную кнопку в интерфейсе приложения.
Ситуация может измениться в Mango, когда приложения смогут указывать, что они являются операторами того или иного вертикального поиска (продукты, фильмы, места или события). Наиболее очевидным выбором для Evernote являются места, так как заметки можно снабжать геометками. Когда вы ищете информацию о том, где провести выходные, и на ум вам приходит одно проверенное местечко, то с помощью поиска вы сможете найти список заметок, созданных там в последний раз.
Глубокая интеграция
Для того чтобы создать новую заметку прямо сейчас с помощью Evernote, вам нужно сначала запустить приложение, а затем нажать на кнопку “New Note”. Этот процесс можно укоротить до одного нажатия, используя глубокую интеграцию. Она позволит создавать тайлы (плитки-виджеты основного экрана), связанные с определенной функцией (например, сделать фотозаметку) или с определенным контентом (отдельный блокнот или заметка).
Тайлы
Мы будем изучать возможности применения нового функционала тайлов в Mango, возможно, для того чтобы показывать с их помощью несинхронизированный контент или выводить число нерешенных вопросов в списках дел.
Фоновая синхронизация
Текущая версия Windows Phone не позволяет запускать приложения в фоне, и хотя в Mango предприняты определенные шаги в этом направлении, Microsoft скромно умалчивает о том, как долго приложение можно будет держать работающим в фоновом режиме. Тем не менее, при наличии телефона и Wi-Fi нет ни одной реальной причины, которая бы помешала вам использовать мощное соединение для синхронизации аккаунта Evernote в фоне.
Заключение
Windows Phone 7 во многом является отличной платформой для программирования, сочетая использование фреймворка .NET и C# с возможностями Silverlight. Тем не менее, она показалась достаточно сложной для создания приложения, ориентированного на работу с данными, с тысячами взаимосвязанных сущностей и без базовых возможностей, свойственных ОС, таких как база данных.
Я уже предвкушаю потенциал следующей версии Windows Phone Mango, которая откроет гораздо больше возможностей для нас, как разработчиков и как дизайнеров, упростив процесс воплощения в жизнь наших идей и задумок.