将 NSData 从 NSURLSession 转换为 JSON

Posted

技术标签:

【中文标题】将 NSData 从 NSURLSession 转换为 JSON【英文标题】:Convert NSData from NSURLSession to JSON 【发布时间】:2016-10-25 13:38:35 【问题描述】:

我知道有许多类似的 SO 问题与我的标题相似。我已经检查了它们,但仍然遇到这个问题。

我正在尝试访问一个 API,该 API 返回一个应该/可以被格式化为 JSON 的字符串。

要检索此字符串并将字符串转换为 JSON,我正在使用(未成功)此代码:

NSError *error;

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request
                                            completionHandler:
                                  ^(NSData *data, NSURLResponse *response, NSError *error) 

                                NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

                                      NSLog(@"Response: %@",responseString);


                                      NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding];

                                      id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];

                                      NSLog(@"%@",[json objectForKey:@"ID"]);


                                      NSLog(@"Json: %@",json);

                                  ];



    [task resume];

NSLog(@"Response:...) 返回一个字符串,当我将其输入本网站时:http://jsonviewer.stack.hu 确认该字符串是有效的 JSON。

两个应该返回 JSON 值的 NSLog 返回 null。

我尝试了什么:

NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData 选项:NSJSONReadingMutableContainers 错误:&error];

NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data 选项:NSJSONReadingMutableContainers 错误:&error];

我现在也试过了:

 NSURLRequest *request = [NSURLRequest requestWithURL:url];

    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request
                                            completionHandler:
                                  ^(NSData *data, NSURLResponse *response, NSError *error) 


                                      NSMutableDictionary *jsonObject;

                                      NSError *err = nil;
                                      @try
                                      
                                          jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&err];
                                      
                                      @catch (NSException *exception)
                                      
                                          NSLog( @"Exception caught %@",exception);
                                      

                                      NSDictionary *info = jsonObject;

                                      NSLog(@"Json: %@",info);

                                  ];



    [task resume];

我在这里做错了什么?如何获得 NSDictionary (JSON) 结果。

【问题讨论】:

你在 responseString 中得到了什么? 你的 JSON 真的是***的 NSDictionary 吗?使用error 参数怎么样? NSData 转换为NSString 并直接转换回NSData 非常愚蠢。根据您的代码datajsonData 是相同的 @vadian 知道这一点,但想看看字符串的输出是什么。 但无论如何,将其转换回来的额外步骤是多余的。您确定 JSON 的根对象是字典吗?并处理错误。 【参考方案1】:

您的主要问题: 如果你阅读+JSONObjectWithData:options:error:的错误参数,它会告诉你:

Error Domain=NSCocoaErrorDomain Code=3840 "JSON 文本没有开始 带有数组或对象以及允许未设置片段的选项。” UserInfo=NSDebugDescription=JSON 文本不是以数组开头或 允许未设置片段的对象和选项。

如上所述,您的答案如下所示:aStringKey = realAndValidJSONSurroundedByCurvyBrackets,这不是有效的 JSON。 在聊天中讨论后,您与服务器端取得了联系,并且提供适当的 JSON 应该是他们的责任。在他们修复它之前,为了继续工作,你可以这样做:

NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
str = [str stringByReplacingCharactersInRange:NSMakeRange(0, [@"aStringKey = " length] ) withString:@""];
NSError *jsonError = nil;
NSDictionary *jsonFinal = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&jsonError];

if (jsonError)

    NSLog(@"Error: %@", jsonError);

但请记住,这是“快速破解/修复”,不应保留在最终版本中并尽快删除。

你试过了:

NSError *err = nil;
@try

    jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&err];

@catch (NSException *exception)

    NSLog( @"Exception caught %@",exception);

@try@catch(NSException *exception) 不应该工作,因为 +JSONObjectWithData:options:error: 在你的情况下不应该抛出 NSException,所以理论上,没有什么可以捕捉到的,但它可能仍然不起作用(因为有一个 @ 987654328@)。 当然,由于data 参数应该是非空的,如果它是nil,你会得到一个NSException(它会记录Exception caught data parameter is nil),但这是另一个问题,并不能保证你解析成功如果没有异常,则错误(因为在我们的例子中是无效的 JSON)。

【讨论】:

【参考方案2】:

试试这个:

  NSMutableDictionary *jsonObject;

    NSError *err = nil;
    @try
    
        jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&err];
    
    @catch (NSException *exception)
    
        NSLog( @"Exception caught %@",exception);
    

    NSDictionary *info = jsonObject;

【讨论】:

@MinkleGrag 仍然为空,没有抛出异常 - 请参阅更新的问题以了解我如何放置它 NSData 也为零? 我不相信,它创建了我之前提到的responseString,证明是好的JSON 向我展示您在 Responsestring 中获得的内容。由于您提供的此链接没有显示任何内容jsonviewer.stack.hu 该链接允许您检查文本,将其视为 JSON。如果它不能转换为 JSON,链接会告诉你,但我也会在问题中攻击字符串

以上是关于将 NSData 从 NSURLSession 转换为 JSON的主要内容,如果未能解决你的问题,请参考以下文章

为啥 NSURLSession dataTaskWithURL 比 NSData dataWithContentsOfURL 慢得多?

如何使用 Swift 从 NSURLSession 获取 cookie?

NSURLSession dataTaskWithRequest Swift

NSData writeToFile 返回 NO 没有任何错误

NSURLSession,多数据任务,completionHandler

ios 中怎样将汉字转成nsdata