FBSDKLoginManager logInWithPublishPermissions всегда возвращает isCancelled=да
у меня возникли проблемы с выяснением, как войти пользователя в мое приложение. [FBSDKAccessToken currentAccessToken]
равно нулю, поэтому я звоню:
[[[FBSDKLoginManager alloc] init] logInWithPublishPermissions:@[@"publish_actions"] handler:…];
согласно прилагаемого образца проекта. Это переключается на приложение Facebook, но в сообщении говорится: "Вы уже авторизованы Название.". Я нажимаю OK, и он возвращается в приложение, но grantedPermissions
и declinedPermissions
как nil
на следствии, и isCancelled
is YES
. [FBSDKAccessToken currentAccessToken]
по-прежнему nil
.
Я не могу понять, как я должен был получить currentAccessToken
для заполнения. Мне кажется, это призыв к logInWithPublishPermissions
должен делать это, но это не так.
11 ответов
вы должны попробовать добавить в свой AppDelegate didFinishLaunchingWithOptions:
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
Это бы получить u [FBSDKAccessToken currentAccessToken]
когда пользователь вошел в систему.
и
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
Если этот метод отсутствует в AppDelegate, то он приводит к отмене состояния.
см.:https://developers.facebook.com/docs/ios/getting-started#startcoding
Это может произойти, когда ваше приложение Facebook не имеет разрешения "publish_actions" или вы не используете тестового пользователя.
на Facebook перейдите к управлению приложением, затем убедитесь, что пользователь Facebook, которого вы используете, определен в разделе "роли" как администратор или тестер.
Если это не тестовый пользователь или администратор - Facebook потребует разрешения" publish_actions " для просмотра и утверждения, прежде чем разрешить вашему приложению использовать его, до тех пор вы получите результат" isCancelled=YES".
после тестирования вашего приложения с этим разрешением можно отправить это разрешение на обзор, вам нужно будет загрузить двоичный файл, который демонстрирует использование этого разрешения с точными сведениями о том, как его использовать. После того, как он будет одобрен, вы сможете использовать его с не тестовыми пользователями Facebook.
так как FBSDKLoginKit 4.6.0, то logInWithReadPermissions
и logInWithPublishPermissions
методы FBSDKLoginManager, похоже, имеют дополнительные fromViewController
аргумент и использовать его для представления модалов.
Я звонил logInWithPublishPermissions
внутри обратного вызова logInWithReadPermissions
, который в этот момент модальный еще не полностью уволен. (Я знаю, что спрашивать разрешения, когда оно не нужно, - плохая практика, но в моем случае, кажется, это правильное место.) Это приводит к сбою с isCancelled
равно да. Я добавил некоторые задержки и ждать, пока модальный будет полностью отклонен Исправлена проблема.
У меня была та же проблема, когда я приземлился здесь, оказывается, я использовал только устаревший метод openURL приложения, потому что я тоже использовал Google sign in. Для поддержки iOS 8 и до того, как вам придется реализовать как текущий, так и устаревший метод:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String!, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) || FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication, annotation: annotation) || FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
}
устаревшие второй.
Примечание: метод FBSDK добавляется после google с оператором or"||", но порядок не имеет значения, и если вы хотите использовать только метод facebook, просто удалите метод и оператор or.
примечание 2: поскольку swift 3 все еще стабилизирует имя метода, я предлагаю вам всегда использовать автозаполнение из XCode при переопределении и реализации метода делегата.
надеюсь, это поможет o/
этот метод работает в iOS 9
// Facebook Login Completion delegate
- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error
{
if (result){
NSLog(@"%@",result);
NSLog(@"%@",result.grantedPermissions);
[self getFacebookData:result];
}
}
- (void)getFacebookData:(FBSDKLoginManagerLoginResult *)result{
if (![result.grantedPermissions containsObject:@"email"])
{
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
login.loginBehavior = FBSDKLoginBehaviorWeb;
[login logInWithReadPermissions:@[@"email"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
{
if (error)
{
// Process error
}
else if (result.isCancelled)
{
// Handle cancellations
}
else
{
if ([result.grantedPermissions containsObject:@"email"])
{
NSLog(@"result is:%@",result);
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"first_name, last_name, email, id"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(@"fetched user:%@", result);
[self registerWithFacebook:result];
}else{
NSLog(@"%@",error);
}
}];
}
}
}
}];
}else{
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"first_name, last_name, email, id"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(@"fetched user:%@", result);
[self registerWithFacebook:result];
}else{
NSLog(@"%@",error);
}
}];
}
}
}
Примечание используйте FBSDKLoginBehaviorWeb вместо FBSDKLoginBehaviorBrowser. Это, безусловно, работает
кроме того, убедитесь, что вы не призываете к FBSDKAccessToken.currentAccessToken
внутри didFinishLaunchingWithOptions
метод. Настройка в didFinishLaunchingWithOptions
необходимо завершить, чтобы маркер мог инициализироваться, прежде чем вы попытаетесь войти в Facebook.
FBSDKLoginManagerLoginResult.isCancelled
неожиданно YES
:
SDK сообщит об отмене, если пользователь явно нажимает кнопку отмены в диалогах входа в систему или если они вручную переключаются на приложение (известное как неявная отмена). Вы должны убедиться, что вы не инициируете поток входа в систему как часть вашего приложения delegate
жизненный цикл (например, запуск входа в систему внутри application:openURL:sourceApplication:annotation:
) как будет внешне неявная отмена. Если необходимо, отправьте инициацию входа позже в main очередь, чтобы жизненный цикл делегата приложения завершился первым.
Я тоже столкнулась с той же проблемой и я потратил почти 2 часа, чтобы решить вопрос. То, что я сделал, это
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
**[login logOut];** // adding this single line fixed my issue
[login logInWithReadPermissions: @[@"public_profile"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
NSLog(@"Process error");
} else if (result.isCancelled) {
NSLog(@"Cancelled");
} else {
NSLog(@"Logged in");
[self GetData];
}
}] // I called this logout function
и проблема была устранена
я использовал как Google, так и Facebook login, поэтому мне пришлось реализовать мой метод openURL, как это, iOS 9+
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([[url absoluteString] containsString:@"YOURFBID"]) {
return [[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options];
} else {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
return NO;
}
/ / вы можете выполнять любые дальнейшие операции с помощью маркера доступа
- (void)GetData {
if ([FBSDKAccessToken currentAccessToken]) {
NSDictionary *AccessToken = [FBSDKAccessToken currentAccessToken];
[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"id, name, first_name, picture.type(large) ,last_name"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
//NSLog(@"fetched user:%@", result);
//NSDictionary *Result = result;
NSDictionary *params = [NSMutableDictionary dictionaryWithObject:[AccessToken tokenString] forKey:@"access_token"];
} else {
[self showAlertController:@"Error" message:error.localizedDescription];
}
}];
} }
(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
options:options];
}
// **Still need this for iOS8**
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(nullable NSString *)sourceApplication
annotation:(nonnull id)annotation
{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
1.уже добавил
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
2.уже добавил
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(nullable NSString *)sourceApplication
annotation:(nonnull id)annotation
{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
3.
напишите это заявление [FBSDKProfile enableUpdatesOnAccessTokenChange:YES];
до
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
4.вызовите метод logInWithReadPermissions в dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t) (1 * NSEC_PER_SEC)), dispatch_get_main_queue (), ^{}
назовите это methord,
FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
[loginManager logInWithReadPermissions:@[@"user_friends"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
code
}];