在 Swift 4 中从 URL 解析 JsonObject

问题描述 投票:0回答:2

对我来说,这是一个非常简单的任务,但即使经过大量研究和尝试,我也无法让它工作......

例如,我有这个 URL,据我了解,这是 JSONObject 的 api?!

http://api.geekdo.com/api/images?ajax=1&gallery=all&nosession=1&objectid=127023&objecttype=thing&pageid=357&showcount=1&size=thumb&sort=recent

如果我在浏览器中打开此链接,我会得到以下结果:

{“图像”:[{“imageid”:“1567153”,“imageurl_lg”:“https://cf.geekdo-images.com/images/pic1567153_lg.jpg”,“名称”:null,“标题”: “白色的 力量 tiles","numrecommend":"6","numcomments":"0","user":{"用户名":"manosdowns","avatar":"1","avatarfile":"avatar_id33829.jpg"} ,"imageurl":"https://cf.geekdo-images.com/6fCr14v025ZKYhXRMnbhYR16Ta8=/fit-in/200x150/pic1567153.jpg"}],"config":{"sorttypes":[{"type":"热门","name":"热门"},{"type":"最近","name":"最近"}],"numitems":402,"endpage":402,"galleries":[{" type":"all","name":"All"},{"type":"game","name":"Game"},{"type":"people","name":"People" },{"type":"creative","name":"Creative"}],"categories":[{"type":"","name":"全部"},{"type":"BoxFront ","name":"BoxFront"},{"type":"BoxBack","name":"BoxBack"},{"type":"Components","name":"Components"},{"type ":"自定义","name":"自定义"},{"type":"播放","name":"播放"},{"type":"其他","name":"其他"} ,{"type":"成熟","name":"成熟"},{"type":"uncat","name":"未分类"}],"licensefilters":[{"type":"" ,"name":"任意"},{"type":"重用","name":"复制 允许"},{"type":"商业","name":"商业用途 允许"},{"type":"修改","name":"修改 允许"}],"datefilters":[{"value":"alltime","name":"全部 时间"},{"value":"今天","name":"今天"},{"value":"两天","name":"二 天"},{"value":"last7","name":"过去 7 天 天"},{"value":"last30","name":"过去 30 天"},{"value":"年份","name":"过去 365 天"}],"过滤器":[{"名称":"许可证","列表名称":"许可证过滤器","类型":"许可证过滤器"},{"名称":"类别","列表名称":"类别","type":"标签"},{"name":"图库","listname":"图库","type":"图库"}]}}

现在我的第一次尝试是以解析主页的方式解析此链接:

    guard let myURL = URL(string: link) else {                                                 >             print("Error: \(link) doesn't seem to be a valid URL")
        return
    }

    do {
        link = try String(contentsOf: myURL, encoding: .ascii)
    } catch let error {
        print("Error: \(error)")
    }

但这不起作用,因为我现在明白这是因为这是 JSON 编码的?!

我搜索了解析 JSON 并找到了一些编码和解码的解释,但我的问题是,在给出的所有示例中,解释都是从“拥有”JsonObject 的内容开始的。 我的问题是我可以在浏览器中读取 URL 的内容,但我需要 Xcode 本身中的 URL 内容,以便我可以解析它?!

所以在我的具体情况下,我只需要“imageurl_lg”的内容

...如果我可以在 Xcode 中显示我在浏览器中可以看到的内容,我就会知道该怎么做 - 但如何将链接的内容获取到 Xcode 中?

作为参考,我还阅读了以下说明,但无法将它们应用到我的示例中...... https://www.raywenderlich.com/172145/encoding-decoding-and-serialization-in-swift-4

https://grokswift.com/json-swift-4/

还有更多,但他们没有帮助我......

ios json swift swift4
2个回答
8
投票

您需要使用 URLSession 任务来执行此操作,之后您需要使用

JSONSerialization
在本例中我返回一个
[String:Any]
的字典,您可以将其转换为您需要的任何模型

使用此代码

func fetchData(completion: @escaping ([String:Any]?, Error?) -> Void) {
    let url = URL(string: "http://api.geekdo.com/api/images?ajax=1&gallery=all&nosession=1&objectid=127023&objecttype=thing&pageid=357&showcount=1&size=thumb&sort=recent")!

    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        guard let data = data else { return }
        do {
            if let array = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:Any]{
                completion(array, nil)
            }
        } catch {
            print(error)
            completion(nil, error)
        }
    }
    task.resume()
}

如何使用

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    fetchData { (dict, error) in
        debugPrint(dict)
    }
}

打印结果日志

Optional(["config": {
    categories =     (
                {
            name = All;
            type = "";
        },
                {
            name = BoxFront;
            type = BoxFront;
        },
                {
            name = BoxBack;
            type = BoxBack;
        },
                {
            name = Components;
            type = Components;
        },
                {
            name = Customized;
            type = Customized;
        },
                {
            name = Play;
            type = Play;
        },
                {
            name = Miscellaneous;
            type = Miscellaneous;
        },
                {
            name = Mature;
            type = Mature;
        },
                {
            name = Uncategorized;
            type = uncat;
        }
    );
    datefilters =     (
                {
            name = "All Time";
            value = alltime;
        },
                {
            name = Today;
            value = today;
        },
                {
            name = "Two Days";
            value = twodays;
        },
                {
            name = "Last 7 Days";
            value = last7;
        },
                {
            name = "Last 30 Days";
            value = last30;
        },
                {
            name = "Last 365 Days";
            value = year;
        }
    );
    endpage = 402;
    filters =     (
                {
            listname = licensefilters;
            name = Licenses;
            type = licensefilter;
        },
                {
            listname = categories;
            name = Category;
            type = tag;
        },
                {
            listname = galleries;
            name = Gallery;
            type = gallery;
        }
    );
    galleries =     (
                {
            name = All;
            type = all;
        },
                {
            name = Game;
            type = game;
        },
                {
            name = People;
            type = people;
        },
                {
            name = Creative;
            type = creative;
        }
    );
    licensefilters =     (
                {
            name = Any;
            type = "";
        },
                {
            name = "Copying allowed";
            type = reuse;
        },
                {
            name = "Commercial use allowed";
            type = commercial;
        },
                {
            name = "Modification allowed";
            type = modify;
        }
    );
    numitems = 402;
    sorttypes =     (
                {
            name = Hot;
            type = hot;
        },
                {
            name = Recent;
            type = recent;
        }
    ); }, "images": <__NSSingleObjectArrayI 0x600000010710>( {
    caption = "White power tiles";
    imageid = 1567153;
    imageurl = "https://cf.geekdo-images.com/6fCr14v025ZKYhXRMnbhYR16Ta8=/fit-in/200x150/pic1567153.jpg";
    "imageurl_lg" = "https://cf.geekdo-images.com/images/pic1567153_lg.jpg";
    name = "<null>";
    numcomments = 0;
    numrecommend = 6;
    user =     {
        avatar = 1;
        avatarfile = "avatar_id33829.jpg";
        username = manosdowns;
    }; } ) ])

更新修复了“应用程序传输安全已阻止明文”错误

调整您的info.plist

enter image description here


1
投票

这就是游乐场给我的。

import UIKit

var str = "Hello, playground"

func makeGetCall() {
    guard let myURL = URL(string: "http://api.geekdo.com/api/images?ajax=1&gallery=all&nosession=1&objectid=127023&objecttype=thing&pageid=357&showcount=1&size=thumb&sort=recent") else {
        print("Error: \(link) doesn't seem to be a valid URL")
        return
    }

    do {
        var content = try String(contentsOf: myURL, encoding: .ascii)
        print("Content: \(content)")
    } catch let error {
        print("Error: \(error)")
    }
}
makeGetCall()

打印

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.