Monday, April 29, 2013

Предикаты, синтаксис формата строки Cocoa http://macbug.ru/cocoa/predformat

http://macbug.ru/cocoa/predformat

Предикаты, синтаксис формата строки

Cocoa

Анализатор строки отличается от строки выражения, переданной движку регулярных выражений. В этой статье описывается анализатор текста, а не синтаксис для движка регулярных выражений.

Основы синтаксического анализатора

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

Переменные обозначаемые с $ (для примера $VARIABLE_NAME). ? не является допустимым шаблоном анализатора.

Формат строки поддерживает printf стиль формат для аргументов, такие как %x (см. "Форматирование строковых объектов"). Два важных аргумента: @% и %K.

  • %@ является аргументом замещения для объекта обозначающим чаще всего строку, число или дату.
  • %K является аргументом замещения для ключа пути

Когда строки переменных подставляются в строку, используя формат %@, они заключены в кавычки. Если вы хотите указать имя динамического свойства, используйте%K в строке формата, как показано в следующем примере.

NSString *attributeName = @"firstName";  NSString *attributeValue = @"Adam";  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@",          attributeName, attributeValue];  

Строка формата предиката в этом случае вычисляется как firstName like "Adam".

Одинарные или двойные кавычки переменных (или строки замещения переменной) вызываемых %@%K, или $variable следует интерпретировать в качестве литералов в строке формата и таким образом предотвращать любую подмену. В следующем примере строка формата предиката вычисляется как firstName like "%@" (обратите внимание на одинарные кавычки вокруг %@).

NSString *attributeName = @"firstName";  NSString *attributeValue = @"Adam";  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like '%@'",          attributeName, attributeValue];  

 

Примечание: Вы можете использовать %@ для замены выражения, но вы не можете использовать его, чтобы передать весь предикат.

Основные сравнения

=, ==
Левое выражение равно правому выражению.

>=, =>
Левое выражение больше или равно правому выражению.

<=, =<
Левое выражение меньше или равно правому выражению.

>
Левое выражение больше правого выражения.

<
Левое выражение меньше правого выражения.

!=, <>
Левое выражение не равно правому выражению.

BETWEEN
Левое выражение между ними, или равно одному из значений, указанных в правой части.

Правая часть состоит из массива с двумя значениями (массив необходим для указания порядка), задавая верхнюю и нижнюю границы. Например 1 BETWEEN { 0 , 33 }, or $INPUT BETWEEN { $LOWER, $UPPER }.

В Objective-C, вы можете создать BETWEEN предикат, как показано в следующем примере:

NSPredicate *betweenPredicate =           [NSPredicate predicateWithFormat: @"attributeName BETWEEN %@",          [NSArray arrayWithObjects:one, ten, nil]];  
Это создает предикат, который соответствует ( ( 1 <= attributeValue ) && ( attributeValue <= 10 ) ), как проилюстрированно ниже:
NSNumber *one = [NSNumber numberWithInteger:1];  NSNumber *ten = [NSNumber numberWithInteger:10];  NSPredicate *betweenPredicate =           [NSPredicate predicateWithFormat: @"attributeName BETWEEN %@",          [NSArray arrayWithObjects:one, ten, nil]];    NSNumber *five = [NSNumber numberWithInteger:5];  NSDictionary *dictionary = [NSDictionary dictionaryWithObject:five          forKey:@"attributeName"];    BOOL between = [betweenPredicate evaluateWithObject:dictionary];  if (between) {      NSLog(@"between");  }  

Предикаты булевых значений

TRUEPREDICATE
Предикат, который всегда вычисляется как TRUE.

FALSEPREDICATE
Предикат, который всегда вычисляется как FALSE.

Основные соединения предикатов

AND, &&
Логическое AND.

OR, ||
Логическое OR.

NOT, !
Логическое NOT.

Сравнение строк

Сравнение строк по умолчанию регистро и диакритически чувствительны. Вы можете изменить оператор с использованием ключевых символов c и d в квадратных скобках, чтобы указать нечувствительность к регистру и диакритическим символам соответственно, например, firstName BEGINSWITH[cd] $FIRST_NAME.

BEGINSWITH
Левое выражение начинается с правого выражения.

CONTAINS
Левое выражение содержит правое выражение.

ENDSWITH
Левое выражение оканчивается с правым выражением.

LIKE
Левое выражение равно правому выражению: ? и * разрешены как символы подстановки, где ? соответствует 1-му символу а * соответствует 0 или более символов. В Mac OS X v10.4, подстановочные символы не соответствуют символу новой строки.

MATCHES
Левое выражение равно правому, используя выражение в стиле сравнения регулярных выражений в соответствии с ICU v3.

Совокупные операции

ANY, SOME
Задает любой из элементов в следующем выражении. К примеру ANY children.age < 18.

ALL
Определяет все элементы в следующем выражении. К примеру ALL children.age < 18.

NONE
Указывает, ни один из элементов в следующем выражении. К примеру NONE children.age < 18. Это логически эквивалентно NOT (ANY ...).

IN
Эквивалент SQL оператора IN, левая сторона должна появиться в коллекции указанной с правой стороны.

Например, name IN { 'Ben', 'Melissa', 'Matthew' }. Коллекция может быть массивом, набором, или словарем в случае словаря, используются его значения.
В Objective-C, можно создать предикат, как показано в следующем примере:

NSPredicate *inPredicate =      [NSPredicate predicateWithFormat: @"attribute IN %@", aCollection];  
где aCollection может быть экземпляром NSArrayNSSetNSDictionary, или любым изменяемым из соответствующих классов.

array[index]
Определяет элемент по указанному индексу в массиве array.

array[FIRST]
Определяет первый элемент в массиве array.

array[LAST]
Определяет последний элемент в массиве array.

array[SIZE]
Определяет размер массива array.

Идентификаторы

C style identifier
Любой идентификатор в C стиле, который не является зарезервированным словом.

#symbol
Используется, для экранирования зарезервированных слов в пользовательских идентификаторах.

[\]{octaldigit}{3}
Используется для экранирования восьмеричного числа (\, затем 3 восьмеричные цифры).

[\][xX]{hexdigit}{2}
Используется для экранирования шестнадцатиричного числа (\x или \X, затем 2 шестнадцатиричные цифры).

[\][uU]{hexdigit}{4}
Используется для экранирования Unicode числа (\u или \U, затем 4 шестнадцатиричные цифры).

Литералы

Одинарные и двойные кавычки дают одинаковый результат, но они не прекращают друг друга. Например, "abc" и 'abc' являются идентичными, в то время как"a'b'c" эквивалентно разделенным пробелами конкатенации a'b'c.

FALSE, NO
Логическое ложь.

TRUE, YES
Логическое истина.

NULL, NIL
Нулевое значение.

SELF
Представляет объект оценки.

"text"
Символьная строка.

'text'
Символьная строка.

Массив из литералов разделенных запятыми
Пример: { 'comma', 'separated', 'literal', 'array' }

Стандартные обозначения целых и с фиксированной точкой
Пример: 1212.7182819.75.

С плавающей точкой записанное с экспонентой
Пример: 9.2e-5.

0x
Префикс, используемый для обозначения последовательности шестнадцатеричных цифр.

0o
Префикс, используемый для обозначения последовательности восьмеричных цифр.

0b
Префикс, используемый для обозначения последовательности двоичных цифр.

Зарезервированные слова

AND , OR , IN , NOT , ALL , ANY , SOME , NONE , LIKE , CASEINSENSITIVE , CI , MATCHES , CONTAINS , BEGINSWITH , ENDSWITH , BETWEEN , NULL , NIL , SELF ,TRUE , YES , FALSE , NO , FIRST , LAST , SIZE , ANYKEY , SUBQUERY , CAST , TRUEPREDICATE , FALSEPREDICATE

Создание предикатов Cocoa http://macbug.ru/cocoa/predcreate

http://macbug.ru/cocoa/predcreate

Создание предикатов

Cocoa

Есть три способа создания предиката в Cocoa: используя формат строки, непосредственно в коде, и с шаблоном предиката.

Создание предикатов с помощью формата строки

Вы можете использовать методы класса NSPredicate вида predicateWithFormat... для создания предиката непосредственно из строки. Необходимо определить предикат в виде строки, при необходимости используя подстановки. Во время выполнения выполняются подстановки переменных, если таковые имеются, и в результате эта строка может быть использована для создания соответствующего предиката и выражений объектов. В следующем примере создается соединение предиката с двумя предикатами сравнения.

NSPredicate *predicate = [NSPredicate      predicateWithFormat:@"(lastName like[cd] %@) AND (birthday > %@)",              lastNameSearchString, birthdaySearchDate];  

(в примере like[cd] означает "без учета регистра и диакритических знаков").

Полное описание синтаксиса строки и список операторов, доступных в разделе "Пердикаты, синтаксис формата строки".

Важно. Синтаксис формата строки предиката отличается от синтаксиса регулярных выражений.

Синтаксический анализатор строки предиката разбирает пробельные символы, регистр по отношению к ключевым словам, а также поддерживает вложенные в скобки выражения. Он также поддерживает в стиле printf формат аргументов (например, x% и %@) см. "Форматирование строковых объектов". Переменные обозначаются $ (например, $VARIABLE_NAME).

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

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

Строковые константы, переменные и шаблоны

Строковые константы должны быть заключены в кавычки в выражении, одинарные и двойные кавычки являются приемлемыми, но должны работать в паре соответствующим образом (то есть двойные кавычки (") не соответствует одинарным кавычкам (')). Если вы используете подстановку переменных с помощью %@(например, как firstName like %@) кавычки добавляются автоматически. Если вы используете строковые константы в вашей строке формата, вы должны привести их самостоятельно, как в следующем примере.

NSPredicate *predicate = [NSPredicate      predicateWithFormat:@"lastName like[c] \"S*\""];  

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

NSString *prefix = @"prefix";  NSString *suffix = @"suffix";  NSPredicate *predicate = [NSPredicate    predicateWithFormat:@"SELF like[c] %@",    [[prefix stringByAppendingString:@"*"] stringByAppendingString:suffix]];  BOOL ok = [predicate evaluateWithObject:@"prefixxxxxxsuffix"];  

В этом примере замена переменной производит строку предиката SELF LIKE[c] "prefix*suffix" и значение реременной ok устанавливается в YES.

Следующий фрагмент, напротив, приводит к строке предиката SELF LIKE[c] "prefix" * "suffix" и предикат выдаст сообщение об ошибке выполнения:

predicate = [NSPredicate      predicateWithFormat:@"SELF like[c] %@*%@", prefix, suffix];  ok = [predicate evaluateWithObject:@"prefixxxxxxsuffix"];  

Булевы значения

Можно указать и проверить равенство логических значений, как показано в следующем примере:

NSPredicate *newPredicate =      [NSPredicate predicateWithFormat:@"anAttribute == %@",       [NSNumber numberWithBool:aBool]];         NSPredicate *testForTrue =      [NSPredicate predicateWithFormat:@"anAttribute == YES"];  

Динамические имена свойств

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

NSString *attributeName = @"firstName";  NSString *attributeValue = @"Adam";  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ like %@",          attributeName, attributeValue];  

Формат строки предиката в этом случае вычисляется как "firstName" like "Adam".

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

predicate = [NSPredicate predicateWithFormat:@"%K like %@",          attributeName, attributeValue];  

Формат строки предиката в этом случае вычисляется как firstName like "Adam" (обратите внимание, что нет никаких кавычек вокруг firstName).

Создание предикатов непосредственно в коде

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

Следующий пример показывает, как создать предикат для представления (revenue >= 1000000) and (revenue < 100000000). Обратите внимание, что то же самое в левой части выражения используется для сравнения предикатов.

NSExpression *lhs = [NSExpression expressionForKeyPath:@"revenue"];    NSExpression *greaterThanRhs = [NSExpression expressionForConstantValue:      [NSNumber numberWithInt:1000000]];    NSPredicate *greaterThanPredicate = [NSComparisonPredicate      predicateWithLeftExpression:lhs      rightExpression:greaterThanRhs      modifier:NSDirectPredicateModifier      type:NSGreaterThanOrEqualToPredicateOperatorType      options:0];     NSExpression *lessThanRhs = [NSExpression expressionForConstantValue:      [NSNumber numberWithInt:100000000]];    NSPredicate *lessThanPredicate = [NSComparisonPredicate      predicateWithLeftExpression:lhs      rightExpression:lessThanRhs      modifier:NSDirectPredicateModifier      type:NSLessThanPredicateOperatorType      options:0];    NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:      [NSArray arrayWithObjects:greaterThanPredicate, lessThanPredicate, nil]];  

Недостатком этого метода по-видимому можно считать что, вам придется писать много кода. Преимущество в том, что он менее склонен к орфографии и другим типографским ошибкам, которые могут быть обнаружены только во время выполнения, и это может быть быстрее, чем в зависимости от анализа строк.

Создание предикатов, используя шаблоны предикатов

Шаблоны предиката предлагают хороший компромисс между простыми в использовании, но потенциально подверженными ошибкам строкам формата на основе подхода техники интенсивного и чистого кодирования кода. Шаблон предиката - просто предикат, который включает в себя переменные выражения. (Если вы используете Core Data framework, вы можете использовать инструменты разработки Xcode, чтобы добавить предикат шаблона выбором для запросов к модели. В следующем примере используется формат строки для создания предикатов с правой стороной, которая является переменной выражения.

NSPredicate *predicateTemplate = [NSPredicate      predicateWithFormat:@"lastName like[c] $LAST_NAME"];  

Это эквивалентно созданию непосредственно переменной выражения, как показано в следующем примере.

NSExpression *lhs = [NSExpression expressionForKeyPath:@"lastName"];    NSExpression *rhs = [NSExpression expressionForVariable:@"LAST_NAME"];    NSPredicate *predicateTemplate = [NSComparisonPredicate      predicateWithLeftExpression:lhs      rightExpression:rhs      modifier:NSDirectPredicateModifier      type:NSLikePredicateOperatorType      options:NSCaseInsensitivePredicateOption];  

Чтобы создать допустимый предикат для оценки объекта, можно использовать NSPredicate метод predicateWithSubstitutionVariables: для прохода по словарю, который содержит переменные, которые будут замещены. (Заметим, что словарь должен содержать пары ключ-значение для всех переменных, указанных в предикате).

NSPredicate *predicate = [predicateTemplate predicateWithSubstitutionVariables:      [NSDictionary dictionaryWithObject:@"Turner" forKey:@"LAST_NAME"]];  

новый предикат возвращаемый этим примером lastName LIKE[c] "Turner".

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

NSPredicate *predicate = [NSPredicate      predicateWithFormat:@"date = $DATE"];  predicate = [predicate predicateWithSubstitutionVariables:      [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"DATE"]];  

новый предикат возвращаемый этим примером date == <null>.

Формат строки, итоги

Важно провести различие между различными типами значений в строке формата. Отметим также, что одинарные или двойные кавычки в переменных (или строке замещающей переменную) служат основанием интерпретировать %@%K, или $ переменные как литералы в формате строк и так будет предохранять любую подмену.

@"attributeName == %@"
Этот предикат проверяет, является ли значение ключа attributeName таким же, как и значение объекта %@, который подставляется во время работы в качестве аргумента predicateWithFormat:. Обратите внимание, что %@ может быть заполнителем для любого объекта, описание которого действует в предикате, например, экземпляр NSDateNSNumberNSDecimalNumber или NSString.

@"%K == %@"
Этот предикат проверяет, является ли значение ключа %K таким же, как значение объекта @%. Переменные поставляются во время выполнения в качестве аргументов predicateWithFormat:.

@"name IN $NAME_LIST"
Это шаблон для предиката, который проверяет, является ли значение ключа с именем в переменной $NAME_LIST (без кавычек), которая подставляется во время выполнения predicateWithSubstitutionVariables:.

@"'name' IN $NAME_LIST"
Это шаблон для предиката, который проверяет наличие постоянной величины 'name' (обратите внимание на кавычки вокруг строки) в переменной $NAME_LISTкоторая предоставляется во время выполнения predicateWithSubstitutionVariables:.

@"$name IN $NAME_LIST"
Это шаблон для предиката, который рассчитывает значения для заменены (с использованием predicateWithSubstitutionVariables:) для обоих $name и $NAME_LIST.

@"%K == '%@'"
Этот предикат проверяет, является ли значение ключа %K равно строке '%@' (обратите внимание на одинарные кавычки вокруг %@). Ключ с именем %Kподставляется во время выполнения в качестве аргумента predicateWithFormat:.

Saturday, April 27, 2013

oauth2 ios http://stackoverflow.com/questions/5374570/whats-the-best-ios-oauth2-framework

http://stackoverflow.com/questions/5374570/whats-the-best-ios-oauth2-framework

oauth2 ios 

Can't seem to find a good, easy to use OAuth 2 framework anywhere. I'm looking for something easy like ASIHTTPRequest. Anyone have experience?

Take a look at this GitHub project: https://github.com/nxtbgthng/OAuth2Client

If you're using the AFNetworking library, you could consider the AFOAuth2Client extension.

I've used google's oauth framework and it works very well. It's pretty complete and was easy enough for me to make a couple minor updates to (ui mostly).

http://code.google.com/p/gtm-oauth/

I don't like sharing the secret either, but I guess I disagree with your statement. It's typical for apps to have the key and secret defined (say in a constants file). I think even Amazons AWS SDK requires the app to know secret...it's part of the app authentication process...when the app is installed (unless there is some jailbroken thing I don't now about), the users should only ever be able to see your apps binary and any image files. – Nathan Jones Jun 30 '11 at 3:06
1  
One thing to take into account is that gtm-oauth follows the spec very closely. It doesn't work with OAuth2 services that return the token in form-format (it only works with JSON format). While the spec does specify JSON, some OAuth2 implementations (for example github's) still return the token in form values. – Ivo Jansch Sep 3 '11 at 16:37
2  
gtm-oauth2 does now support legacy implementations that return the tokens in form-style responses, though those implementations should update to the spec. – grobbins Sep 24 '11 at 16:25
Thanks for the pointer to gtm-oauth2 @grobbins. For reference the documentation is atcode.google.com/p/gtm-oauth2 – Domenic D. Oct 24 '12 at 17:59

LROAuth2Client seems to be another solid implementation.

MixioAuthFramework appears to be another OAuth2 library.

FROAuth2Request is OAuth2 Support for the well known ASIHTTPRequest Lib.

oAuth авторизация в iOS http://blog.zakovinko.com/2012/04/oauth-ios.html

http://blog.zakovinko.com/2012/04/oauth-ios.html

oAuth авторизация в iOS

Нашел хорошую библиотечку, в которой реализована поддержка oAuth 1 & oAuth 2 для iOS/Mac OS. К сожалению, документации по ней нет, зато есть демка использования, в которой реализована поддержка авторизации для twitter, facebook, flickr, qq.

Далее расскажу как я делал авторизацию LinkedIn с ее помощью.

Создаем новый проект "Single View Application", у меня он будет называться "LinkedInAuth".

Подключаем зависимости:

Теперь нужно указать дополнительные флаги линкеру (это требует ytoolkit).

  • открываем "Build Settings"
  • в разделе "Linking" находим "Other Linker Flags" и добавляем туда "-all_load" и "-ObjC" (если вы не видите "Other Linker Flags" переключите отображение списка на "All")

Нам нужен класс в проекте, в котором будут хранится ключ и секрет от LinkedIn'а. Для этого добавляем новый "Objective-C class" под названием "AuthCredentials", унаследованный от "NSObject". Мы потом уберем обьявленый Xcode'ом интерфейс.

В "AuthCredentials.h" обявлием константы kLinkedInKey и kLinkedInSecret:

#import <Foundation/Foundation.h>  #import <ytoolkit/ydefines.h>    YEXTERN NSString * const kLinkedInKey;  YEXTERN NSString * const kLinkedInSecret;  

А в "AuthCredentials.m" указываем значения наших констант:

#import "AuthCredentials.h"    NSString * const kLinkedInKey = @"сюда вписываем ключ";  NSString * const kLinkedInSecret = @"а сюда секрет )";  

Добавляем в проект новый "Objective-C class", который назовем "AuthViewController" и наследуем от "UIViewController". Также не забываем поставить галку "With XIB for user interface".

Открываем AuthViewController.h и приводим его вот к такому виду:

#import <UIKit/UIKit.h>  #import <ytoolkit/ydefines.h>  #import "ASIHTTPRequest.h"    @class AuthViewController;    @protocol AuthViewControllerDelegate  - (void)authViewControllerDidFinish:(AuthViewController *)controller;  @end    @interface AuthViewController : UIViewController <UIWebViewDelegate, ASIHTTPRequestDelegate>    @property (assign, nonatomic) id<AuthViewControllerDelegate> delegate;  @property (retain, nonatomic) IBOutlet UIWebView *webView;  @property (copy, nonatomic) NSString *accesstoken;  @property (copy, nonatomic) NSString *tokensecret;  @property (copy, nonatomic) NSString *verifier;  @property (copy, nonatomic) NSString *step; // нужен что бы в будующем понимать на каком шаге авторизации мы находимся    - (IBAction)done:(id)sender;    @end  

Открываем AuthViewController.xib, добавляем на него WebView и привязываем к нашему webView(с зажатым "control" тянем связть от "File's Owner" до "WebView" и из выпавшего списка выбираем "webView") и в обратном порядке выбирая delegate.

Теперь можно перейти к самой большой части, непосредственно к функционалу авторизации через LinkedIn для этого открываем наш AuthViewController.m и добавляем в него код.

Для начала прописываем нужные импорты:

#import "ASIHTTPRequest+YOAuthv1Request.h"  #import "AuthCredentials.h"  #import "SBJson/SBJson.h"  #import <ytoolkit/ymacros.h>  #import <ytoolkit/ycocoaadditions.h>  #import <ytoolkit/yoauthadditions.h>  

В "viewDidLoad" начинам процедуру авторизации:

// создаем запрос  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"https://api.linkedin.com/uas/oauth/requestToken"]];  request.delegate = self; // указываем что мы будем обрабатывать ответ  [request setRequestMethod:@"POST"]; // тип запроса POST  // вызываем функцию подготовки запроса, которая добавит нужные параметры в url  [request prepareOAuthv1AuthorizationHeaderUsingConsumerKey:kLinkedInKey                                           consumerSecretKey:kLinkedInSecret                                                       token:nil                                                 tokenSecret:nil                                             signatureMethod:YOAuthv1SignatureMethodHMAC_SHA1                                                       realm:nil                                                    verifier:nil                                                    callback:@"http://linkedinauth"]; // линк нашего приложения  self.step = @"0"; // это первый шаг  [request startAsynchronous];  

Добавляем метод который покажет ошибку если она произошла:

- (void)requestFailed:(ASIHTTPRequest *)request {      UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"LinkedIn Auth"                                                       message:[request.error localizedDescription]                                                      delegate:nil                                             cancelButtonTitle:@"OK"                                             otherButtonTitles:nil]                            autorelease];      [alert show];  }  

И обработчик вернувшегося запроса:

- (void)requestFinished:(ASIHTTPRequest *)request {      NSDictionary *params = [request.responseString decodedUrlencodedParameters];      self.accesstoken = [params objectForKey:YOAuthv1OAuthTokenKey]; // забираем токены      self.tokensecret = [params objectForKey:YOAuthv1OAuthTokenSecretKey];            if (self.accesstoken && self.tokensecret) {          if ([self.step isEqualToString:@"0"]) {         // если есть токены и это первый шаг, то открываем страницу авторизации LinekdIn в нашем WebView              NSString *url = [NSString stringWithFormat:@"https://www.linkedin.com/uas/oauth/authorize?%@=%@", YOAuthv1OAuthTokenKey, self.accesstoken];              NSMutableURLRequest *r = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];              [self.webView loadRequest:r];          } else {              // если шаг не первый, то завершаем процесс авторизации              [self.delegate authViewControllerDidFinish:self];          }      }  }  

Теперь ловим обновление WebView:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {      NSURL *url = request.URL;      NSString *s = [url absoluteString];      NSString *host = [url host];            // если загружаемый урл принадлежит нашему приложению      if ([host isEqualToString:@"linkedinauth"]) {          NSDictionary *params = [s queryParameters];          // проверяем не заприщен ли доступ          if ([params objectForKey:@"denied"] == nil) {              self.verifier = [params objectForKey:YOAuthv1OAuthVerifierKey]; // сохраняем верификационный код              ASIHTTPRequest *r = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"https://api.linkedin.com/uas/oauth/accessToken"]];              [r setRequestMethod:@"POST"];              r.delegate = self;              // отправляем запрос авторизации наших токенов              [r prepareOAuthv1AuthorizationHeaderUsingConsumerKey:kLinkedInKey                                                 consumerSecretKey:kLinkedInSecret                                                             token:self.accesstoken                                                       tokenSecret:self.tokensecret                                                   signatureMethod:YOAuthv1SignatureMethodHMAC_SHA1                                                             realm:nil                                                          verifier:self.verifier                                                          callback:nil];              self.step = @"1"; // дальше пошел второй шаг              [r startAsynchronous];          } else {              NSString *deniedMsg = [NSString stringWithFormat:@"authorize denied: %@", [params objectForKey:@"denied"]];              UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:[[self class] description]                                                               message:deniedMsg                                                              delegate:nil                                                     cancelButtonTitle:@"OK"                                                     otherButtonTitles:nil]                                    autorelease];              [alert show];          }                    return NO;      }            return YES;  }  

Вот собственно и все. Осталось только сохранить полученные нами токены. Для этого мы в "ViewController.h" добавляем объявление переменных, импорт контролера авторизации и делегирование AuthViewControllerDelegate:

#import <UIKit/UIKit.h>  #import "AuthViewController.h"    @interface ViewController : UIViewController <AuthViewControllerDelegate>    @property (strong, nonatomic) NSString *accesstoken;  @property (strong, nonatomic) NSString *tokensecret;    @end  

Сохранение полученных значений в "ViewController.m":

- (void)authViewControllerDidFinish:(AuthViewController *)controller {      self.accesstoken = controller.accesstoken;      self.tokensecret = controller.tokensecret;      [self dismissModalViewControllerAnimated:YES];  }  


Исходный код: скачать