29 December 2012

Тернистый путь в Windows Store

Website development
Как и многие программисты, я с опаской относился (и отношусь) к Windows 8, но не удержался попробовать написать пару программ для Windows Store. Все-таки, это модная тенденция: .Net 4.5, C# 5, XAML.

Как раз в эти дни, 4го декабря, мне попалась на глаза статья про конкурс приложений для W8 от Microsoft. Выкладывать экспериментальные программы было как-то не серьезно (хотя маркет такими поделками буквально переполнен), потому я решился портировать достаточно масштабный проект с MonoTouch и iOS. Запаситесь попкорном, потому как кроме программистских деталей тут будет и комедия, и драма, и жизненный финал.


Совсем другой C#


Код для MonoTouch/MonoDroid пишется на C#, но это нормальный, «канонический» C# с System.Drawing, System.Xml, System.IO и пр. Я ожидал под Windows 8 все это же, с бонусными бриджем и юристками, но реальность оказалась жестокой: перечисленные неймспейсы в принципе отсутствуют. Больше нет PointF, вычеркнут XmlNode, нельзя сделать File.ReadAllText(), нет FileStream и чего-либо совместимого с ним. Даже с изображениями можно сделать лишь одно действие — загрузить, да и то асинхронно, т.е. даже размер в пикселях сразу после загрузки мы без бубна узнать не сможем.
Собственно, вообще все I/O операции с внешним миром стали асинхронными, с ключевыми словами async и await, что уже через несколько часов работы вызывало у меня приступы неконтролируемой ярости. На самом-то деле, это неплохое нововведение и интересный подход, но если в стабильном и проверенном коде читался текстовый файл на 500 байт (порядок уровней в игре, скрипт и пр.), то теперь подразумевается заметная переделка кода, а заодно всю цепочку вызовов надо пометить как async. Другой вариант — писать враппер, имитирующий старый синтаксис, внутре которого неонка происходит не кошерный синхронный вызов асинхронного метода (привет будущим саппортерам!).

Вообще, я сторонник замораживания кода: бизнес логика единожды пишется, отлаживается и затем вообще не трогается, а изменения касаются только взаимодействия с пользователем. Потому, преодолев приступ отвращения я сел творить собственные велосипедыврапперы.
За пол-дня были сделаны свои реализации PointF, RectangleF, XmlDocument, System.IO.File и пр., которые по синтаксису такие же, как в .Net 2.0-4.0, но внутри используют уже реалии Windows Store. Для работы с ресурсами таки пришлось смириться с костылями для «осинхронивания асинхронов»:
public static string ReadAllText(string path)
{
        IAsyncOperation<StorageFile> file =
                  StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///" + path));
        file.AsTask<StorageFile>().Wait();

        IAsyncOperation<string> result = FileIO.ReadTextAsync(file.GetResults());
        result.AsTask<string>().Wait();

        return result.GetResults();
}


С XmlDocument и XmlElement получилось сложнее, такие классы существуют в «облегченном» виде в неймспейсе Windows.Data.Xml.Dom, но теперь они не наследуются от XmlNode, а реализуют интерфейс IXmlNode с некоторыми изменениями синтаксиса. Мой враппер не очень красив, не умеет работать с XPath и могими другими возможностями, но для простейших задач подошел отлично. Если кому-то понадобится как заготовка, вот код: paste2.org/p/2664348

Графика


На iOS/Android наши игры рисуют спрайты через OpenGL ES 1.1. Без шейдеров, без трансформаций, без VBO — вызовами glDrawTexiOES. В Windows, понятное дело, GL и не пахнет, потому я рассчитывал на XNA и SpriteBatch, но… его там не оказалось. В мире Windows Store вообще XNA в чистом виде нет, только за счет его кросс-платформенной реализации MonoGame! Продукт это достаточно занимательный, но хотелось обойтись возможностями платформы, да и в перспективе интересовал вариант порта на Silverlight. Решение на WPF/XAML выглядит доморощенным, но работает почти как надо: для каждого спрайта я создаю Rectangle нужного размера на Canvas и назначаю ему ImageBrush, который ссылается на нужную текстуру, а за счет трансформаций извлекает только ее часть. Технически, WPF использует DirectX для отрисовки, потому этот метод вполне имеет право на жизнь и дает неплохую производительность.
Подводный камень я нашел лишь один, когда порт был почти закончен: в принципе не существует метода изменить цвет спрайта. К примеру, в головоломке с цветами мы красили разные части в красный и синий цвет через glColor4f(1.0f,0.0f,0.0f,1.0f). При всем богатстве выбора, альтернативы я не нашел (кроме переписывания на MonoGame), потому пришлось работать с тремя разными текстурами. Подобная проблема получилась и в головоломке с костями, но тут я смог обойтись прозрачностью — зафиксированные кости теперь «серые» (справа), а не «желтые», как на других платформах (слева).



Заметное отличие Windows Store игр от мобильных/планшетных еще и в том, что они могут показываться на огромных экранах и разрешениях. К примеру, графика для iPhone 3GS не очень хорошо смотрится на 27" мониторе с разрешением 2560x1440. Благо, для iPad 3 было подготовлено некое количество hi-res контента, а заодно некоторые уровни и элементы управления давно пора было перерисовать. Я не художник, потому это у меня заняло чуть ли не больше времени, чем портирование.

Выкладывание в маркет


Итого, 6го декабря рано утром программа была готова к отправке на сертификацию. Времени до дедлайна конкурса, 10 декабря, оставалось мало, но я надеялся на лучшее. Скриншоты для Windows Store полагается делать в симуляторе с разрешением от 1366х768 в формате png, который в лучших традициях Microsoft, раздут до невозможности. Размер выходит приемлемый для однотипной графики, но не для фотографий или картин: показанный выше скриншот с творчеством Дали занял 2.9 мегабайта. Это не проблема для современного интернета, но форма отправки программы не принимает файлы больше 2 МБ. JPEG она тоже не берет, потому я предварительно пропустил скрин через optipng, от чего он визуально не изменился, но стал на мегабайт меньше.

Отказ


В субботу утром, 8го декабря мне пришел отказ в сертификации программы. Причина поражала воображение: «один или несколько скриншотов были изменены в сторонних программах». Мысленно обругав себя за беспечность, а разработчиков и тестеров за все совершенные и не совершенные ими грехи, я удалил скрин и переотправил программу.
Отдельно скажу, что о идиотизмеситуации со скриншотами я оповестил саппорт, официальный форум, знакомых представителей фирмы, но вразумительных ответов не получил. Вчера со мной связался коллега из Беларуси, у которого ситуация еще сложнее: их программа показывает красивейшие фотографии уголков Земли, и все как один скриншоты получаются больше 2 Мб. По всей видимости, к каждому такому скриншоту надо делать приписку вроде «изменено в Photoshop для уменьшения размера».

Тестирование


Зачастую тестеры в iTunes Store/Samsung Store/Amazon AppStore смотрят на базовые качества программы: нет ли там явных багов, таймбомб, голых красоток, кейлоггеров. Сертификация в Windows Store не была исключением для других моих продуктов и занимала один, максимум два дня. Но в этот раз, как я понял, тестеры решили пройти игру целиком, иначе я не понимаю, чем еще могли они заниматься 11 (!!) календарных дней. Либо просто не смогли пройти первую головоломку.
Служба поддержки ответила, что технически прошло только 7 рабочих дней и это не так страшно, надо еще потерпеть. Смирившись, что меня иносказательно обозвали терпилой, я пообщался с организаторами конкурса и узнал, что финальный срок подачи заявок сместили с 10 до 28 декабря. Это обнадеживало, хотя уже и было понятно, что шансы попасть на конкурс невелики.
В ночь с 17 на 18 декабря мне пришло уведомление, что программа прошла сертификацию и через 4 часа появится в магазине.

Потери


Через несколько дней программа в магазине так и не появилась. Как раз в эти дни Microsoft почти в полном составе собирался отправился на недельные каникулы (или встречать КС в кругу семьи), потому я забил тревогу и оперативно связался с службой поддержки. Девушка с красивым именем Brandi (или неудачно названный мальчик) сообщила, что к огромному сожалению в процессе сертификации были безвозвратно потеряны все мои скриншоты! Это было 20е декабря, за один день до предполагаемых каникул и сопутствующего мероприятия. Чтобы не затягивать процесс я предложил сразу три варианта: выслать скриншоты почтой, отменить сертификацию программы, взять скриншоты из бесплатной версии этой же игры, уже отправленной на рассмотрение. Решение, видимо, оказалось не простым, потому 23 декабря дня мне ответили, что наверное надо высылать скрины почтой…
Сказано — сделано, я приаттачил набор скринов, написал описания на русском и английском, отправил и в течение 15 минут получил ответ:

В конце 2012 года, после окончания календаря майя, в эпоху, когда был найден бозон Хиггса, а любопытный робот шлет фотографии с Марса в реальном времени, телефоны снимают 41 мегапиксель, а фирмы покупают петабайтные хранилища данных, лимит на почтовые сообщения в MS оказался 14 мегабайт…
Я составил новое письмо, выбросил часть скринов и… получил ответ от другого робота:

На этом этапе я психанул, залил все файлы на свой хостинг и отослал ссылки. Следующий ответ пришел через 6 дней, 29го декабря, когда о конкурсе уже не было и речи. Он гласил, что скриншоты залили, все отлично, но пока не выложили программу, т.к. в логах видно, что еще был некий promo image (картинка справа) — по-сути, декорированная плитка-баннер для маркета, на случай если редакторы захотят вынести программу на главную страницу. Так вот, этот promo image был тоже утерян и они просят моего совета, как поступать дальше — выпускать без него, или я вышлю обновленный.
Очень хотелось написать нецензурный ответ, но я ответил одной фразой, что обойдемся без promo image.

Конкурс


Тем временем в конкурсе прошло предварительное награждение «8 лучших новогодних программ». Победили там «Салаты» и психоделическая игра Lighthouse, несколько отдаленная от новогодней тематики и здравого смысла.
Сейчас мой продукт тоже числится в списке участников, потому что я успел подать на сертификацию бесплатную версию этой же программы и сертификация прошла за один день. Отличается она от платной только баннером, который ведет на покупку платной, а значит в никуда :)
К сожалению, главный приз — планшет с Windows 8 — не идет ни в какое сравнение с раскруткой и 4кк баннеропоказов, которую получат Салаты, потому смысл участия несколько теряется. Финал будет на днях, а заодно наградят призера в номинации «Наибольшее количество опубликованных приложений одним участником». Такую номинацию кое-кто воспринял как призыв к действию и стали делать программы, складывающие или вычитающие два числа. Прорекламирую пару таких шедевров:

Не стану осуждать авторов программ и сотрудников MS, пропустивших такое в маркет, но надеюсь, что все-таки организаторам конкурсов приятнее сообщать о победе и раскручивать что-то уровня Cut The Rope, чем 12345 и Салаты.

На этом историю закончу, хотя на самом деле финал еще предстоит: конец света не наступил, но программа до сих пор не попала в магазин, конкурс еще не завершен, а технические проблемы в Windows Store не решены.
Tags:windows 8windows rtwindows storexamlwpfконкурс разработчиковкактус
Hubs: Website development
+83
47.9k 77
Comments 107
Popular right now
Data Analyst
December 8, 2020102,000 ₽SkillFactory
Python для анализа данных
December 9, 202024,900 ₽SkillFactory
Профессия Data Scientist
December 9, 2020162,000 ₽SkillFactory
Специализация Data Science
December 9, 2020114,000 ₽SkillFactory
Машинное обучение
December 11, 202049,000 ₽Нетология
Top of the last 24 hours