Использование Facebook Graph API на iOS

Это мой первый пост на StackOverflow, но я использую его уже давно...

Моя проблема в основном проста, я хочу поделиться содержимым UITextView(mShareText) на стене пользователя, не вызывая никакого диалога. По сути, пользователь должен ввести свое сообщение в UITextView, а затем щелкнуть кнопку пользовательского интерфейса "post". Просто не правда ли?

Я скачал Facebook iOS SDK и скопировал его в свой проект. Я включил «FBConnect.h» и «Facebook.h» в заголовочный файл моего контроллера и создал переменную: Facebook* facebook; контроллер также реализует следующие делегаты: FBSessionDelegate, FBRequestDelegate.

В файле реализации моего контроллера IBAction запускается, когда пользователь нажимает кнопку UIButton "post".

- (IBAction)onShareByFBPressed:(id)sender {
NSLog(@"onShareByFBPressed");

// Facebook settings
NSMutableDictionary* params = [[NSMutableDictionary alloc] initWithCapacity:3];

[params setObject:mShareText.text forKey:@"message"];
[params setObject:@"http://www.example.com" forKey:@"link"];
[params setObject:@"https://www.example.com/myImg.jpg" forKey:@"picture"];

[facebook requestWithGraphPath:@"me/feed" 
                         andParams:params
                     andHttpMethod:@"POST"
                       andDelegate:self];
    [params release];
}

Я реализовал это на своем viewdidload:

- (void)viewDidLoad
{
    NSLog(@"viewDidLoad");
    [super viewDidLoad];

(...)

    // Test facebook
    facebook = [[Facebook alloc] initWithAppId:@"XXXXXXXXXXX" andDelegate:self];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) {
        facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
        facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
        NSLog(@"AccessToken: %@ ExpirationDate: %@", facebook.accessToken, facebook.expirationDate);
    }else{
        NSLog(@"No AccessToken or ExpirationDate");
    }
    if (![facebook isSessionValid]) {
        [facebook authorize:[NSArray arrayWithObjects:@"publish_stream", nil]];
    }
}

Вот различные методы, которые мне пришлось реализовать из-за делегатов:

// Pre 4.2 support
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    return [facebook handleOpenURL:url]; 
}

// For 4.2+ support
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    return [facebook handleOpenURL:url]; 
}

- (void)fbDidLogin {
    NSLog(@"fbDidLogin");
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"];
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"];
    [defaults synchronize];
}

- (void)fbSessionInvalidated{
    NSLog(@"fbSessionInvalidated");
}

- (void)fbDidLogout{
    NSLog(@"fbDidLogout");
}

- (void)fbDidExtendToken:(NSString*)accessToken expiresAt:(NSDate*)expiresAt{
    NSLog(@"fbDidExtendToken");
}

- (void)fbDidNotLogin:(BOOL)cancelled{
    NSLog(@"fbDidNotLogin");
}

- (void)request:(FBRequest *)request didReceiveResponse:(NSURLResponse *)response{
    NSLog(@"didReceiveResponse: %@", response);
}

- (void)request:(FBRequest *)request didFailWithError:(NSError *)error{
    NSLog(@"didFailWithError: %@", [error description]);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Share on Facebook" 
                                                message:@"An error occured" 
                                               delegate:nil 
                                      cancelButtonTitle:@"OK"
                                      otherButtonTitles:nil];
    [alert show];
    [alert release];
}

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

2012-02-17 13:02:06.401 Mixtapes[935:707] didFailWithError: Error Domain=facebookErrDomain     Code=10000 "The operation couldn’t be completed. (facebookErrDomain error 10000.)"     UserInfo=0x1f6f60 {error=<CFBasicHash 0x1f6660 [0x3ec6d630]>{type = mutable dict, count = 3,
entries =>
    2 : <CFString 0x1f64a0 [0x3ec6d630]>{contents = "type"} = <CFString 0x1f6b10     [0x3ec6d630]>{contents = "OAuthException"}
    3 : <CFString 0x1f6ab0 [0x3ec6d630]>{contents = "message"} = <CFString 0x1f6a10     [0x3ec6d630]>{contents = "An active access token must be used to query information about the     current user."}
    6 : <CFString 0x1f6e60 [0x3ec6d630]>{contents = "code"} = 2500
}
}

Может ли кто-нибудь сказать мне, что не так с моей реализацией ??

Большое спасибо.

С наилучшими пожеланиями.

РЕДАКТИРОВАТЬ: @Адиль

Спасибо за ваше предложение. Это действительно иногда работает.

Иногда я получал следующую ошибку:

didFailWithError: Error Domain=facebookErrDomain Code=10000 "The operation couldn’t be     completed. (facebookErrDomain error 10000.)" UserInfo=0xa17e0d0 {error=<CFBasicHash 0xa171e10     [0x3ec6d630]>{type = mutable dict, count = 3,
entries =>
    2 : <CFString 0xa179d10 [0x3ec6d630]>{contents = "type"} = <CFString 0xa17a280     [0x3ec6d630]>{contents = "OAuthException"}
    3 : <CFString 0x6127710 [0x3ec6d630]>{contents = "message"} = <CFString 0xa178db0     [0x3ec6d630]>{contents = "Error validating access token: Session is invalid. This could be     because the application was uninstalled after the session was created."}
    6 : <CFString 0xa17e020 [0x3ec6d630]>{contents = "code"} = 190
}
}

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


person colletjb    schedule 17.02.2012    source источник


Ответы (2)


Проблема в следующем:

Авторизованный facebook является объектом facebook AppDelegate, а не facebook вашего ViewController.

Решение:

Вместо этого выделяйте новый объект Facebook для каждого ViewController или там, где вам нужно. вы должны сделать свойство вашего приложения delegate. так:

в appDelegate.h

@property(nonatomic, retain) Facebook *facebook;

и синтезировать его в appDelegate.m, а теперь поместите инициализацию Facebook в

- (BOOL)application:(UIApplication *)ap didFinishLaunchingWithOptions:(NSDictionary *)op
{
// other code.... 

    facebook = [[Facebook alloc] initWithAppId:@"XXXXXXXXXXX" andDelegate:self];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([defaults objectForKey:@"FBAccessTokenKey"] && [defaults objectForKey:@"FBExpirationDateKey"]) {
        facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
        facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
        NSLog(@"AccessToken: %@ ExpirationDate: %@", facebook.accessToken, facebook.expirationDate);
    }else{
        NSLog(@"No AccessToken or ExpirationDate");
    }
    return true;
}

теперь, где вы хотите его использовать, напишите что-то вроде этого:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //...
    AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];     
    facebook = app.facebook;    
    if (![facebook isSessionValid]) {
        [facebook authorize:[NSArray arrayWithObjects:@"publish_stream", nil]];
    }
}
person Adil Soomro    schedule 17.02.2012
comment
да и нет, я все еще тестирую, см. мой первый пост;) (я не могу ответить на свой вопрос, потому что я новичок ^^) - person colletjb; 17.02.2012
comment
я понятия не имею, как реализовать такую вещь в Obj-C... :'( Я только что изменил это: - (void)fbSessionInvalidated{ NSLog(@fbSessionInvalidated); [self fbDidLogout]; } Но ничего не изменилось :'( - person colletjb; 17.02.2012

Попробуйте деавторизовать ваше приложение, а затем снова авторизовать его.

person Paul Rosk    schedule 17.02.2012
comment
У меня было, но так не помогло :'( - person colletjb; 17.02.2012