我正在为Stack Exchange API制作iOS客户端。经过漫长的争执,我终于设法实现了身份验证-这给了我一个粘贴在URL中的 token 。当 token 有效时,URL如下所示:

https://api.stackexchange.com/2.1/me/associated?key=_____MY_SECRET_KEY______&access_token=_____ACCESS_TOKEN_:)_____

当有效时,它将带我到网页中的此JSON:
{"items":[{"site_name":"Stack Overflow","site_url":"http://stackoverflow.com","user_id":1849664,"reputation":4220,"account_id":1703573,"creation_date":1353769269,"badge_counts":{"gold":8,"silver":12,"bronze":36},"last_access_date":1375455434,"answer_count":242,"question_count":26},{"site_name":"Server Fault","site_url":"http://serverfault.com","user_id":162327,"reputation":117,"account_id":1703573,"creation_date":1362072291,"badge_counts":{"gold":0,"silver":0,"bronze":9},"last_access_date":1374722580,"answer_count":0,"question_count":4},...

我使用以下代码获得正确的JSON:
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.stackexchange.com/2.1/me/associated?key=__SECRET_KEY_:)__&access_token=%@", [[NSUserDefaults standardUserDefaults] objectForKey:@"token"]]];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
if (jsonData)
{
    NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
}

但是,当我手动使 token 无效时,URL仍然看起来相同,并且浏览器中的页面显示如下:
{"error_id":403,"error_name":"access_denied","error_message":"`key` is not valid for passed `access_token`, token not found."}

但是, dataWithContentsOfURL:始终为nil 。为什么?我究竟做错了什么?

我确实收到了NSError返回:
Error Domain=NSCocoaErrorDomain Code=256 "The operation couldn’t be completed. (Cocoa error 256.)" UserInfo=0x1dd1e9f0 {NSURL=https://api.stackexchange.com/2.1/me/associated?key=key((&access_token=to‌​ken))}

最佳答案

NSCocoaErrorDomain代码= 256实际上表示“原因不明的文件系统或文件I / O相关的错误”。

为什么会出现此错误,可能是因为使用dataWithContentsOfURL:无法与该远程URL配合使用-或可能是因为包含身份验证和 token 的查询参数。因此,您会收到“怪异”错误。

通常,NSData的dataWithContentsOfURL:仅应用于访问本地文件资源。

为了解决您的问题,您应该分两步改进代码:

1)使用NSURLConnection的便捷类方法
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler
该块定义了请求完成后如何处理响应数据。通常,首先检查错误参数,然后依次检查响应的状态代码和Content-type。

2)将前者替换为您自己的实例方法(或来自第三方的实例方法),该方法具有相似的签名,但更为复杂。

方法2使您能够实现和使用以下重要功能

  • 取消
  • 在各个方面自定义身份验证
  • 将正文数据加载到文件
  • 进程同时接收大块
  • 在队列中执行多个请求,该队列控制同时连接的数量

  • 还有更多。

    方法2通常实现为NSOperation的子类,并封装了NSURLConnection对象(您需要取消连接)。

    您将找到有关如何在实现代理的异步模式下使用NSURLConnection的答案。此外,还有第三方解决方案。

    您可能还会发现官方文档也非常宝贵:
    Using NSURLConnection

    为了快速入门,您可以看一下我在Gist上的“简单GET请求”类:

    SimpleGetHTTPRequest

    此类不是基于NSOperation,但可以轻松对其进行修改。请查阅NSOperation的官方文档,了解如何制作子类。这基本上很容易,但是有一些重要的事情(KVO)应该正确。

    10-06 09:23
    查看更多