» » » Внедрение социальных сервисов в неигровое приложение

 

Внедрение социальных сервисов в неигровое приложение

Автор: admin от 12-01-2017, 06:40, посмотрело: 50

Современную реальность невозможно представить без социальных сетей и различных рейтингов. В связи с этой тенденцией мобильные игры и приложения активно «социализируются». Однако, в то время как для игр такое явление обыденно и закономерно, добавить фунционал социальной сети в неигровые приложения не каждому покажется очевидным решением. Тем не менее, наши давние партнеры и друзья — компания-разработчик музыкальных приложений Music Paradise — решились на подобный шаг. Сегодня мы делимся их кейсом под кодовым названием «Внедрение социальных сервисов в неигровое приложение».

«В этой статье мы хотели бы поделиться опытом создания социальной платформы для меломанов на базе музыкального приложения DJ Mix Pads 2.

Изначально приложение представляло собой простой набор инструментов, с помощью которого любители музыки могли записывать треки, даже не имея особых навыков и знаний. Всего в несколько кликов можно было получить законченную композицию со звучанием, близким к профессиональному.

Внедрение социальных сервисов в неигровое приложениеВнедрение социальных сервисов в неигровое приложение

Чтобы выделиться из множества схожих продуктов, мы решили сыграть на соревновательном элементе и сделать процесс создания композиций более целенаправленным. Открывать в себе музыканта будет интереснее, если дать людям возможность делиться своими творениями с другими пользователями, оценивать чужие, выбиваться в топы, объединяться в группы по музыкальным интересам и открывать новые возможности приложения, поднимая себе рейтинг.

В данной статье мы коснемся различных аспектов работы с сервером, расскажем о некоторых дополнительных функциях, которые потребовались для введения социальной составляющей, и о том, как они были реализованы в продукте.

Взаимодействие c клиент-сервером


Работа с серверным API осуществляется посредством POST и GET запросов. Тут хотелось бы подробно рассмотреть ухищрения, к которым мы прибегали, чтобы настроить работу с ними.

Рассказывать про формирования HTTP запросов особого смысла нет: гугл и так переполнен соответствующей информацией, да и на гитхабе можно найти множество полезных библиотек.

Поэтому разберем лучше работу с ответом от сервера на примере того, как получали список треков, которые пользуются популярностью у пользователей. Список треков приходит в таком формате:

{
    data = ();
    success = 1;
}

Либо в таком, если запрос неверный или произошла какая-то ошибка:

{
    error = "Error description";
    success = 0;
}

Для разбора ответа мы используем данную конструкцию:

NSDictionary *answer = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];//Где data - пришедший от сервера ответ
if([[answer objectForKey:@"success"] boolValue]){
	NSMutableArray *dataArray = [answer objectForKey:@"data"];
	[self doSomeStuff:dataArray];
}
else{
	if([answer objectForKey:@"error"])
		NSLog(@"%@",[answer objectForKey:@"error"]);
}

Передача изображений


При регистрации в приложении у пользователя есть возможность поставить себе аватарку. Соотвественно, встал вопрос о том, как изображения будут передаваться на сервер и с сервера.

Механизм циркуляции изображений мы выбрали весьма своеобразный. Самым простым решением было бы передавать сами файлы в качестве POST запроса, после чего при необходимости получать ссылку на файл на стороне сервера. Именно таким образом у нас реализовано хранение аудио-файлов, которые загружают на сервер пользователи.

Однако было решено передавать изображения в качестве base64 строки. Для этого на стороне клиента используются следующие методы преобразования строки.

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

-(NSString *)imageToNSString:(UIImage *)image
{
    if(!image)
        return nil;
    if(image.size.width>250&image.size.height>250)
        image = [self imageWithImage:image scaledToSize:CGSizeMake(250, 250)];
    NSData *imageData = UIImagePNGRepresentation(image);
    return [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}

- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

Теперь преобразовываем строку в картинку:

-(UIImage *)stringToUIImage:(NSString *)string
{
    if(string==nil)
        return nil;
    NSData *data = [[NSData alloc]initWithBase64EncodedString:string
                                                      options:NSDataBase64DecodingIgnoreUnknownCharacters];
    return [UIImage imageWithData:data];
}

На первый взгляд данный подход может показаться не самым эффективным, ведь приходится выполнять двойную работу, преобразовывая изображения туда и обратно. Однако для нас такое незначительное усложнение было оправдано: в конечном итоге оно существенно облегчило нам жизнь и ускорило процесс разработки.

Немного про пагинацию


Эта проблема встала перед нами неожиданно и несколько позже остальных, когда наши социальные нововведения уже начали набирать популярность. Люди стали загружать достаточно большое количество треков в день, массив аудиофайлов на сервере неумолимо рос — все это вызывало проблемы в получении списков топов. При попытке обработать весь список разом приложение подвисало и выдавало ошибки. Стало ясно, что придется переходить на частичную подгрузку контента, а значит, вводить пагинацию.

Внедрение социальных сервисов в неигровое приложение

Списки стандартно создавались с помощью UITableView, и необходимо было разработать метод подгрузки новых ячеек по мере получения данных с сервера.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    
    if(indexPath.row == self.tableContentArray.count-1 && !self.isFullContent)
    {
        [self getContentFrom:self.tableContentArray.count withCount:10];
    }
}

В первую очередь мы проверяем:

— является ли данная ячейка последней, которую мы можем отобразить;
— получили ли мы весь контент который должны отобразить на данном контролере.

Расчет такой: если мы получили меньшее количество записей, чем запрашивали, (в данном случае меньше 10), то в этот момент помечаем переменную isFullContent как true.

Уведомления внутри приложения


Нам хотелось, чтобы внутри приложения пользователь имел доступ к полной информации о состоянии своего аккаунта (количество лайков, прослушиваний и т. д.). Для этого была введена система локальных уведомлений. Принцип работы у нее следующий — при входе пользователя в приложение мы сохраняем текущее состояние:

[[NSUserDefaults standardUserDefaults] setInteger:user.countOfLikes forKey:@"countOfLikes"];
[[NSUserDefaults standardUserDefaults] setInteger:user.countOfLikes integerValue] forKey:@"countOfListens"];
[[NSUserDefaults standardUserDefaults] setInteger:user.level forKey:@"countOfLevels"]; 

При следующем же входе данные значения сверяются с данными, полученными от сервера. Если они не совпадают, мы отображаем локальное уведомление, информируя пользователя о том что у него есть прогресс. Такие приятные новости положительно влияют на пользовательский опыт:

CongratsCustomPush *push = [[CongratsCustomPush alloc] initInController:[self topViewController]
                                                              withTitle:@"Changes since your last visit.nGood job!"
                                                              withLevel:countOfLevels
                                                              withLikes:countOfLikes
                                                         andWithListens:countOfListens];
[push showAnimated:YES];

Внедрение социальных сервисов в неигровое приложение

Достижения


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

Внедрение социальных сервисов в неигровое приложение

На данный момент в приложении имеется 9 достижений:


  • Создать студию

  • Пройти мини-урок по эффектам

  • Получить 5 прослушиваний ваших треков

  • Опубликовать 3 трека

  • Опубликовать первый трек в студии

  • Записать свой первый трек

  • Провести 30 минут в приложении

  • Пройти мини-урок по созданию студии

  • Завершить начальный туториал


Зарабатывать ачивки — дело клиента, сервер лишь хранит информацию о полученных достижениях и некоторую статистику (например, сколько времени пользователь провел в приложение)

При рассылке оповещений о достижениях используется система удаленных PUSH-уведомлений для конкретных пользователей. Чтобы идентифицировать пользователя мы сохраняем UUID девайса, с которого был выполнен последний вход в систему, и при получении PUSH-уведомления идем одним из двух путей, в зависимости от обстоятельств.

Если пользователь в данный момент не находится в приложение, он получает стандартное оповещение с информацией о полученном достижении — это первый путь.

Второй же путь более сложный. Если в данный момент пользователь находится в приложении, мы перехватываем полученное сообщение в методе AppDelegate’а:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo


и отображаем его, в текущем ViewController’e.

Заключение


Обобщим, какие дополнительные возможности в итоге дало нам использование сервера:


  • Регистрация пользователей и сохранение данных из их профилей (почта или страница в Facebook, имя, аватарка).

  • Удаленное хранение треков на сервере.

  • Предоставление треков на общий суд.

  • Возможность отмечать чужие трэки как понравившиеся и сохранять их в собственную коллекцию.

  • «Студии» — группы пользователей по предпочтениям в музыкальных жанрах. Вступление в студию дает доступ к новым сэмплам, звукам.

  • Топы по трекам, пользователям, студиям

  • Отправка пуш-уведомлений конкретным пользователям по достижениям

  • Получение ачивок

  • Подгрузка части контента (звуки, сэмплы) с сервера. Это дало нам возможность ужать приложение до размера меньше 100мБ. Это важно: согласно правилам маркета, приложения размером более 100мБ весом не могут скачиваться через мобильные сети, только по wi-fi.

  • Сбор подробной, точечной статистики по пользователям, публикациям, предпочтениям. Количество публикуемых треков, самые популярные жанры, активность отдельных юзеров, частота получения ачивок – все это дало материал для более объективной оценки результатов наших трудов.? А также, скажем по секрету, возможность удаленно награждать самых активных пользователей».


P.S. Ребята также рассказали нам, что заметили забавную тенденцию: ведущие разработчики данного проекта женятся примерно через 2-3 месяца после того как начинают над ним работу. В данный момент счет 2:0 в пользу этого «поверья». Так что, если хотите кардинальных изменений в личной жизни, попробуйте реализовать подобный проект в своем приложении.

Источник: Хабрахабр

Категория: Программирование » Веб-разработка

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *