Получение базовой информации (id, first_name) из Facebook с помощью Social Framework — исходный код и скриншоты прилагаются

Для того, что позже станет игрой в слова, я пытаюсь получить очень основную информацию об игроке, используя социальную структуру:

  • id
  • Имя
  • Пол
  • расположение

(т. е. ничего чувствительного, как email, и я не использую Facebook iOS SDK).

Итак, в Xcode 5.0.2 я создаю пустое приложение с одним представлением для iPhone и добавляю Social.framework на вкладку Фазы сборки.

Затем я добавляю следующий код в ViewController.m:

#import "ViewController.h"
#import <Social/Social.h>
#import <Accounts/Accounts.h>

#define FB_APP_ID @"432298283565593"
//#define FB_APP_ID @"262571703638"

@interface ViewController ()
@property (strong, nonatomic) ACAccountStore *accountStore;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"Facebook is available: %d", [SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]);

    [self getMyDetails];
}

- (void) getMyDetails {
    if (!_accountStore) {
        _accountStore = [[ACAccountStore alloc] init];
    }

    ACAccountType *facebookAccountType = [_accountStore
                                        accountTypeWithAccountTypeIdentifier: ACAccountTypeIdentifierFacebook];
    NSDictionary *options = @{
                              ACFacebookAppIdKey: FB_APP_ID,
                              ACFacebookPermissionsKey: @[@"basic_info"]};

    [_accountStore requestAccessToAccountsWithType:facebookAccountType
                                           options:options
                                        completion:^(BOOL granted, NSError *error)
    {
        if (granted) {
            NSLog(@"Basic access granted");
        } else {
            NSLog(@"Basic access denied %@", error);
        }
    }];
}

@end

И создайте новое приложение Facebook, для которого я укажу de.afarber.MyFacebook в качестве iOS Идентификатор пакета:

введите здесь описание изображения

Наконец, в Apple iTunes Connect я создаю новый идентификатор приложения, а затем новое приложение (с фиктивным значком и даже двумя прикрепленными снимками экрана iPhone):

введите здесь описание изображения

введите здесь описание изображения

Моя вкладка Xcode Информация и остальная часть исходного кода не изменились:

введите здесь описание изображения

ОБНОВЛЕНИЕ 2:

Я обновил исходный код в соответствии с полезными комментариями, спасибо.

Кроме того, у меня есть еще одна игра на Facebook, которая хорошо работает (уже 1-2 года) в течение Настольные и мобильные приложения Adobe AIR (но теперь я пытаюсь изучить нативное программирование для iOS), и я безуспешно пытался использовать его идентификатор 262571703638.

И я добавил FacebookAppID к MyFacebook-Info.plist по предложению Mohit10 (мне кажется, что это нужно только для Facebook SDK, пока я пытаюсь использовать Social Framework - но это не помешает...)

Теперь я получаю вывод отладчика:

2013-12-31 11:08:07.584 MyFacebook[3009:70b] Facebook is available: 1
2013-12-31 11:08:07.964 MyFacebook[3009:3903] Basic access granted

Мне просто нужно выяснить, как теперь получить идентификатор, имя, пол, местоположение (и действительно ли для этого нужно basic_info)...


person Alexander Farber    schedule 29.12.2013    source источник
comment
Не уверен, что это полностью связано с ошибкой, которую вы видите, но запрашиваемые вами разрешения (идентификатор, имя, пол, местоположение) на самом деле не являются действительными разрешениями FB. Список действующих разрешений см. на странице developers.facebook.com/docs/reference/login   -  person Ming Li    schedule 30.12.2013
comment
Я взял те же строки, что и в версии PHP (другого моего приложения), поэтому мне интересно, какие строки вы имеете в виду?   -  person Alexander Farber    schedule 31.12.2013
comment
Я не уверен, что делает ваше другое приложение, все, что я знаю, это то, что id и first_name не являются допустимыми разрешениями facebook и не должны передаваться в ACFacebookPermissionsKey. Такие вещи, как basic_info, user_birthday, являются разрешениями. Параметры, которые вы устанавливаете, выглядят как поля, которые вам нужны, когда вы фактически делаете запрос пользователя (например, &fields=id,gender,first_name,location).   -  person Ming Li    schedule 31.12.2013
comment
Вы правы, и, возможно, мне следует просто попробовать SLRequest без запроса разрешений...   -  person Alexander Farber    schedule 31.12.2013


Ответы (4)


В вашем коде есть несколько ошибок.

  • ACAccountStore *accountStore выходит за рамки, это должна быть переменная экземпляра.
  • Вам не нужен ACFacebookAudienceKey, это для публикации.
  • Вам не нужен ACFacebookPermissionsKey, так как вам нужны свойства доступно по умолчанию

С этими исправлениями ваш код по-прежнему не работает для меня, хотя он работает для моего идентификатора приложения. Я получаю следующую ошибку:

"The Facebook server could not fulfill this access request: Invalid application 432298283565593" UserInfo=0x1d5ab670 {NSLocalizedDescription=The Facebook server could not fulfill this access request: Invalid application 432298283565593}

Похоже, что-то не так с конфигурацией Facebook вашего приложения.

Единственная разница, которую я вижу, заключается в том, что мое приложение находится в песочнице, и я вошел в систему, используя свою учетную запись разработчика. Удачи.

person Rhythmic Fistman    schedule 29.12.2013
comment
Спасибо, я обновил исходный код, как (я думаю) вы предлагаете... а также попробовал другое (уже работающее) приложение Facebook Id, но ошибка все та же: Basic access denied (null). Я установлю награду 500 завтра на мой вопрос - person Alexander Farber; 30.12.2013
comment
Обновили ли вы BundleID, чтобы он соответствовал рабочему идентификатору приложения Facebook? Удаление приложения и выполнение чистой перестройки перед этим тоже не повредит, так как Xcode может запутаться. - person Rhythmic Fistman; 31.12.2013

Благодаря полезным комментариям (спасибо) я наконец смог получить некоторую информацию с помощью следующего кода:

#import "ViewController.h"
#import <Social/Social.h>
#import <Accounts/Accounts.h>

#define FB_APP_ID @"432298283565593"
//#define FB_APP_ID @"262571703638"

@interface ViewController ()
@property (strong, nonatomic) ACAccount *facebookAccount;
@property (strong, nonatomic) ACAccountType *facebookAccountType;
@property (strong, nonatomic) ACAccountStore *accountStore;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    if (NO == [SLComposeViewController isAvailableForServiceType: SLServiceTypeFacebook]) {
        [self showAlert:@"There are no Facebook accounts configured. Please add or create a Facebook account in Settings."];
        return;
    }

    [self getMyDetails];
}

- (void) getMyDetails {
    if (! _accountStore) {
        _accountStore = [[ACAccountStore alloc] init];
    }

    if (! _facebookAccountType) {
        _facebookAccountType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
    }

    NSDictionary *options = @{ ACFacebookAppIdKey: FB_APP_ID };

    [_accountStore requestAccessToAccountsWithType: _facebookAccountType
                                           options: options
                                        completion: ^(BOOL granted, NSError *error) {
        if (granted) {
            NSArray *accounts = [_accountStore accountsWithAccountType:_facebookAccountType];
            _facebookAccount = [accounts lastObject];

            NSURL *url = [NSURL URLWithString:@"https://graph.facebook.com/me"];

            SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
                                                    requestMethod:SLRequestMethodGET
                                                              URL:url
                                                       parameters:nil];
            request.account = _facebookAccount;

            [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
                NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData
                                                                                   options:NSJSONReadingMutableContainers
                                                                                     error:nil];
                NSLog(@"id: %@", responseDictionary[@"id"]);
                NSLog(@"first_name: %@", responseDictionary[@"first_name"]);
                NSLog(@"last_name: %@", responseDictionary[@"last_name"]);
                NSLog(@"gender: %@", responseDictionary[@"gender"]);
                NSLog(@"city: %@", responseDictionary[@"location"][@"name"]);
            }];
        } else {
            [self showAlert:@"Facebook access for this app has been denied. Please edit Facebook permissions in Settings."];
        }
    }];
}

- (void) showAlert:(NSString*) msg {
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        UIAlertView *alertView = [[UIAlertView alloc]
                                  initWithTitle:@"WARNING"
                                  message:msg
                                  delegate:nil
                                  cancelButtonTitle:@"OK"
                                  otherButtonTitles:nil];
        [alertView show];
    });
}

@end

Это печатает мои данные:

id: 597287941
first_name: Alexander
last_name: Farber
gender: male
city: Bochum, Germany

Если у вас есть какие-либо предложения по улучшению, пожалуйста.

person Alexander Farber    schedule 31.12.2013

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

person procrastinator    schedule 30.12.2013
comment
Спасибо, но это не FacebookAppID для Facebook iOS SDK (для FBSession)? Пока я пытаюсь использовать Apple Social Framework... - person Alexander Farber; 30.12.2013

Ответ прост

в viewDidLoad() используйте:

accountStore= [[ACAccountStore alloc]init];
facebookAccountType= [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

NSDictionary *options= @{
ACFacebookAudienceKey: ACFacebookAudienceEveryone,
ACFacebookAppIdKey: @"<YOUR FACEBOOK APP ID>",
ACFacebookPermissionsKey: @[@"public_profile"]

                          };


[accountStore requestAccessToAccountsWithType:facebookAccountType options:options completion:^(BOOL granted, NSError *error) {

    if (granted) {
        NSLog(@"Permission has been granted to the app");
        NSArray *accounts= [accountStore accountsWithAccountType:facebookAccountType];
        facebookAccount= [accounts firstObject];
        [self performSelectorOnMainThread:@selector(facebookProfile) withObject:nil waitUntilDone:NO];

    } else {
        NSLog(@"Permission denied to the app");
    }
}];

/////И функция -(void)facebookProfile{

NSURL *url = [NSURL URLWithString:@"https://graph.facebook.com/me"];

//////Обратите внимание, что необходимые параметры добавляются в виде словаря ///Полный список см. ниже ////https://developers.facebook.com/docs/graph-api/reference/пользователь

NSDictionary *param=[NSDictionary dictionaryWithObjectsAndKeys:@"picture,id,name",@"fields", nil];

SLRequest *profileInfoRequest= [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:url parameters:param];
profileInfoRequest.account= facebookAccount;


[profileInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
    NSLog(@"Facebook status code is : %ld", (long)[urlResponse statusCode]);

    if ([urlResponse statusCode]==200) {

        NSDictionary *dictionaryData= [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];



    } else {

    }
}];


}
person Rahul Thankachan    schedule 11.07.2015