Facebook SDK внутри расширения приложения iOS не может найти вошедшего пользователя?

#ios-app-extension #fbsdk

#ios-app-extension #fbsdk

Вопрос:

Я создал пример расширения общего доступа к приложению. Следовал инструкциям Apple, что означает, что мой проект состоит из основного приложения и целевого параметра «расширение общего доступа».

Я настроил Facebook SDK внутри основного приложения, поскольку в настройках приложения есть некоторые функции входа в систему / статуса FB. Это работает хорошо в соответствии с ожиданиями: пользователи могут входить в систему и использовать некоторые общие ресурсы.

Но я также хочу, чтобы вошедший в систему пользователь был доступен для самого целевого расширения. Когда появляется мое расширение (в любом приложении), я проверяю статус входа Facebook в viewDidLoad:, и оно выводит «не авторизован»:

 if ([FBSDKAccessToken currentAccessToken]) {
    NSLog(@"logged in");
} else {
    NSLog(@"not logged in");
}
  

Тот же код выводит «logged in», если вызывается из основного приложения. Я подозреваю, что это как-то связано с тем фактом, что у целевого расширения другой идентификатор пакета, который выглядит следующим образом: .suffix и я предполагаю, что FB SDK пытается считывать идентификатор пользователя из кэша связки ключей, но, возможно, он считывает его с неправильной связки ключей из-за разных идентификаторов пакетов… Но, я думаю, могут быть и другие причины.

Есть идеи, как сохранить Facebook SDK «авторизованным» внутри расширения после того, как сам вход произошел в содержащем основном приложении?

Ответ №1:

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

Чтобы решить проблему, я помещаю кнопку входа в приложение и использую shared UserDefaults (с именем группы) для сохранения свойства :

 /*
 * Get / sets if is FB connected (because we can't use FB SDK in Extension)
 */
public var isFacebookConnected : Bool {
    get {
        // Getting Bool from Shared UserDefaults
        let defaults : NSUserDefaults = NSUserDefaults.init(suiteName: "MY_GROUP_NAME")!
        let isFBConnected : Bool? = defaults.boolForKey("IsFacebookConnected")
        if isFBConnected == nil {
            return false
        } else {
            return isFBConnected!
        }
    }
    set {
        // Setting in UserDefaults
        let defaults : NSUserDefaults = NSUserDefaults.init(suiteName: "MY_GROUP_NAME")!
        defaults.setBool(newValue, forKey: "IsFacebookConnected")
        defaults.synchronize()

    }

}
  

Доступ к этому свойству осуществляется из приложения или из расширения.

Затем в моих методах входа / выхода я добавляю :

     //FBLogin
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
    if let error = error {
        print(error.localizedDescription)
        return
    }

    if result.isCancelled
    {
        return
    }

    // Set in Shared UserDefaults if connected / not connected
    ConfigManager.sharedInstance.isFacebookConnected = true
    ...
}

func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
    // OK, keeping track
    ConfigManager.sharedInstance.isFacebookConnected = false
}
  

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

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

1. Проблема не в сохранении флага — это был тот факт, что любая попытка вызвать FB API из модуля расширения сообщала мне, что пользователь не вошел в систему (хотя я выполнил вход в систему из приложения). Вы видели что-то еще?

2. @SagiMann: привет, я не смог импортировать FBSDKLogin в расширение из-за зависимости от Bolts и того факта, что в нем использовалось sharedApplication. И, кстати, расширение не позволяет вам открывать сторонние приложения — поэтому вы не смогли войти в FB в приложении FB; вы сможете открыть свое приложение-контейнер только из своего расширения, вот почему я решил сохранить механизм входа в FB в приложении.

3. разве вам не нужен был токен доступа, который также можно использовать внутри расширения? Это именно моя проблема: вход работает из контейнера, но токен доступа не применяется после входа из расширения..

Ответ №2:

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

https://developer.apple.com/documentation/security/keychain_services/keychain_items/sharing_access_to_keychain_items_among_a_collection_of_apps