目标c从url请求中解析json

Posted

技术标签:

【中文标题】目标c从url请求中解析json【英文标题】:objective c parse json from url request 【发布时间】:2013-11-19 16:51:59 【问题描述】:

我正在尝试解析从位于以下位置的 api 请求的 json 字符串: http://www.physics.leidenuniv.nl/json/news.php

但是,我无法解析这个 json。 我收到以下错误: Unexpected end of file during string parse

我已经找了几个小时,但我找不到这个问题的答案。

我的代码sn-p:

在我看来DidLoad:

NSURLRequest *request = [NSURLRequest requestWithURL:
                         [NSURL URLWithString:@"http://www.physics.leidenuniv.nl/json/news.php"]];

[[NSURLConnection alloc] initWithRequest:request delegate:self];

委托人:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
NSMutableData *responseData = [[NSMutableData alloc] init];
[responseData appendData:data];

NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSError *e = nil;
NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingMutableContainers error: &e];

有人知道这个问题的答案,所以我可以解析 json 数据吗?

【问题讨论】:

didReceiveData 被调用并不意味着所有数据都已收到——可能还会有更多数据。 确实,didReceiveData 方法将被调用几次,其中包含您的全部数据。您必须实例化一个 NSData 并将块一个接一个地粘贴到其中。 试试AFNetworking 【参考方案1】:

我建议这样做:

NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.physics.leidenuniv.nl/json/news.php"]];

__block NSDictionary *json;
[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) 
                           json = [NSJSONSerialization JSONObjectWithData:data
                                                                  options:0
                                                                    error:nil];
                           NSLog(@"Async JSON: %@", json);
                       ];

或者如果出于某种原因(不推荐)您想要运行同步请求,您可以这样做:

NSData *theData = [NSURLConnection sendSynchronousRequest:request
                      returningResponse:nil
                                  error:nil];

NSDictionary *newJSON = [NSJSONSerialization JSONObjectWithData:theData
                                                        options:0
                                                          error:nil];

NSLog(@"Sync JSON: %@", newJSON);

【讨论】:

【参考方案2】:

这样做:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

    // Append the new data to receivedData.
    // receivedData is an instance variable declared elsewhere.

    [responseData appendData:data];



- (void)connectionDidFinishLoading:(NSURLConnection *)connection

NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSError *e = nil;
NSData *jsonData = [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingMutableContainers error: &e];


【讨论】:

【参考方案3】:
//call this method
-(void)syncWebByGETMethod

      [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    NSString *urlString = [NSString stringWithFormat:@"http://www.yoursite.com"];
    NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
   [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue]                          completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError)
        
         if (data)
         
             id myJSON;
             @try 
                 myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
             
             @catch (NSException *exception) 
             
             @finally 
             
             jsonArray = (NSArray *)myJSON;

             NSLog(@"mmm %@",jsonArray);
         
     ];

【讨论】:

【参考方案4】:

在字典中存储 json-url 数据的简单方法。

 NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://query.yahooapis.com/v1/public/yql?q=select+%2A+from+weather.forecast+where+woeid%3D1100661&format=json"]];
    NSError *error=nil;
    id response=[NSJSONSerialization JSONObjectWithData:data options:
                 NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:&error];

    if (error) 
        NSLog(@"%@",[error localizedDescription]);
     else 
        _query = [response objectForKey:@"query"];
        NSLog(@"%@",_query); 

你可以试试这个,很简单。

【讨论】:

【参考方案5】:

一种解决方案是使用NSURLConnection sendSynchronousRequest:returningResponse:error: (docs)。在完成处理程序中,您将拥有所有响应数据,而不仅仅是您在委托的 connection:didReceiveData: 方法中获得的部分数据。

如果您想继续使用代理,您需要遵循Apple docs 中的建议:

委托应该连接每个数据对象的内容 交付以构建 URL 加载的完整数据。

【讨论】:

【参考方案6】:

Volunteermatch API Objective C

我正在使用一种常见的方法进行 AFNetworking WS 调用。 用途:

调用WS:

NSDictionary* param = @
                        @"action":@"helloWorld",
                        @"query":@"\"name\":\"john\""
                        ;

[self requestWithUrlString:@"URL" parmeters:paramDictionary success:^(NSDictionary *response) 
    //code For Success
 failure:^(NSError *error) 
   // code for WS Responce failure
];

添加两种方法: 这两种方法是通用的,你可以在使用 NSObject 类的整个项目中使用这些通用方法。 还添加 // 定义错误代码...

定义 kDefaultErrorCode 12345

- (void)requestWithUrlString:(NSString *)stUrl parmeters:(NSDictionary *)parameters success:(void (^)(NSDictionary *response))success failure:(void (^)(NSError *error))failure 

[self requestWithUrl:stUrl parmeters:parameters success:^(NSDictionary *response) 
    if([[response objectForKey:@"success"] boolValue]) 
        if(success) 
            success(response);
            
        
    
    else 
        NSError *error = [NSError errorWithDomain:@"Error" code:kDefaultErrorCode userInfo:@NSLocalizedDescriptionKey:[response objectForKey:@"message"]];
        if(failure) 
            failure(error);
        
    
 failure:^(NSError *error) 
    if(failure) 
        failure(error);
    
];

和 // 在下面的方法中设置标题(如果需要,否则删除)

- (void)requestWithUrl:(NSString *)stUrl parmeters:(NSDictionary *)parameters success:(void (^)(NSDictionary *response))success failure:(void (^)(NSError *))failure 

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager setResponseSerializer:[AFHTTPResponseSerializer serializer]];


[manager.requestSerializer setValue:@"WWSE profile=\"UsernameToken\"" forHTTPHeaderField:@"Authorization"];



[manager GET:stUrl parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) 
    if([responseObject isKindOfClass:[NSDictionary class]]) 
        if(success) 
            success(responseObject);
        
    
    else 
        NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil];
        if(success) 
            success(response);
        
    
 failure:^(AFHTTPRequestOperation *operation, NSError *error) 
    NSLog(@"Error: %@", error);
    if(failure) 
        failure(error);
    
];

如有任何问题和更多详情please visit..AFNetworking

【讨论】:

【参考方案7】:
-(void)getWebServic
NSURL *url = [NSURL URLWithString:@"----URL----"];

// 2
NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession]
                                      dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)

    NSDictionary *jsonObject=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
    [self loadDataFromDictionary:(NSArray*)jsonObject];
    NSLog(@"data: %@",jsonObject);

];

// 3
[downloadTask resume]; 

【讨论】:

以上是关于目标c从url请求中解析json的主要内容,如果未能解决你的问题,请参考以下文章

如何在目标c中逐行解析JSON文件

如何从JSON请求解析特定数据

如何使用目标 C 解析 JSON 并获取特定值? [复制]

如何在没有目标c的键的情况下解析json第一个对象?

AWS Lambda 错误:当 url 参数包含 JSON 数组时,“无法将请求正文解析为 json”

使用目标 C 解析 JSON?