ios - 在app启动时从服务器获取初始数据

时间:2014-05-17 13:16:42

标签: ios objective-c singleton global-variables afnetworking-2

我是iOS开发新手并尝试解决以下问题。

在我的应用程序(使用REST API)中,我想在应用程序启动时向服务器发出初始请求以获取用户信息。我决定使用单独的服务类和单例方法。它向服务器发出一次请求,然后返回用户实例。

@implementation LSSharedUser

+ (LSUser *)getUser {
  // make request to api server on the first call
  // on other calls return initialized user

  static LSUser *_sharedUser = nil;

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    LSHTTPClient *api = [LSHTTPClient create];
    [api getUser:^(AFHTTPRequestOperation *operation, id user) {
        _sharedUser = [[LSUser alloc] initWithDictionary:user];
    } failure:nil];
  });

  return _sharedUser;
}

@end

我的问题是从服务器初始化全局数据的正确方法?如您所见,请求是异步的(使用AFNetworking lib),因此在请求完成之前它将返回null

这里的另一个问题是,一旦失败(例如连接错误),用户将永远为null。

2 个答案:

答案 0 :(得分:0)

像这样更新您的代码

 static LSUser *_sharedUser ;
+ (LSUser *)getUser {
  // make request to api server on the first call
  // on other calls return initialized user

if(_sharedUser){

//this will execute only at first time
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    LSHTTPClient *api = [LSHTTPClient create];
    [api getUser:^(AFHTTPRequestOperation *operation, id user) {
        _sharedUser = [[LSUser alloc] initWithDictionary:user];
        return _sharedUser;
    } failure:nil];
  });
}
//this will execute 2nd time
  return _sharedUser;
}

答案换行 - > 问题2)这里的另一个问题是,一旦失败(例如连接错误),用户将永远为null。 - >一旦_sharedUser初始化,用户将获得_sharedData。但是在共享数据未初始化之前,无论何时调用它都会返回null。

问题1)我的问题是从服务器初始化全局数据的正确方法?如您所见,请求是异步的(使用AFNetworking lib),因此在请求完成之前它将返回null。

更好的方法是实现自己的自定义委托方法。一旦获取请求或在该委托方法中执行您的工作的调用。 第一次:在获取或失败请求时执行调用委托方法。 第二次:if if block call delegate methods。

答案 1 :(得分:0)

基本方法需要异步设计。

假设你有一个异步方法:

- (void) loadUserWithCompletion:(void (^)(NSDictionary* user, NSError* error))completion;

您可以在“Continuation”(完成块)中执行您需要执行的任何操作:

[self loadUserWithCompletion:^(NSDictionary* params, NSError*error) {
    if (user) {
        User* user = [[User alloc] initWithDictionary:params];

        // better we ensure we execute the following on the main thread:
        dispatch_async(dispatch_get_main_queue(), ^{
            self.model.user = user;  
            // If we utilize KVO, observers may listen on self.model.user 
            // which now get a notification.

            // We also may to notify the user through an alert:
            ...

        });
    }
    else {
        // handler error
    }
}];

使用异步编程风格时,在让用户执行任意任务(例如,标签按钮)时需要更加谨慎。您可以考虑禁用需要用户模型的任务。或者,在用户模型尚不可用时显示警报表。

通常,当用户模型最终可用时,您会使用一些“观察者”技术来获得通知。您可以使用KVO或完成处理程序,或使用专门针对这些问题的专用第三方库(例如Promise库)。

您还应该让用户随时取消该任务。然而,这需要更详细的方法,您可以在其中执行“可取消”任务,并且您可以在其中保留对这些任务的引用,以便能够向他们发送cancel消息。