【问题标题】:Parse JSON file from URL and return single String从 URL 解析 JSON 文件并返回单个字符串
【发布时间】:2022-11-16 02:33:32
【问题描述】:

我正在尝试从 this JSON file from a 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:@"https://i-doser.com/radio/livestream.json"]
          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);

但这返回空值。

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

【问题讨论】:

  • 使用 NSLog(@"YouTube ID: %@", json); 的确切输出更新您的问题。顺便说一句——看起来 json 变量应该是 NSDictionary,而不是 NSArray。
  • 正如它所说:到目前为止,我可以将整个 JSON 返回到日志中。所以, NSLog(@"YouTube ID: %@", json);当我试图仅返回 videoId 时返回整个 json。
  • 至少显示从一开始到您想要的 videoID 的 NSLog 语句的输出。关键是要确认您获得的实际结构是否符合您的预期。
  • 它返回nil,因为根对象是一个字典,注意开头的{。

标签: json objective-c


【解决方案1】:

我认为你在正确的轨道上。我已将下面的示例 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 应该执行的操作,以便在返回数据之前以某种方式操作数据。

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

【讨论】:

    猜你喜欢
    • 2020-07-10
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    相关资源
    最近更新 更多