Задайте свои вопрос про слияние Elance и Odesk

18 декабря 2013 года odesk и elance объявили о слиянии. Odesk является крупнейшей фриланс биржей в мире и ориентирован на гарантированную оплату по часам, elance как мне кажется держит паритет в финансах, так как начал работать существенно раньше и больше ориентирован фиксированную оплату через гарант escrow. Для российского рынка аналогичной сделкой наверное стало объединения free-lance.ru и weblancer.net хотя конечно масштабы у бирж не те.

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

Через две три недели сформируется видение будущего и у меня появилась возможность взять небольшое инсайдерское интервью и в связи с этим хотел бы собрать вопросы фрилансеров. Кстати будет новый логотип у объединенной биржи. Кстати заправлять всем будет CEO Elance и сделка больше похожа на покупку Елансом Одеска. Судя по всему основному конкуренту Freelancer.com придется довольно сложно бороться за кусок рынка.

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

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

Google опубликовал в Маркете свой лаунчер. Ставим его на HTC One

Вместе в новым Nexus 5 на базе Android 4.4 корпорация Google представила и фирменный лаунчер, сейчас имеющий название «Google Старт». Эта программная оболочка изначально была доступна только на Nexus 5. На днях лаунчер появился отдельным приложением в Play Market. Но его страничка видна только с устройств Nexus. Но раз это приложение, то есть и его apk-дистрибутив, который можно установить теоретически на любом аппарате под управлением Android 4.4+


Страничка Лаунчера на Маркете:
play.google.com/store/apps/details?id=com.google.android.launcher

Согласно описанию в Google Play, лаунчер предоставляет следующие возможности:
доступ к Google Now с главного экрана;
голосовой ввод с главного экрана: скажите «OK Google», а затем произнесите запрос или команду, чтобы отправить сообщение, проложить маршрут или включить музыку (доступно только в США, Великобритании и Канаде);
удобный поиск: просто нажмите на окно поиска и введите запрос;
быстрый доступ к сервисам Google: Gmail, YouTube и Картам;
прозрачная строка состояния и панель навигации;
удобный интерфейс выбора обоев: вы можете выбрать любую картинку с вашего устройства или из облачного хранилища и настроить ее положение на экране.

У меня есть Нексус 5, на котором я впервые и увидел этот Лаунчер. Вкратце, очень шустрая оболочка, с симпатичной анимацией, достаточно удобная и без лишних «наворотов». Но если зайти с аппарата на страницу Лаунчера, появляется кнопка «обновить», то есть на Нексусе стоит уже не последняя версия Лаунчера. После обновления с с помощью ES проводника нашел в списке приложений «Google Старт» и сделал его бекап в виде apk-файла весом чуть более 10 мегабайт.

Ради интереса установил apk на свой HTC One, версия РСТ со свежей прошивкой на Android 4.4.
Вот ссылка на мое сообщение, где можно и скачать дистрибутив:
4pda.ru/forum/index.php?s=&showtopic=420431&view=findpost&p=29724628

После установки приложения его сразу не запускаем, возвращаясь в Sence-лаунчер. Нажимаем кнопку «Домой», система предлагает выбрать лаунчер. Отмечаем «Google Старт» и использовать «Всегда». И вот мы в гугловском Лаунчере на аппарате, где его быть (пока) не должно. После установки рекомендую полностью перезагрузить смартфон. Сразу после установки в Лаунчере у меня были некоторые «подтормаживания», которые полностью пропали после перезагрузки.

Интересная особенность. На Нексусах кнопки навигации наэкранные, и Лаунчер закономерно должен отобрать их ан экране. Но на One кнопки аппаратные. И при работе на One аппарат все так же управляется кнопками на корпусе. То есть Лаунчер отлично понимает, когда на смартфоне есть кнопки а когда нет, и выбирает соответствующий стиль отображения. Думаю, в будущем, после тестирования на большом парке Нексусов, Лаунчер может стать доступен и для всех устройств на 4.4.

Вкратце, Лаунчер абсолютно стабилен. Ничего не тормозит, не падает, приложения запускаются с прежней скоростью. С другой стороны, явных преимуществ по сравнению с Sense 5.5 я не заметил. Это больше удовлетворение желания поставить что-то новое, но качественное, чем поиск новых функций. Лично меня огорчает только традиционное отсутствие фирменных часов HTC с погодой (как и вобще каких-либо встроенных часов в лаунчере).

В планах на ближайшее будущее — проверить энергопотребление аппарата с новым лаунчером.

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

Биржа Mt. Gox объявила себя банкротом

На днях на Хабре публиковалась новость о том, что крупнейшая (некогда) биржа виртуальных валют Mt. Gox прекратила все операции. Сегодня юрист биржи, представляющий интересы Mt. Gox, объявил о банкротстве компании.

В настоящее время долг этой биржи перед ее пользователями составляет 63,6 миллиона долларов США. Стоит отметить/, что операции были прекращены еще в начале февраля, а на этой неделе, во вторник, биржа прекратила работу, убрав с сайта контент и контактные данные.

Само собой, все это не могло не сказаться на курсе криптовалюты Bitcoin — курс упал примерно в 10 раз, если учитывать пиковый курс в 1200 долларов за единицу криптовалюты (все это было актуально на начало года).

Via vedomosti

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

Интеграция Facebook SDK (iOS) в мобильные free-to-play игры

imageМобильный free-to-play уже практически не обходится без использования социальных сетей в играх. Социальные сети обеспечивают то, что называют виральностью (от англ. viral – вирусный, т.е. способный распространяться как вирус, от одного человека к другому), что позволяет привлекать новых игроков с минимальными затратами. В данной статье мы поделимся опытом интеграции Facebook в игры Alawar на платформе iOS.

В типичной мобильной free-to-play-игре интеграция Facebook предоставляет следующие возможности:

  1. Возможность авторизации через аккаунт пользователя в Facebook. Такая авторизация хороша тем, что мы формируем уникальный идентификатор пользователя игры с минимальными усилиями с его стороны. Игроку нет необходимости придумывать логин, вводить адрес электронной почты и т.д. Ведь речь идет о мобильном приложении, где постоянно вводить текстовые данные несколько утомительно. Достаточно однажды нажать на кнопку с хорошо узнаваемым логотипом “f”. Есть преимущества и для разработчиков – прогресс игрока может быть синхронизован между различными устройствами на разных платформах, главное чтобы на этих платформах был Facebook.
  2. Возможность отправлять запросы (app requests) друзьям. Запросы – это своего рода сообщения, которые появляются на Facebook-странице игрока (и в приложении Facebook) и содержат относящуюся к игре информацию. К типичным запросам можно отнести приглашения друзей в игру, просьбы вида «отправь/подари мне что-либо» или «помоги пройти уровень». В конечном счёте, запрос нужен только для того, чтобы человек нажал на него и перешел в игру (или на страницу игры в App store). Использование запросов – это мощный механизм для бесплатного привлечения новых игроков и возвращения старых игроков в игру.
  3. Возможность отправлять посты в таймлайн (timeline). Такой постинг позволяет сообщать об игре всем, кто читает таймлайн. Игры обычно помещают туда информацию о достижениях игрока, что добавляет соревновательную составляющую.
  4. Возможность получать информацию об игроке из его аккаунта в Facebook. Чаще всего в такую информацию входит имя игрока, его аватарка и, возможно, аватарки его друзей. Пример использования аватарок в реально существующей free-to-play-игре под спойлером.
    Игра с аватарками

    image

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

Демо-приложение

Демо-приложение написано на C++ (как и большинство наших free-to-play-игр) со вставками на Objective-C и представляет собой простейшее приложение на движке Cocos2d-x (скачать можно здесь). По экрану перемещается прямоугольник и отражается от границ экрана при достижении этих границ.
image
Управление осуществляется при помощи 4 кнопок: f – авторизация, REQ – отправка запроса друзьям, POST – постинг в таймлайн и LOGOUT. После авторизации на место прямоугольника помещается аватарка пользователя, и добавляется приветственная надпись.
image
Для компиляции необходимо скачать и установить Facebook SDK, добавить фреймворк Facebook SDK в проект в XCode. Мы использовали Facebook SDK версии 3.9.
Для запуска демо-приложения вы должны создать собственное Facebook-приложение на вашем портале разработчика, прописать его идентификатор в plist нашего демо-приложения, а также проделать ряд других несложных операций. Подробнее про это можно прочитать здесь.

Технические детали реализации

Права доступа

Первое, с чем сталкиваешься при интеграции Facebook на клиенте – это создание сессии с запросом прав доступа (permissions), разные варианты которых предлагает Facebook. Здесь важно сдержать порыв и не запросить права доступа на все сразу. Хорошим тоном считается запрос прав доступа в момент, когда они действительно необходимы. При создании сессии запросим только базовые права.

+ (NSArray*) getBasicPermissions {     NSArray* permissions = [[NSArray alloc] initWithObjects: @"user_birthday", nil];     return permissions; } 

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

image

В противном случае iOS попытается использовать приложение Facebook (если оно было установлено из App Store) или откроет Facebook в браузере.
Когда нам потребуются права для опубликования чего-либо в таймлайн или при запросе друзьям, запросим права конкретно на это.

+ (void) requestPublishPermissions {     if (hasPublishPermissions) return;          NSArray *permissions = [[NSArray alloc] initWithObjects:                             @"publish_actions", @"publish_stream", nil];          [[FBSession activeSession] requestNewPublishPermissions:permissions                                defaultAudience:FBSessionDefaultAudienceFriends                                completionHandler:^(FBSession *session, NSError *error)     {         hasPublishPermissions = [[FBSession activeSession].permissions containsObject:@"publish_actions"] &&                                 [[FBSession activeSession].permissions containsObject:@"publish_stream"];         if (g_handler) { g_handler->OnGetPublishPermissions(hasPublishPermissions); }     }]; } 

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

Запросы к друзьям

Реализация запросов к друзьям (app requests) достаточно подробно изложена в документации, однако есть ряд тонкостей. При базовой реализации запросов будет показано диалоговое окно, приведенное ниже.
image
Код этой реализации находится под спойлером.

Реализация

+ (void) requestFriend {     // more details here     // https://developers.facebook.com/docs/ios/send-requests-using-ios-sdk/          if (!friendsCache)     {         friendsCache = [[FBFrictionlessRecipientCache alloc] init];     }          [friendsCache prefetchAndCacheForSession:nil];          [FBWebDialogs presentRequestsDialogModallyWithSession:nil                   message:@"Help me, friend!"                   title:@"Help me!"                   parameters:nil                   handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error)     {         if (error)         {             NSLog(@"Error sending request");         }         else         {             if (result == FBWebDialogResultDialogNotCompleted)             {                 NSLog(@"User canceled request");             }             else             {                 NSDictionary *urlParams = [FacebookController parseURLParams:[resultURL query]];                 if (![urlParams valueForKey:@"request"])                 {                     NSLog(@"User canceled request");                 }                 else                 {                     NSLog([NSString stringWithFormat: @"Request Sent: %@", [urlParams valueForKey:@"request"]]);                 }             }         }     }     friendCache:friendsCache]; } 

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

NSString *friendId=@"100006530868327"; NSMutableDictionary* params = [[NSMutableDictionary alloc] init]; params[@"to"] = friendId;

Facebook SDK в этом случае покажет видоизменённое окно App requests и даже предложит не показывать окно при следующих запросах этому другу.

Постинг в таймлайн

Facebook позволяет размещать в таймлайн так называемые истории (stories). Для того чтобы сформировать историю необходимо на странице вашего приложения на портале Facebook-разработчика выбрать в меню слева «Open Graph». Вы увидите 3 вкладки: Stories (Истории), Object Types (Типы объектов) и Action Types (Типы действий). Тип объекта обобщает некоторую группу объектов, которые могут встретиться пользователям вашей игры, например, бейджи. Теперь нужны действия, которые можно применить к объекту «Бейдж», например, действие «Найти». Тип действия и тип объекта могут быть объединены в историю «Find a Badge». Facebook имеет широкие возможности по настройке историй. Подробнее об этом можно узнать здесь.
Чтобы получить код для публикации созданной истории из приложения, необходимо кликнуть на надпись «Get Code» справа от названия истории. Выбираем требуемую платформу (iOS SDK в нашем случае) и вкладку «Code for Object». Система сгенерирует код подобный этому:

NSMutableDictionary<FBGraphObject> *object =     [FBGraphObject openGraphObjectForPostWithType:@"aw_test:badge"                                             title:@"Sample Badge"                                             image:@"https://fbstatic-a.akamaihd.net/images/devsite/attachment_blank.png"                                               url:@"http://samples.ogp.me/473380876115865"                                       description:@""];;  [FBRequestConnection startForPostWithGraphPath:@"me/objects/aw_test:badge"                                    graphObject:object                              completionHandler:^(FBRequestConnection *connection,                                                  id result,                                                  NSError *error) {                                  // handle the result                              }]; 

Во вкладке «Code for Action» можно получить код для действия. Для формирования истории в таймлайн сначала необходимо выполнить создание объекта затем создание действия с этим объектом.
Как ни странно, этот код не работает. Если включить его в проект без модификаций, то будет крэш по необнаруженному селектору в одном из классов. Для того чтобы это исправить, необходимо добавить пару строк в параметры создаваемого объекта Open Graph.

object[@"create_object"] = @"true"; object[@"fbsdk:create_object"] = @"true";

Эта «магия» исправляет крэш, однако постинг в таймлайн по-прежнему не работает. Хорошим признаком того, что все заработало, является возвращенный Facebook идентификатор операции в коллбэке. Идентификатор представляет собой набор цифр (например, 586146891470767). В ответ на код, полученный с портала, приходит строка «true». Это можно исправить, еще немного модифицировав код. В частности, предлагаемый кодогенератором вызов startForPostWithGraphPath необходимо заменить на startForPostOpenGraphObject при создании объекта.
Полный код для постинга в таймлайн можно увидеть под спойлером.

Реализация

+ (void) createOpenGraphObjectWithType:(NSString *) type                                  title:(NSString *) title                                    url:(NSString *) url                                  image:(NSString *) image                                  handler: (OpenGraphObjectCreationHandler) handler {     NSMutableDictionary<FBOpenGraphObject> *object =     [FBGraphObject openGraphObjectForPostWithType:type                                             title:title                                             image:image                                               url:url                                       description:@""];     object[@"create_object"] = @"true";     object[@"fbsdk:create_object"] = @"true";          [FBRequestConnection startForPostOpenGraphObject:object                                    completionHandler:^(FBRequestConnection *connection, id result, NSError *error)      {          if (!error && result != nil)          {              NSLog([NSString stringWithFormat:@"Posting object '%@' (id=%@) is created!",                     title, [result objectForKey:@"id"]]);                            handler([result objectForKey:@"id"]);          }          else          {              NSLog([NSString stringWithFormat:@"Posting object creation error: %@", error]);          }      }]; }  + (void) postStory {     NSString* badge_title = @"Blue Badge";     NSString* badge_url = @"http://demo.tom3.html5.services.alawar.com/images/tester/blue_badge.htm";     NSString* badge_image = @"http://demo.tom3.html5.services.alawar.com/images/tester/blue_badge.png";     int rnd = arc4random() % 2;     if (rnd == 0)     {         badge_title = @"Red Badge";         badge_url = @"http://demo.tom3.html5.services.alawar.com/images/tester/red_badge.htm";         badge_image = @"http://demo.tom3.html5.services.alawar.com/images/tester/red_badge.png";     }          [FacebookController createOpenGraphObjectWithType:@"aw_test:badge"                                                 title:badge_title                                                 url:badge_url                                                 image:badge_image                                                 handler:^(NSString *objectId)     {         // action         NSMutableDictionary<FBGraphObject> *action = [FBGraphObject graphObject];         action[@"badge"] = objectId;         action[@"fb:explicitly_shared"] = @"1";                  [FBRequestConnection startForPostWithGraphPath:@"me/aw_test:find"                                            graphObject:action                                      completionHandler:^(FBRequestConnection *connection,                                                          id result,                                                          NSError *error)          {              if (!error && result != nil)              {                  NSLog([NSString stringWithFormat:@"Posted (id=%@)!", [result objectForKey:@"id"]]);              }              else              {                  NSLog([NSString stringWithFormat:@"Posting error: %@", error]);              }          }];     }]; } 

Внимательный читатель обратит внимание, что при выполнении кода для действия был добавлен дополнительный параметр.

action[@"fb:explicitly_shared"] = @"1";

Если этот параметр не выставлен, то созданная история попадет в Recent Activities пользователя, а не в таймлайн. Если все сделано правильно, то в таймлайн пользователя можно будет наблюдать нечто, похожее на рисунок ниже.

image

Последний момент, с которым необходимо разобраться: где и как хранятся описания объектов. Описание объекта хранится как специальным образом размеченный html-документ на каком-либо открытом сервере. Изображения также размещаются на открытых серверах, откуда их Facebook и загружает.

Вместо заключения

Если вы решились на интеграцию в игру Facebook помните, что это не минутное дело. Обязательно продумайте, как игра будет взаимодействовать с пользователем через Facebook. В противном случае вы получите вместо полезного инструмента для привлечения игроков очередное приложение досаждающие игрокам. Жалобы от игроков на спам приведут к тому, что Facebook забанит приложение, чего, разумеется, никому не хочется.
Как показывает практика, взять Facebook с наскока получается далеко не у всех. Мы надеемся, что приведенный нами опыт по интеграции этой социальной сети будет вам полезен.

ссылка на оригинал статьи http://habrahabr.ru/company/alawar/blog/214043/

Сбор лайткоинов в помощь вьетнамскому приюту

Пока некоторые центробанки считают, что криптовалюты нужны для финансирования терроризма и создания финансовых пирамид, энтузиаст из Вьетнама saigoned проводит акцию по сбору лайткоинов в поддержку детского приюта Gò Vấp, где много больных детей, в том числе испытывающих на себе последствия от «Агент Оранж».

Изначально saigoned связался с крупной вьетнамской газетой Thanh Niên и предложил им написать статью про лайткоины. Идея была в том, чтобы собрать в благотворительных целях лайткоинов на сумму в $1000, продемонстрировав таким образом возможности криптовалюты, и описать это в статье. После консультаций был выбран приют, который особо остро нужнается в средствах, и 3 февраля saigoned создал тему в сообществе LitecoinTalk с первоначальной целью собрать в течение месяца 50LTC (тогда лайткоины торговались дороже $20). И хотя с тех времён цена за LTC существенно упала, удалось достигнуть цели меньше, чем за месяц. Фактически сбор средств начался 13 февраля, и на момент написания этой статьи собрано 136LTC или около $1800. Собранную сумму можно в реальном времени отслеживать в Block-explorer’е.

Особенность акции в том, что средства принимаются исключительно в лайткоинах. Чтобы повысить доверие к акции, модератор форума ThomasFX взял на себя ответственность быть посредником в сборе средств. Являясь энтузиастом лайткоинов, saigoned не планирует сразу после сбора их продавать, а просто выдаст приюту из собственных денег эквивалент собранной суммы в долларах (по курсу BTC-E на момент окончания акции) или вьетнамских донгах. В поддержку сбора средств был изготовлен баннер, проведена фотосессия и снят небольшой видеоролик (видеографу заплатили в LTC!)

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