Как реагировать на асинхронные события (логин)? - PullRequest
0 голосов
/ 26 июля 2011

Я реализую некоторые функции Facebook в своем приложении для iPhone, для которых требуется вход в приложение. Сам логин больше не проблема, он работает.

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

Например:

У меня есть метод

- (void)refreshEvents;

Этот метод должен вызывать метод входа в систему, чтобы убедиться, что действие действительно может быть выполнено. Я звоню [self checkLogin], но что теперь? Как я могу ждать события, которое на самом деле не связано с моим методом? Поскольку checkLogin запускает асинхронные действия / события, я не могу просто сказать ему ждать, пока будет выполнен вход в систему.

В методе

- (void)request:(FBRequest *)request didLoad:(id)result;

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

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

Спасибо за вашу помощь

Arne

1 Ответ

1 голос
/ 26 июля 2011

Самое простое решение - передать блок завершения, который может быть выполнен после завершения входа в систему. Кроме того, вы можете передать блок, который вызывается в случае ошибки. В моих приложениях я обернул это в шаблон «ответчик», где вы определяете класс, который содержит блок завершения и ошибки. Это передается в качестве аргумента асинхронным методам. Единственный улов здесь заключается в том, что вы должны написать логин, чтобы «выполнить» блоки в соответствующее время.

Я реализовал этот шаблон несколько раз в приложениях, которые используют асинхронные API (включая Facebook SDK).

ОБНОВЛЕНИЕ (добавлено несколько примеров кода):

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

typedef void (^successBlock)(id);

Далее вы можете создать контроллер, который создает фасад для вашего взаимодействия с классом Facebook. В этом случае вы можете создать метод входа в систему с такой подписью (предполагается, что у вас есть iVar типа successBlock):

- (void)loginWithCompletionHandler:(successBlock)handler
{
    // If you aren't using ARC - you'll need to use Block_copy(handler)
    completionHandler = handler;

    [facebook authorize:facebookSettings.defaultPermissions 
               delegate:self];
}

Наконец, в вашей реализации FBSessionDelegate вы можете выполнить этот блок:

#pragma mark - FBSessionDelegate Implementation

- (void)fbDidLogin
{
    // Store Facebook token, etc.....

    if( completionHandler )
    {
        // You could pass any data you want in this data property
        completionHandler(data);
    }
}

}

Шаблон «Ответчик», о котором я упоминал выше, немного сложнее, чем этот, но этого должно быть достаточно, чтобы вы начали.

...