пятница, 15 февраля 2013 г.

Одноклассники в профиль





     Доброго всем времени суток, друзья. Вот и прошли зимние “каникулы”, для кого они были успешными, для кого иначе. И вот рабочие будни снова возвращаются  и привычный ритм  жизни потихоньку восстанавливается. В последние полторы недели, у меня была, одна из тривиальнейших задач для mobile developer-а  -   работа с социальной сетью, в данном случае это были - Одноклассники. Проблем, ни каких не предвиделось, но когда обычно так думаешь, в процессе вылезут такие баги, о которых даже и представления не  имеешь.        
  Сразу акцентирую внимание  - я отказался от использования Odnoklassniki SDK! Не буду говорить, что там есть серьезные проблемы, но они есть и те, кто выберет  SDK – удачи. 





    Начнем! 

     Для начала скажу, что для авторизации и получения данных  , я использовал технологию OAuth-протокола, так же как и в SDK Одноклассников.

     И первым делом, что бы получить возможность использовать их RestAPI и само собой размещать и регистрировать свои приложения у них на сайте, необходимо получить профиль Developer-a от Одноклассники.ру

    Первым этапом мы регистрируемся в их системе  JIRA (Профиль Developer-a), за тем заполняем форму регистрации на получение OAuth доступа

    На сайте Одноклассников можно глянуть не большой туториал по регистрации приложения тут. Заметьте, что мы выбираем не мобильное приложение, а во "Вне одноклассников"->"OAuth авторизация".

    После этих манипуляций, на ваш email придет письмо с тремя ключами:
    - Application ID (Индикатор приложения)
    - Public Key (Публичный ключ приложения)
    - Secret Key (секретный ключ, служит для подписи запросов)

    P.S. Есть один момент, который все почему-то пропускают. После того как вы получите профиль разработчика и ключи для приложения, что бы получить сведения о друзьях или контакте через API, необходимо еще написать письмо в поддержку Одноклассников  что бы они предоставили VALUABLE ACCESS для вашего профиля.


     Кодим!

     Из сторонних фреймфорков, я использовал - ASIHTTPRequest  и JSON. 

-    Документация и ссылки на исходники библиотеки ASIHTTPRequest - http://allseeing-i.com/ASIHTTPRequest/
 
-    JSON- https://github.com/Nuclominus/JSONParserIOS

-    Нам еще понадобиться написанный мной класс по работе с Одноклассниками - 
OdnoklassnikiBridge-IOS
 

Создаем новый проект

 

  Далее добавим выше описанные библиотеки/фреймворки в проект

Добавили фреймворки
   
    Следующим шагом мы добавим в проект те библиотеки, которые необходимы для правильной работы ASIHTTPReqwest.

Добавление библиотек

  Зайдем в наш xib  и  добавим на вью, UIWebView.

UIWebView

      

    Далее один из важнейших моментов (сам порой про него забывал;) )
    Добавляем ULR Types:
- в поле Identifier, пишем  - okurl
- URL Schemes - ok+Application ID (без "+")



    Теперь приступаем к коду.

   В основном ViewController-e:
- Делаем импорт класса Одноклассников и объявляем его переменную.
- Назначаем классу все необходимые делегаты для работы с интернетом.
- Создаем объект и свойство нашего WebView.

  #import <UIKit/UIKit.h>  
  #import "OSOdnoklassniki.h"  
  @interface OSViewController : UIViewController<UIApplicationDelegate, NSURLConnectionDelegate, NSURLConnectionDataDelegate,OdnoklassnikiDelegate,UIWebViewDelegate>  
  {  
    IBOutlet UIWebView * oauthWeb;  
    OSOdnoklassniki * apiOK;  
  }  
  @property (assign,nonatomic) IBOutlet UIWebView * oauthWeb;  
  @property (assign,nonatomic) id delegate;  
  @end  
ViewController.h

  Заходим в *.m файл  нашего контроллера и  в первую же очередь после импорта ашки(*.h), вписываем статические переменные наших индикаторов приложения какие мы получили по email.

  static NSString * appID = @"*********";  
  static NSString * appSecret = @"***************";  
  static NSString * appKey = @"***************";  
Свои я не писал ;)


  
  В методе viewDidLoad добавим несколько строчек:


   _oauthWeb.scalesPageToFit = TRUE;       // авторесайз страницы загружаемой в WebView
   apiOK = [[OSOdnoklassniki alloc]init];  // Инициализация класса Одноклассники
   apiOK.delegate = self;                  // Назначение делегата 
   _oauthWeb.delegate = self;              // Назначение делегата 
   apiOK.clientID = appID;                 // Передаем appID классу одноклассников 
   apiOK.appPublicKey = appKey;            // Передаем Публичный ключ
   apiOK.appSecretKey = appSecret;         // Передаем секретный ключ 
   [self authenticationOk];                // Вызываем метод Аутентификации

 
  Еще нужно добавить объявление еще нескольких методов:

- authenticationOk
   В этом методе мы посылаем запрос на авторизацию через WebView (под "******", подразумевается цифры из App ID)

 - (void)authenticationOk{    
      NSString *authString = @"http://www.odnoklassniki.ru/oauth/authorize?client_id=*******&response_type=code&redirect_uri=ok*******";  
      NSURL *authURL = [[NSURL alloc] initWithString:authString];  
      NSURLRequest *authRequest = [[NSURLRequest alloc] initWithURL:authURL];  
      [_oauthWeb loadRequest:authRequest];  
 }  


- logOut
  метод выхода из профиля после авторизации, я его в примере использовать не буду. (Обычная чистка куки)

 - (void)logOut{  
   NSHTTPCookie *cookie;  
   NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];  
   for (cookie in [storage cookies]) {  
     [storage deleteCookie:cookie];  
   }  
   [self authenticationOk];  
 }  


webView: shouldStartLoadWithRequest: navigationType:

   Этот метод позволит отловить момент когда придет ответ от сервера, после авторизации он вернет нам code, который позволит получить нам токен. (И тут все также присутствует наш App ID)

 // метод для соcтавления и посылки запроса на получение токена  
 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{  
   if([request.URL.absoluteString rangeOfString:@"ok*******/"].location != NSNotFound) {  
     NSLog(@"shouldStartLoadWithRequest =%@", request);  
       [apiOK requwestToken:request];  
       NSLog(@"DATA REQUEST = %@",[apiOK getDataRequest]);  
     }  
   return YES;  
 }  

Ну и последний метод

- showUp
  Это метод делегата класса одноклассников. Вообще я его писал для того, что бы  после окончательной авторизации (после того как получили токен) перейти на следующую вью. В примере, я вписал туда запрос на список друзей, об этом дальше.

 - (void) showUp:(OSOdnoklassniki *)api{  
   [apiOK requestAPIData:@"GET" requestRestAPI:@"friends.get" withParams:nil withTagOfRequest:1];  
 }  

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


 
    P.S. Для тех кто не понял - русский язык приходит в UTF8 ;)


   OSOdnoklssniki


   Пройдемся по основным методам в классе, который я написал для работы с соц. сетью
 
    Код я приводить больше не буду, комментарии там есть, если будут вопросы пишите мне в скайп (Mitsuhide_Aketi).
 
- requestToken
    После авторизации нам приходит code, который нужен для получения токена. Как только мы получаем токен, срабатывает метод showUp, позволяя нам работать дальше.

- requestAPIData: requestRestAPI: withParams: withTagOfRequest:
  Основной метод для посылки запроса с RestAPI. Основным параметром, я отметил для себя - tag(тэг запроса), т.к. любой ответ от сервера приходит в один и тот же метод. Что бы распознать какой именно это ответ(по какому запросу), я пометил запрос тегом и в методе requestFinished получая ответ делаю то что мне нужно.

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


 Выводы

  Задачи, которые были поставлены передо мной - решил своими силами. До этого полтора дня потратил на реализацию через SDK, но так и не получил желаемого результата. Надеюсь люди из поддержки OK SDK, доведут дело до конца ;)



 Всем удачного кодинга и не пыльных проектов!

 Вот пример проекта, без данных Developer-a ;) 

Комментариев нет :

Отправить комментарий