Facebook SDK v4.0 для iOS — FBSDKProfile currentProfile не установлен

Я только что «обновил» свой Facebook SDK до версии 4.0 для своего приложения iOS.

У меня есть журнал, работающий нормально, однако, согласно документации, теперь я должен использовать FBSDKProfile.currentProfile() для доступа к информации профиля.

Однако это значение всегда выглядит как nil, даже несмотря на то, что изображение моего профиля отображается (через FBSDKProfilePictureView), а мое FBSDKAccessToken.currentAccessToken() не равно nil.

Это мой логин ViewController:

import UIKit

class LoginViewController: UIViewController, FBSDKLoginButtonDelegate {

    @IBOutlet weak var fbLoginButton: FBSDKLoginButton!
    @IBOutlet weak var fbProfilePicture: FBSDKProfilePictureView! //displays a picture

    override func viewDidLoad() {
        super.viewDidLoad()
        self.fbLoginButton.delegate = self
        FBSDKProfile.enableUpdatesOnAccessTokenChange(true)
        if FBSDKAccessToken.currentAccessToken() != nil {
            println("\(FBSDKAccessToken.currentAccessToken().userID)") //works
        }
        self.fbLoginButton.readPermissions = ["public_profile", "email", "user_friends"]
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
        println(FBSDKProfile.currentProfile()) //is nil
    }

    func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
    }
}

Любые идеи?


person fanfan    schedule 27.03.2015    source источник


Ответы (8)


Выборка FBSDKProfile может быть не завершена к моменту обратного вызова при входе в систему. Вместо этого вы можете наблюдать за сообщением уведомления «FBSDKProfileDidChangeNotification».

person Chris Pan    schedule 27.03.2015
comment
Похоже дело в этом, спасибо. Как (и когда) именно я должен наблюдать за изменением этой строки? - person fanfan; 28.03.2015
comment
Как и другие уведомления NSNotification, вы обычно можете наблюдать это в viewDidLoad любых контроллеров представления, которым необходимо работать с этими данными. - person Chris Pan; 30.03.2015

Не забудьте FBSDKProfile.enableUpdatesOnAccessTokenChange(true)!! Я некоторое время боролся с этим, пока не нашел это в документах. Затем подписка на уведомления в FBSDKProfileDidChangeNotification должна работать для FBSDKLoginButton.

Полный пример... Я подключаю loginButton через Interface Builder

class LoginController: UIViewController, FBSDKLoginButtonDelegate {

@IBOutlet var loginButton: FBSDKLoginButton!

override func viewDidLoad() {
    super.viewDidLoad()
    loginButton.delegate = self;
    FBSDKProfile.enableUpdatesOnAccessTokenChange(true)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "onProfileUpdated:", name:FBSDKProfileDidChangeNotification, object: nil)

}

func onProfileUpdated(notification: NSNotification)
{
}

func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!){

}

func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {

}

}

person Johnny Z    schedule 28.03.2015
comment
Мне это не помогло. Мне пришлось вручную сделать запрос на получение профиля пользователя. - person nerowolfe; 29.03.2015
comment
Исправление: теперь это работает. Итак, основные якоря: сделать FBSDKProfile.enableUpdatesOnAccessTokenChange(true) в viewDidLoad. А также вы должны подписаться на name:FBSDKProfileDidChangeNotification, потому что вы узнаете об изменении профиля только после этого уведомления. Но проблема в том, что этот профиль не содержит электронной почты пользователя. Чтобы получить электронную почту, вы должны использовать мой запрос - person nerowolfe; 29.03.2015
comment
Кроме того, могу отметить, что я не мог получить профиль без использования FBSDKLoginButton. Итак, только с FBSDKLoginManager этот метод не работает - person nerowolfe; 29.03.2015
comment
для obj-c: [FBSDKProfile enableUpdatesOnAccessTokenChange:YES]; и это очень помогло... спасибо! - person Derek; 10.04.2015
comment
Спасибо за полный пример - person Damo; 28.05.2015
comment
Это ключевая фраза, спасибо. Кстати, по образцу кода Scrumptious эту строку можно поместить в функцию didFinishLaunchingWithOptions AppDelegate - person Dino Tw; 16.05.2016
comment
Предложение Эрика Алфорда легко работает без необходимости прослушивания уведомлений и всех других дополнительных шагов. - person ArdenDev; 30.07.2016
comment
Спасибо. Я не думаю, что этот интерфейс был доступен, когда я писал этот ответ. Все, кто читает, посмотрите ответ Эрика Алфорда. - person Johnny Z; 31.07.2016
comment
Для Swift 3.0 NotificationCenter.default.addObserver(self, selector: #selector(ViewController.handleFBDelegate), name:NSNotification.Name.FBSDKProfileDidChange, object: nil) - person Starlord; 14.11.2016

Для тех из вас, кто ищет более обновленный ответ и более чистый подход, чем использование NSNotificationCenter, есть метод класса в FBSDKProfile, который вы можете вызвать после входа в систему, который выглядит так:

[FBSDKProfile loadCurrentProfileWithCompletion:^(FBSDKProfile *profile, NSError *error) {

}];
person Eric Alford    schedule 27.06.2016
comment
Спасибо, это намного лучше, чем слушать уведомления. Естественный поток в коде. - person ArdenDev; 30.07.2016
comment
Полезно наконец :D - person Sanjith Bravo Dastan; 27.09.2016
comment
Лучшее решение, спасибо! ... еще лучше было бы, если бы FB SDK не вызывал обработчик входа в систему до загрузки профиля. - person shelll; 23.03.2018

Я в objc, но тоже столкнулся с этой проблемой.

Во-первых, ответ Johnny Z верен, что вы должны явно включить класс FBSDKProfile, установив для параметра enableUpdatesOnAccessTokenChange значение true, а затем наблюдая за изменениями. Фактически, это то, что FBSDKProfile делает внутри, согласно комментариям в заголовке.

Однако, как отметил fanfan в комментарии, FBSDKProfile не имеет всех полей, которые могут вас заинтересовать. В итоге я не использовал FBSDKProfile и просто сделал запрос графика для «меня» следующим образом:

    [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:nil]
         startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
             if (error) {
                 CLS_LOG(@"Login error: %@", [error localizedDescription]);
                 return;
             }

             NSLog(@"fecthed user: %@", result);
}];

Примечание. Вы по-прежнему можете отслеживать изменения с помощью уведомления «FBSDKProfileDidChangeNotification». Прочтите комментарии FBSDKAccessToken.h для документации этого уведомления и ключей, которые оно отправляет.

person Chad Pavliska    schedule 06.04.2015
comment
Работал для меня! Спасибо !! - person youssman; 03.05.2015

В Objective-C я использовал следующий подход, основанный на комментариях в этой ветке.

Если для этого флага установлено значение yes, после входа или выхода из системы будет вызываться уведомление. Итак, в viewDidLoad добавьте эту строку кода и добавьте уведомление, которое будет вызываться после получения профиля пользователя.

[FBSDKProfile enableUpdatesOnAccessTokenChange:YES];

[[NSNotificationCenter defaultCenter] addObserverForName:FBSDKProfileDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
     //do whatever you want
}];

Вся информация по этой ссылке https://developers.facebook.com/docs/facebook-login/ios/v2.3#profiles

person Pedro Romão    schedule 14.04.2015

Похоже, вам нужно вызвать метод AppDelegate для инициализации SDK перед вызовом enableUpdatesOnAccessTokenChange:YES

Я сделал свой метод AppDelegate didFinishLaunching таким

BOOL fbsdk = [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions]; [FBSDKProfile enableUpdatesOnAccessTokenChange:YES]; return fbsdk;

Казалось, это сработало. Вам по-прежнему может потребоваться выполнить запрос /me, если вам нужны элементы, которых нет в объекте профиля.

person Brian Broom    schedule 22.05.2015

У меня была аналогичная проблема с [FBSDKProfile currentProfile], но в Objective-C вы также можете получить свойства профиля пользователя из Graph API с ответом на https://graph.facebook.com/me?access_token= с вашим currentAccessToken.

person Andrei Ogrenich    schedule 28.03.2015
comment
Похоже, что в любом случае это может быть правильным способом, поскольку в FBSDKProfile отсутствует некоторая информация (например, электронная почта). - person fanfan; 31.03.2015

версия Свифт 4,

FBSDKProfile.loadCurrentProfile(completion: {
        profile, error in
        let url = profile?.imageURL(for: FBSDKProfilePictureMode.square, size:  self.imageview.frame.size)
    })
person cnu    schedule 23.04.2018