1

我创建了一个名为 User 的模型,它有一个属性“name”。

我正在向 facebook API 发出请求(使用最新的 iOS SDK),这个想法是在 facebook 返回数据时设置我的 user.name 属性。

facebook 将数据返回到startWithCompletionHandler块中,但我无法将此数据设置为我的用户对象,我只能访问startWithCompletionHandler. 当我尝试从我的模型返回的块中访问数据时NULL

当 facebook 请求返回时,如何填充我的模型/对象?

我当前的方法实现:

+ (void)requestUserData:(User *)userModel {
    if(FBSession.activeSession.isOpen) {
     [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
       if(user.name) [self setUserData:user userModel:userModel];
     }];
   }
}

 + (void)setUserData:(NSDictionary<FBGraphUser> *)user userModel:(User *)userModel {
     userModel.name = user.name;
 }

和电话:

   __block User *user = [[User alloc] init];
   [GFFacebookHelpers requestUserData:user];
   NSLog(@"user: %@", user.name); //this part prints 2013-06-06 18:03:43.731 FacebookClassTest[74172:c07] user: (null)

谢谢。

4

1 回答 1

2

Facebook 的 SDK 是异步获取的,因此您编写的完成处理程序将在您的辅助方法返回后执行。

因此,当您的方法返回您的用户对象时,逻辑上只是一个空用户(因为您已经分配/初始化了它)。

当调用完成块时,该用户对象被更新,但此时,您不再在应用程序(视图控制器)中处理它。

所以这是我的建议:要么直接从您的视图控制器中使用 Facebook SDK,或者如果您想将所有这些逻辑保留在您的助手类中,然后更改它以便您的方法不返回数据,但它需要一个块将在数据请求完成时调用,更像这样:

+ (void)requestUserDataWithCompletionHandler:(void (^)(User *user, NSError *error))handler{
    if(FBSession.activeSession.isOpen) {        
        [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
            if(!error){
                User *userData = [[User alloc] init];
                userData.name = user.name;

                dispatch_async(dispatch_get_main_queue(), ^{
                    handler(userData, nil);
                });
            }
            else{
                dispatch_async(dispatch_get_main_queue(), ^{
                    handler(nil, error);
                });
            }
        }];
    }
}

请注意,我已将处理程序块的调用包装dispatch_async()到主队列中,以确保您可以更新任何 UI。

你的视图控制器的方法现在看起来像这样:

- (void)updateStatusLabels {
    if([GFFacebookHelpers isLogged]){
        [GFFacebookHelpers requestUserDataWithCompletionHandler:^(User *user, NSError *error) {
            if(!error){
                self.fbStatus.text = user.name;
                [_loginButton setTitle:@"Logout" forState:UIControlStateNormal];
            }
        }];
    }else{
        self.fbStatus.text = @"You need to login";

        [_loginButton setTitle:@"Login" forState:UIControlStateNormal];
    }
}
于 2013-06-06T20:46:28.680 回答