История одного пасхального приложения

от автора

Не яйца красят человека, а человек красит яйца

Лучок, свекла, старый гастук, цветные нитки — сколько способов раскраски яиц знаете вы? Сегодня мы расскажем еще об одном, придуманном нами.

image

Набить морду павлину

Яйца раскрасить — не картошки пожарить.

Для каждой палитры есть подходящий материал, а когда речь идет о продукте, который потом еще и съедается — не хочется делать это как попало.

image

Можно!

Все, что вам понадобится — это iPhone, хотя на первых порах можно обойтись и без него. Главное — припасите яиц.

Нарисовав первые прототипы интерфейса мы прикинули, сколько у нас будет разметок, орнаментов, как они будут выглядеть и, наконец, отправились готовить контент для приложения. Спустя несколько дней у нас получилось немного-немало 350 разных орнаментов для 5 цветов и 5 разметок.

“Мотор, камера… Экшн!”

Тут же были нарисованы первые прототипы, на которых были распределены основные экраны приложения, доступный функционал и основная механика расраски. Естественно, все тестировалось на яйцах.

image

Казалось, что при такой простой задаче должно найтись множество способов оформить идею в интерфейсе, однако, оставалось противоречивое мнение по разным мелочам, вроде “нужно ли переключаться на следующий этап редактирования при выборе какой-то зоны, или нет?” и так далее

image

Каждое яйцо было заботливо отрендерено вручную — на это ушло немало времени.
“Почему бы не рендерить в самом приложении по модели?” — спросите вы. Отвечаем: каждый орнамент натягивался на яйцо по-своему — такую работу нельзя доверить роботам.

Подводные яйца

Первую версию мы сделали на Кокосе, и основные сложности были только со скрещиванием объектов сцены с наследниками UIView, но и это можно решить, разбив объекты по разным сценам.

image

Задача, которая появилась на горизонте: слишком много картинок, нужно уложиться в 50 мегабайт (на дворе был 2013, в iOS 7 лимит увеличился вдвое), иначе приложение не получится скачать через сотовую сеть. Пожали все в джипеги, для каждой зоны нарисовали маску, по которой фильтровали слой с каждой зоной. Уложились!

В синий — прищемите дверью

Проверяйте дважды все, прежде чем отправляете приложение с In-App Purchase внутри. Особенно — не забудьте кнопку восстановления для non-consumable покупок. Мы получили свой заслуженный reject и отправились на доработку к следующему году.

Огромного внимания заслуживает тестирование In-App Purchase. Тестирование при помощи тестовых iTunes аккаунтов очень своеобразное — лучше один раз попробовать. И да, если вы публикуете новую версию, и определенные In-App’ы доступны только в ней — не забудьте, что это нужно указать перед отправкой приложения на review.

Те же яйца — вид сбоку

Быстро перевели проект на SpriteKit — логика осталась той же, но стало значительно проще работать с внутренней структурой объектов для отрисовки, для этого даже не пришлось лезть CoreGraphics:

SKSpriteNode *patternNode = [SKSpriteNode spriteNodeWithImageNamed:spriteImageName]; SKSpriteNode *maskNode  = [SKSpriteNode spriteNodeWithImageNamed:maskImageName]; SKCropNode *zoneNode = [SKCropNode node]; [zoneNodeaddChild:patternNode]; [zoneNode setMaskNode:maskNode]; 

Зачем изобретать велосипед? Вернулись к стандартной навигации UINavigationController, сейчас кастомизируй — не хочу.

image

Симулировать поведение UIScrollView для наследника SKNode можно положив его в один контейнер с UIScrollView, а сам контейнер положить поверх SKView который отрисовывает SKScene, и реализовать для такого контейнера протокол UIScrollViewDelegate и далее изменять положение SKNode внутри контейнера в зависимости от параметра contentOffset:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {   // See also: http://stackoverflow.com/a/19197965/429253   _selectorNode.position = CGPointMake(- scrollView.contentOffset.x + 160.0f,                                        _selectorNode.position.y); } 

Анатомия яйца

В качестве счетчика был подключен Google Analytics, это потребовало минимального количества времени на интеграцию, и предоставило кучу рычагов прямо из коробки. Экраны, события, модель поведения пользователей — все добавляется в пару строчек.

Отслеживание событий:

[[[GAI sharedInstance] defaultTracker] send:  [[GAIDictionaryBuilder createEventWithCategory:@"Share"                                          action:@"Facebook"                                           label:nil                                           value:nil] build]]; 

Отслеживание экранов:

id tracker = [[GAI sharedInstance] defaultTracker]; [tracker set:kGAIScreenName value:@"Store: Super Eggs"]; [tracker send:[[GAIDictionaryBuilder createAppView] build]]; 

Особо доставляет раздел Real-Time:

image

И да, не забудьте отрубить статистику для симулятора и тестовых запусков — зачем в статистике мусор?

#if TARGET_IPHONE_SIMULATOR || DEBUG   [[GAI sharedInstance] setOptOut:YES]; #endif 

Сетевые яйца

image

Создание «приложение» для Facebook — это стотыщ баннеров разного размера. Вам все равно придется их сделать. Здесь тоже придется какое-то время подождать (говорят про три рабочих дня, обычно делают за день), прежде чем фейсбучное приложение появится в App Center.

Также, логин при помощи Facebook SDK очень чувствителен к разным условиям: у зависимости от того, установлено на телефоне приложение Facebook или нет, залогинены вы в социальных сетях в настройках iOS, или нет — результат будет разный. Для SSO авторизации не забудьте правильно прописать URL types в настройках приложения в XCode (заменив девятки на идентификатор вашего приложения в Facebook‘е):

image

Фотографию заливаем с помощью FBRequestConnection и указываем, кого мы на этой фотографии отмечаем:

FBRequestConnection *photoUploadConnection = [[FBRequestConnection alloc] init]; FBRequest *request = [FBRequest requestForUploadPhoto:_image]; [request.parameters setObject:[NSString stringWithFormat:@"[{\"tag_uid\":\"%@\"}]", friendId] forKey:@"tags"]; [request.parameters setObject:K_APP_PROMO_TEXT forKey:@"name"];  [photoUploadConnection addRequest:request                 completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {                   if (!error){                     // handle success                   }                 } batchEntryName:@"photopost"];  [photoUploadConnection start]; 

Заливать картинки ВКонтакт немного сложнее, придется сначала запросить адрес сервера для загрузки картинки, и только после этого запостить ее другу на стену (в отличие от Facebook, где мы добавляем фотку в альбом и отмечаем ан ней кого-то:

 // 1. Get upload server   NSDictionary *result = [self sendVkRequestForMethod:@"photos.getWallUploadServer"                                                params:[NSDictionary dictionaryWithObjectsAndKeys:                                                        friendId, @"uid",                                                        K_ACCESS_TOKEN, @"access_token", nil]                                                 error:&error];    // 2. Upload image   if (!error) {     result = [self sendPOSTRequest:[[result objectForKey:@"response"] objectForKey:@"upload_url"]                      withImageData:UIImageJPEGRepresentation(_image, 75)];   }    // 3. Save image   if (!error) {     result = [self sendVkRequestForMethod:@"photos.saveWallPhoto"                                    params:[NSDictionary dictionaryWithObjectsAndKeys:                                            friendId, @"uid",                                            K_ACCESS_TOKEN, @"access_token",                                            [result objectForKey:@"hash"], @"hash",                                            [result objectForKey:@"photo"], @"photo",                                            [result objectForKey:@"server"], @"server", nil]                                     error:&error];   }    // 4. Post on wall   if (!error) {     result = [self sendVkRequestForMethod:@"wall.post"                                    params:[NSDictionary dictionaryWithObjectsAndKeys:                                            friendId, @"owner_id",                                            K_ACCESS_TOKEN, @"access_token",                                            K_APP_PROMO_TEXT, @"message",                                            [[[result objectForKey:@"response"] lastObject]objectForKey:@"id"], @"attachment",                                            nil]                                     error:&error];   } 

C Instagram‘ом проще, сначала сохраняем картинку с расширением *.igo, потом открываем ссылку через UIDocumentInteractionController.

// 1. Save file with *.igo extension NSString *path = [[self applicationDocumentsDirectory].path                   stringByAppendingPathComponent:@"EggMaker.igo"]; NSError *error = nil; [UIImagePNGRepresentation(postcardImage) writeToFile:path                                              options:0  // 2. Open with UIDocumentInteractionController if (!error) {   NSURL *instagramURL = [NSURL URLWithString:@"instagram://app"];   if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {     self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:                                           [NSURL fileURLWithPath:path]];     self.documentInteractionController.UTI = @"com.instagram.exclusivegram";     self.documentInteractionController.annotation = [NSDictionary dictionaryWithObject:K_SHARE_TEXT                                                                                 forKey:@"InstagramCaption"];     [self.documentInteractionController presentOpenInMenuFromRect:self.view.frame inView:self.view animated:YES];   } } 

Интерактивные яйца

Всегда не хватало возможности сделать интерактивную перезентацию своего приложения, особенно если приложение платное, а правилами App Store демо версии запрещены? С этой задачей справился App.io:
image

Добавить приложение можно зарегистрировав бесплатный аккаунт, бесплатно доступно множество настроек отображения и встраивания такого интерактивного демо через параметры ссылки. С недавнего времени такое демо своего приложения можно встраивать в виде полноэкранной интерактивной рекламы.

Скачай Яйцедел в App Store: appstore.com/Яйцедел (кто спрашивал про короткие ссылки?)
Спасибо что вы с нами, обязательно попробуйте Super Eggs — там есть с котиками и пингвинятами!
Наши страницы в Фейсбуке и ВКонтакте

И на будущее: берегите яйца!
Христос Воскресе!

ссылка на оригинал статьи http://habrahabr.ru/post/219693/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *