【问题标题】:Design simple ios application using NSURLSession使用 NSURLSession 设计简单的 ios 应用程序
【发布时间】:2014-06-01 08:27:21
【问题描述】:

我正在为 iOS 7.1 编写我的第一个应用程序 Objective-c。我可能根本不明白我为什么会出现这个问题。

应用程序非常简单:客户端使用 web api 与外部服务进行通信。要发送 http 请求,我使用 NSURLSession。 我有一个简单的架构。

THETALETestViewController - 这个视图控制器。此类使用 THETALEAPI.h THETALEAPI——是web api的实现。我已经在一个单独的类中突出显示,每个外部 API 方法都已在一个地方实现。下面是每个方法的查询形成。此类使用 THETALEHttpHandler.h。 THETALEHttpHandler - 这个类直接负责发送http-request和接收http-response。

这是来自 THETALEHttpHandler.m 的代码,用于发送 POST - 查询。

-(void) sendPostToURL:(NSURL *)url withParams: (NSString *) inParams competion:(void     (^) (NSData *data)) completion
{
    NSLog(@"sendPostToURL");

    // _csrftoken a token in cookie
    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:@"csrftoken" forKey:NSHTTPCookieName];
    [cookieProperties setObject:_csrftoken forKey:NSHTTPCookieValue];

    [cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];

    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    [_httpCookieStorage setCookie:cookie];

    [_sessionConfig setHTTPCookieStorage:_httpCookieStorage];


    // tried and so
    // //   NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil //delegateQueue: [NSOperationQueue mainQueue]];   
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:_sessionConfig];


    NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];

    // _csrftoken a token in the parameter
    NSString *params = [@[inParams, _csrftoken] componentsJoinedByString:@""];

    [urlRequest setHTTPMethod:@"POST"];
    [urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];

    NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
                                                   completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                    NSLog(@"Got response %@ with error %@.\n", response, error);
                                                       if(error == nil)
                                                       {
                                                           NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
                                                           NSLog(@"Data = %@",text);
                                                       }
                                                   completion(data);
                                                   }];
    [dataTask resume];

}

所以,块完成不是在主线程中运行的,并且是异步的,所以当一个请求被发送并且有一个接收和处理响应时——主线程继续运行。原则上,它是清晰和合乎逻辑的,但我想分别使用这种方法“登录”,通过单击“登录”我必须在成功请求和响应后去处理用户应该看到答案。 iOS 有什么能力实现这样的行为,让主线程等待异步块的完成并显示相应的信息?或者也许它不值得等待,它只是需要通知?

当然,除非不创建单独的类,并且在 viewController 中做所有事情,那么,假设会出现委托,但我想在其应用程序中做一些模块化。

也许我设计的系统有误,那么您可以解释或展示一个通常如何完成的示例吗?

我认为这个要求相当平庸,答案就在附近,请解释一下,提前谢谢!

【问题讨论】:

  • 对不起。翻译了代码中的cmets。

标签: ios objective-c ios7.1 nsurlsession


【解决方案1】:

您可以使用AFNetworking 进行API 调用。Tutorial 详细解释如何正确使用它。您也可以使用NSNotificationCenter 在调用成功/失败时通知视图控制器

【讨论】:

  • 我考虑过 Notification 和 delegirovanii。到那里我需要做内部块通知来查看控制器?
  • 我不确定我是否理解您的问题
  • 我对实施很感兴趣。在指定的架构中,您将如何进行通知?
  • api 调用完成时发布通知(应该在块内):[[NSNotificationCenter defaultCenter] postNotificationName:@"some name to identify the notification" object: nil userInfo:nil];并始终删除观察者: [[NSNotificationCenter defaultCenter] removeObserver:self name:@"same notification name" object:nil];注册视图控制器以“监听”通知:[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(methodToHandleTheNotification) name:@"same notification name" object:nil];
  • 谢谢!它很有用。我会试试这个方法。请告诉我这个应用程序的架构是否正确?
【解决方案2】:

首先,您可以使用dispatch_sync 在主线程上执行一个块。但这并不是真正的问题。您试图在一个代码块中做太多事情。

您的流程需要如下所示:

  1. 您是否记录了用户名/密码?
  2. 如果没有,请索要一个
  3. 运行您的网络请求
  4. 错误处理将包括查找无效凭据,在这种情况下,请求将被取消,您的代码将跳转到第 2 步。

【讨论】:

  • 为什么你认为我要一个块做太多?我只想接受回复并在 THETALEAPI 中进一步给出。我尝试使用'code' dispatch_sync 'code',但程序没有等待块执行。我的问题实际上是如何实现您在列表中描述的内容。
  • @njc 您的代码下方的文本段建议您希望用户在网络请求期间登录,即网络请求应该等到信息有在继续之前从用户那里获得。这不是它需要的工作方式。您需要获取凭据,然后执行请求。
  • 可能是我解释错了。已经有凭据,用户输入它们。现在我想等待答案,并根据答案向用户界面显示信息。
  • 所以问题只是完成块没有在主线程上运行?
  • 我的问题是我不知道如何告诉我处理响应的接口,但是我在上面提出了建议。我将使用或委托或通知。对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多