0

通过访问 url test.com/test.cfm,我可以输出以下内容:

{"COLUMNS":["OBJID","USERNAME","USERPASSWORD","USERFNAME","USERMI","USERLNAME","COMPANY","TBLCOMPANYID","TBLTITLE","USERADDRESS1","USERADDRESS2","USERCITY","USERSTATE","USERZIP","USERSIGNATUREFILE","USERBUSINESSNUMBER","USERBUSINESSEXT","USERFAXNUMBER","USERCELLNUMBER","USEROTHERNUMBER","USEREMAIL1","USEREMAIL2","USEREMAIL3","DEFAULTPROJECTID","SIGNATURE","SIGNATUREUPLOADBY","SORTORDER","DISABLESTATUS","UUID","SITEID","PROGRAMID"],
"DATA":[[1,"test",11214.0,"admin","","admin","adf Inc.",1,1,"admin","","","California","","","",null,"","","","admin@test.com","","",0,null,null,0,false,"468373c5-1234-1234-1234-3133a2bb1679",62,1]]}

要遍历这个,我首先需要使用这个来获取数据?

NSMutableData *receivedData;
    NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL     URLWithString:@"test.com/test.cfm"]
                                          cachePolicy:NSURLRequestUseProtocolCachePolicy
                                      timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:receivedData];
if (theConnection) {
    // Create the NSMutableData to hold the received data.
    // receivedData is an instance variable declared elsewhere.        
    NSLog(@"test = %@",receivedData);
} else {
    // Inform the user that the connection failed.
} 

我在正确的轨道上吗?输出显示为空...

4

1 回答 1

1

你没有分配任何东西给receivedData; 它要么是nil(在 ARC 下),要么是一个未定义的值,可能是也可能不是nil(在非 ARC 下)。您创建了一个可用于启动 URL 连接的对象,但没有对其进行任何操作。您也可能没有得到有效的NSURL,因为您没有指定 URI 方案(即 http://)。

可能最简单的事情(假设至少 iOS 5 和/或 OS X v10.7)是使用NSURLConnection's+sendAsynchronousRequest:queue:completionHandler:然后NSJSONSerialization解析结果。例如

NSURLRequest *theRequest = 
            [NSURLRequest 
                 requestWithURL:[NSURL URLWithString:@"http://test.com/test.cfm"]
                    cachePolicy:NSURLRequestUseProtocolCachePolicy
                timeoutInterval:60.0];

// or just use [NSURLRequest requestWithURL:[NSURL ...]], since the
// protocol cache policy and a 60s timeout are the default values anyway

[NSURLConnection
   sendAsynchronousRequest:theRequest
   queue:[NSOperationQueue mainQueue]
   completionHandler:
        ^(NSHTTPURLResponse *urlResponse, NSData *data, NSError *error)
        {
            // catch all for connection errors...
            if(
                (urlResponse.statusCode < 200) ||
                (urlResponse.statusCode >= 300) || // bad status code, e.g. 404
                error || // error is non-nil would imply some other error
                ![data length] // data returned was empty
             )
             {
                  // report some sort of connection error
                 return;
             }

             NSError *jsonError = nil;
             id <NSObject> returnedJSONObject =
                [NSJSONSerialization
                          JSONObjectWithData:data options:0 error:&jsonError];
             if(jsonError)
             {
                   // server returned unintelligible JSON...
                   return;
             }

             NSLog(@"Got object %@", returnedJSONObject);

             // then, e.g.
             if(![jsonObject isKindOfClass:[NSDictionary class]])
             {
                 // server didn't return a dictionary
                 return;
             }

             NSArray *columns = [jsonObject objectForKey:@"COLUMNS"];
             if(![columns isKindOfClass:[NSArray class]])
             {
                  // server returned no COLUMNS object, or that
                  // object wasn't an array
                  return;
             }

             NSLog(@"columns are %@", columns);

             /* etc, etc */
        }];

如果您找不到自动化的方法,那么类类型检查的内容很快就会变得非常乏味,但这都是与您的问题没有直接关系的验证内容。

上面实现的是它发送一个对URL内容的异步(即非阻塞)请求。结果累积在主队列中(即,您通常进行用户交互的同一位置)。一旦整个 HTTP 操作完成,您在底部指定的代码就会被调用,并验证和解析响应。它是同步进行的,因此会阻塞,但除非分析表明值得担心,否则这不值得担心。

内置解析器用于 JSON,直到“得到对象”的所有内容实际上只是确保获取和解析成功。它可能不完整——如果你能想到任何其他可能出错的地方,那么不要以为我故意忽略了它。

那时你只有一个未知类型的对象,但由于 JSON 的基本原理,它通常是字典或数组。因此,示例代码测试它确实是一个字典,然后使用普通NSDictionary接口获取“COLUMNS”键的对象。如果您尝试调用objectForKey:数组,则会引发异常,因为数组不实现该方法。

然后它相当死记硬背——代码检查存储为“COLUMNS”的对象是一个数组。根据 JSON 规则,它可能是另一个字典或字符串或其他一些东西之一。可能有趣的是代码调用isKindOfClass:以测试是否找到了一个对象,并且它是一个单一调用中的数组;之所以有效,是因为明确允许向其发送任何消息,nil并且结果将始终为nil,看起来与 BOOL NO 相同。

于 2012-10-30T22:33:05.813 回答