从 URL 解析 JSON 文件并返回单个字符串

Parse JSON file from URL and return single String

提问人:BinDev 提问时间:11/16/2022 最后编辑:BinDev 更新时间:11/16/2022 访问量:58

问:

我正在尝试从 URL 处的 JSON 文件返回 videoId

{
  "kind": "youtube#searchListResponse",
  "etag": "imd66saJvwX2R_yqJNpiIg-yJF8",
  "regionCode": "US",
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "BeIXYopOmOl2niJ3NJzUbdlqSA4",
      "id": {
        "kind": "youtube#video",
        "videoId": "1q7NUPF6j8c"
      },

(示例中的正确返回值为 1q7NUPF6j8c)。然后我想将视频 ID 加载到 一个

[self.playerView loadWithVideoId:@"the JSON video ID"];

到目前为止,我可以使用以下命令将整个JSON返回到日志中:

NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"URL"]
          completionHandler:^(NSData *data,
                              NSURLResponse *response,
                              NSError *error) {
    NSArray* json = [NSJSONSerialization JSONObjectWithData:data
                                                    options:0
                                                      error:nil];
    NSLog(@"YouTube ID: %@", json);
    //NSArray *videoid = [json valueForKeyPath:@"items.0.id.videoId"];
    //NSLog(@"VideoID: %@", videoid);

  }] resume];

这将返回到 NSLOG:

**App [6094:1793786] YouTube ID: {
    etag = "imd66saJvwX2R_yqJNpiIg-yJF8";
    items =     (
                {
            etag = BeIXYopOmOl2niJ3NJzUbdlqSA4;
            id =             {
                kind = "youtube#video";
                videoId = 1q7NUPF6j8c;
            };
            kind = "youtube#searchResult";**

(以及 json 的其余部分)。

我试过这是在黑暗中拍摄的。

//NSArray *videoid = [json valueForKeyPath:@"items.0.id.videoId"];
//NSLog(@"VideoID: %@", videoid);

但这返回 null。

我怎样才能只返回并将其传递给 ?videoIDself.playerView loadWithVideoId

JSON Objective-C

评论

0赞 HangarRash 11/16/2022
使用 的确切输出更新您的问题。顺便说一句 - 看起来变量应该是 ,而不是 。NSLog(@"YouTube ID: %@", json);jsonNSDictionaryNSArray
0赞 BinDev 11/16/2022
正如它所说:到目前为止,我可以将整个 JSON 返回到日志中。所以,NSLog(@“YouTube ID: %@”, json);当我尝试仅返回 videoId 时返回整个 json。
0赞 HangarRash 11/16/2022
至少从一开始就显示该 NSLog 语句的输出到您想要的输出。关键是要确认你得到的实际结构与你所期望的相匹配。videoID
0赞 vadian 11/16/2022
它返回是因为根对象是一个字典,请注意开头的 。nil{

答:

1赞 R4N 11/16/2022 #1

我认为你走在正确的轨道上。我已将下面的示例json添加到您的示例json中,作为数组中有多个项目以进行说明的示例:"items"

{
  "kind": "youtube#searchListResponse",
  "etag": "imd66saJvwX2R_yqJNpiIg-yJF8",
  "regionCode": "US",
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "BeIXYopOmOl2niJ3NJzUbdlqSA4",
      "id": {
        "kind": "youtube#video",
        "videoId": "1q7NUPF6j8c"
      },
    },
    {
      "kind": "youtube#searchResult",
      "etag": "secondETag",
      "id": {
        "kind": "youtube#video",
        "videoId": "secondVideoId"
      },
    }
  ]
}

我首先注意到的一行代码是,在解析 json 对象时,您期望有一个 NSArray:

    NSArray* json = [NSJSONSerialization JSONObjectWithData:data
                                                    options:0
                                                      error:nil];

根据示例输入,您应该期望 NSDictionary 作为顶级对象:

    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data
                                                             options:0
                                                               error:nil];

现在进入valueForKeyPath

如果你要使用这样的东西:

[jsonDict valueForKeyPath:@"items.id.videoId"]

您将获得所有视频 ID 的 NSArray:

(
    1q7NUPF6j8c,
    secondVideoId
)

然后你想要第一个对象,这样你就可以用作“集合运算符”来获取第一个对象。因此,完整的密钥路径为:@firstObject

    NSString *videoId = [jsonDict valueForKeyPath:@"items.id.videoId.@firstObject"];

其结果是:1q7NUPF6j8c

键值编码编程指南中提供了一些有关使用集合运算符的其他文档:https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/CollectionOperators.html#//apple_ref/doc/uid/20002176-BAJEAIEE

虽然在您可以使用的页面上没有明确说明(或记录),但以下是其中的一些部分,这些部分暗示了前几段中的解决方案:@firstObject

集合运算符是一小群关键字之一,前面有一个 at 符号 (@),它指定了 getter 在返回数据之前应以某种方式操作数据的操作。

当键路径包含集合运算符时,运算符前面的键路径的任何部分(称为左键路径)指示相对于消息接收方要操作的集合。

评论

0赞 BinDev 11/16/2022
非常感谢你,这很完美,而且解决方案解释得很好。