2012-08-09 34 views
11

Tôi đang cố gắng tích hợp Facebook SDK mới cho iOS và gặp sự cố khi hiểu một số khái niệm.Mở FBSession trong các lần ra mắt liên tiếp (FB SDK cho SDK 3.0)

  1. tôi xác thực bằng [FBSession sessionOpenWithPermissions:...] thoại auth đi lên và tôi trả lại ứng dụng. Xác thực thành công.

  2. Sau đó tắt ứng dụng, khởi chạy lại. [[FBSession activeSession] accessToken] trả về thành công mã thông báo đã lưu trước đó.

  3. Tuy nhiên, cùng lúc, [[FBSession activeSession] isOpen] trả về NO. (Điều này có nghĩa là phiên không sẵn sàng để sử dụng.)

  4. Ngoài ra, [[FBSession activeSession] state]FBSessionStateCreatedTokenLoaded tại thời điểm này. Hướng dẫn here sử dụng cuộc gọi isOpen để xác minh phiên đang hoạt động được tải và mở bằng mã thông báo.

Vậy chúng ta gọi gì để mở phiên nạp mã thông báo mà không chuyển hướng người dùng đến hộp thoại xác thực?

Gợi ý:

Trong FBSessionState enum, cho FBSessionStateOpen nó nói:

mở chỉ sử dụng trạng thái phiên đã đăng nhập hoặc một thẻ lưu trữ có sẵn.

Tuy nhiên FBSessionStateCreatedTokenLoaded được mô tả như sau:

Một trong hai trạng thái phiên ban đầu chỉ ra rằng một thẻ lưu trữ đã được nạp; khi một phiên ở trạng thái này, lệnh gọi để mở * sẽ dẫn đến phiên mở, không có UX hoặc chuyển đổi ứng dụng

Bạn có thể giúp tôi tìm hiểu sự chuyển tiếp phiên này không?

+0

Bạn cần phải mở lại phiên của bạn trên mỗi mắt ứng dụng. –

+2

Làm thế nào để làm điều đó? Tôi đang thiếu phần đó. sẽ '[FBSession sessionOpenWithPermissions: ...]' làm các trick mà không hiển thị hộp thoại auth mỗi lần? –

+2

điều này: '+ (BOOL) openActiveSessionWithAllowLoginUI: (BOOL) allowLoginUI' và google FBSession - nghĩa đen là lần truy cập đầu tiên. –

Trả lời

31

Tôi bao gồm lớp tiện ích Facebook tôi đã viết giúp hiểu trạng thái đăng nhập, vì tôi hiển thị thông báo "đăng nhập"/"chưa đăng nhập" cho người dùng trong Giao diện người dùng cài đặt của riêng mình, ngoài việc sử dụng thành phần 'FBLoginView' thực tế khi đến lúc cho phép người dùng chuyển đổi trạng thái ủy quyền.

Mã bên dưới cũng có sẵn qua số gist này.

Tôi có thể không giải thích tất cả các loại FBSessionState một cách chính xác trong báo cáo chuyển đổi của mình, nhưng cho đến nay, nó đã phục vụ tốt cho tôi trong các trường hợp tôi đã thử nghiệm (tôi vừa mới kết hợp).

Điều quan trọng cần lưu ý là đôi khi bạn có mã thông báo ủy quyền được lưu trong bộ nhớ cache mà bạn không thể sử dụng ngay lập tức, nhưng nếu thực hiện cuộc gọi trên Facebook open, bạn có thể làm cho nó trở thành có thể tái sử dụng (được làm mới). Cuộc gọi mở này hoạt động sau hậu trường, không kích hoạt bất kỳ chuyển đổi cửa sổ/ứng dụng OAuth UI/jarring nào (nếu bạn có mã thông báo được lưu trong bộ nhớ cache).

Xem nhận xét của tôi theo phương pháp isLoggedInAfterOpenAttempt. Lưu ý cách tôi kiểm tra trạng thái là FBSessionStateCreatedTokenLoaded và chỉ sau đó, thực hiện cuộc gọi đến

-openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error).

mẩu tin khác về lớp này:

  • tôi có một tài sản vào đây để bộ nhớ cache đăng nhập của người dùng, các loại phù hợp với giao thức FBGraphUser. Tuy nhiên, nó không được sử dụng trong bất kỳ phương thức đăng nhập nào được minh họa ở đây.
  • Mã mẫu Facebook SDK 3.0 cho iOS đề xuất xây dựng lớp học của riêng bạn để giữ và quản lý các loại hoạt động này, nếu bạn có bất cứ điều gì nhiều hơn một ứng dụng tầm thường. Lớp này của tôi dưới đây là sự khởi đầu của ý tưởng đó cho ứng dụng của tôi.
  • Bạn có thể thay thế macro 'log4Info' và 'log4Debug' bằng NSLog để làm việc này.
 
#import "UWFacebookService.h" 

@implementation UWFacebookService 

// Static 
static const int ddLogLevel = LOG_LEVEL_DEBUG; 

// Strong 
@synthesize facebookGraphUser = _facebookGraphUser; 


#pragma mark - Inquiries 

- (BOOL)isSessionStateEffectivelyLoggedIn:(FBSessionState)state { 
    BOOL effectivelyLoggedIn; 

    switch (state) { 
     case FBSessionStateOpen: 
      log4Info(@"Facebook session state: FBSessionStateOpen"); 
      effectivelyLoggedIn = YES; 
      break; 
     case FBSessionStateCreatedTokenLoaded: 
      log4Info(@"Facebook session state: FBSessionStateCreatedTokenLoaded"); 
      effectivelyLoggedIn = YES; 
      break; 
     case FBSessionStateOpenTokenExtended: 
      log4Info(@"Facebook session state: FBSessionStateOpenTokenExtended"); 
      effectivelyLoggedIn = YES; 
      break; 
     default: 
      log4Info(@"Facebook session state: not of one of the open or openable types."); 
      effectivelyLoggedIn = NO; 
      break; 
    } 

    return effectivelyLoggedIn; 
} 

/** 
* Determines if the Facebook session has an authorized state. It might still need to be opened if it is a cached 
* token, but the purpose of this call is to determine if the user is authorized at least that they will not be 
* explicitly asked anything. 
*/ 
- (BOOL)isLoggedIn { 
    FBSession *activeSession = [FBSession activeSession]; 
    FBSessionState state = activeSession.state; 
    BOOL isLoggedIn = activeSession && [self isSessionStateEffectivelyLoggedIn:state]; 

    log4Info(@"Facebook active session state: %d; logged in conclusion: %@", state, (isLoggedIn ? @"YES" : @"NO")); 

    return isLoggedIn; 
} 


/** 
* Attempts to silently open the Facebook session if we have a valid token loaded (that perhaps needs a behind the scenes refresh). 
* After that attempt, we defer to the basic concept of the session being in one of the valid authorized states. 
*/ 
- (BOOL)isLoggedInAfterOpenAttempt { 
    log4Debug(@"FBSession.activeSession: %@", FBSession.activeSession); 

    // If we don't have a cached token, a call to open here would cause UX for login to 
    // occur; we don't want that to happen unless the user clicks the login button over in Settings, and so 
    // we check here to make sure we have a token before calling open 
    if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) { 
     log4Info(@"We have a cached token, so we're going to re-establish the login for the user."); 
     // Even though we had a cached token, we need to login to make the session usable: 
     [FBSession.activeSession openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) { 
      log4Info(@"Finished opening login session, with state: %d", status); 
     }]; 
    } 
    else { 
     log4Info(@"Active session wasn't in state 'FBSessionStateCreatedTokenLoaded'. It has state: %d", FBSession.activeSession.state); 
    } 

    return [self isLoggedIn]; 
} 

@end 

2

Hãy thử sau mẫu mã:

///////////////////////////////// 

-(void)CallBackOpenURLFromDelegate:(NSURL *)url 
{ 
    [FBSession.activeSession handleOpenURL:url]; 
} 

-(id)init 
{ 
    self = [super init]; 
    FBSessionTokenCachingStrategy* pToken = [[[FBSessionTokenCachingStrategy alloc]initWithUserDefaultTokenInformationKeyName:@"STokenInfoX"]autorelease]; 
    FBSession.activeSession = [[FBSession alloc] initWithAppID:FACEBOOK_AppId 
                permissions:[NSArray arrayWithObject:@"status_update"] 
               urlSchemeSuffix:@"" 
              tokenCacheStrategy: pToken]; 
    return self; 
} 


-(void)dealloc 
{ 
    [FBSession.activeSession close]; 
    [super dealloc]; 
} 

-(void) UploadImpl:(NSString*)strImagePath 
{ 
    FBRequest *photoUploadRequest = [FBRequest requestForUploadPhoto: [UIImage imageWithContentsOfFile:strImagePath ]]; 
    [photoUploadRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) 
    { 
     NSLog(@"%@",[error description]); 
     //self.delegate 
    }]; 
} 
5

này có nghĩa là khi bạn có một thẻ lưu (cache) hoặc đã có sẵn, thư viện Facebook iOS vẫn đòi hỏi bạn phải sử dụng phương pháp mở cửa cho reinitialise một phiên làm việc.

Làm như vậy nếu nó có thể sử dụng lại mã thông báo hiện có (và đây là trường hợp của bạn), và trong trường hợp này UX (trải nghiệm người dùng - tức là chuyển đổi ứng dụng hoặc popup đăng nhập Facebook) sẽ không được kích hoạt.

Ấn tượng của người dùng là anh ấy chưa bao giờ đăng xuất, nhưng trong ứng dụng những gì đang xảy ra là bạn đang liên hệ với Facebook để mở lại một phiên.

Lý do này được thiết kế như vậy là do trong trường hợp mã thông báo có sẵn nhưng đã hết hạn, thư viện Facebook sẽ cho bạn biết - "mã thông báo lỗi đã hết hạn, hãy xem bản thân bạn đã đăng xuất trừ khi bạn nhận được mã thông báo mới ngay bây giờ".

Hy vọng điều đó sẽ hữu ích.

1

Đây có thể là một chủ đề cũ, nhưng bây giờ một ngày tất cả các bạn phải làm là gọi handleDidBecomeActive trong đối tượng FBSession của bạn từ bên trong (void) applicationDidBecomeActive: (UIApplication *) ứng dụng trong đại biểu ứng dụng của bạn.

Ví dụ:

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    [[[MLSocialNetworksManager sharedManager] MLFacebook] handleDidBecomeActive]; 
} 

đâu MLFacebook là đối tượng FBSession tôi.

+0

Tại sao bạn tạo một lớp khác gọi là MLFacebook? Phương thức 'handleDidBecomeActive' có phải là phương thức' FBSession' không? –

+0

Nó đóng gói logic facebook của tôi. Không có nghĩa là nó được yêu cầu. –

0

chỉ cần gọi theo quan điểm điều khiển init của bạn

self.FBloginView = [[FBLoginView alloc] init]; 
Các vấn đề liên quan