JSON 对象解析但省略了集合中的第一项

标签 json swift

我正在尝试访问此查询的第一个结果: https://www.instagram.com/web/search/topsearch/?query=_myUsername

我能够像这样得到一个 JSON 对象:

var request = URLRequest(url: URL(string: api)!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else { // check for fundamental networking error
        print("error=\(error ?? "" as! Error)")
        return
    }

    do {
        let jsonResponse = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
        completionHandler(jsonResponse,nil)

    } catch let parsingError {
        print("Error", parsingError)
    }

    if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {  // check for http errors
        print("statusCode should be 200, but is \(httpStatus.statusCode)")
        print("response = \(String(describing: response))")
    }

}
task.resume()

结果是一个 JSON 对象,它省略了“users”中的第一个用户。例如,如果我解析 JSON 对象以获取结果中第一个用户的用户名,如下所示...

if let users = jsonResponse!["users"] as? [Any] {
    if let first = users.first as? [String: Any] {
        if let user = first["user"] as? [String: Any] {
            self.igUser = user["username"] as! String

...它返回“position = 1”用户的用户名,而我实际上想要“position = 0”用户。我解析错了吗?

最佳答案

如您所见,有一个关键的位置,您应该假设该列表未排序。您必须找到列表的 nth 元素。

最小的 Codable 实现是:

struct TopSearchAPIResponse: Codable {
    let users: [User]
    //let places, hashtags: [Type] // As these two are empty arrays you don't know 
                                   // their type in advance. So you can omit them 
                                   // for now. When you know their type you can 
                                   // use them by providing actual type.
    let hasMore: Bool
    let rankToken: String
    let clearClientCache: Bool
    let status: String

    struct User: Codable {
        let position: Int
        let user: UserInfo

        struct UserInfo: Codable {
            let pk: String
            let username: String
            let fullName: String
            let isPrivate: Bool
            let profilePicURL: URL
            let profilePicID: String?
            let isVerified: Bool
            let hasAnonymousProfilePicture: Bool
            let followerCount: Int
            let reelAutoArchive: ReelAutoArchive
            let byline: String
            let mutualFollowersCount: Int
            let unseenCount: Int

            private enum CodingKeys: String, CodingKey {
            /* This enum is necessary as we want profile_pic_url & profile_pic_id  
            to be decoded as profilePicURL & profilePicID respectively (instead of 
            profilePicUrl & profilePicId) so that we follow Swift conventions */

                case pk
                case username
                case fullName
                case isPrivate
                case profilePicURL = "profilePicUrl"
                case profilePicID = "profilePicId"
                case isVerified
                case hasAnonymousProfilePicture
                case followerCount
                case reelAutoArchive
                case byline
                case mutualFollowersCount
                case unseenCount
            }

            enum ReelAutoArchive: String, Codable {
                case off
                case on
                case unset
            }
        }
    }
}

您将使用它作为:

do {
    let jsonDecoder = JSONDecoder()
    jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase
    let response = try jsonDecoder.decode(TopSearchAPIResponse.self, from: data)
    if let firstUser = response.users.first(where: { $0.position == 0 }) {
        print(firstUser.user.username) // prints "myusernameisverygay"
    }
} catch {
    print(error)
}

注意:部分答案采纳后进行了修改。

关于JSON 对象解析但省略了集合中的第一项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53823946/

相关文章:

python - 如何通过 python API 将 json/pickle 文件转储和读取到 Google Drive?

mysql - 在 Groovy SQL 中使用参数的正确方法

flash - 将 JSON 传递给 Flash 电影

php - 无法让 POST 与 swift 一起工作

ios - 从多个部分 UITableView 中的 UITableViewCell 获取 IndexPath 以响应通知

java - 如何解析 JSON 数组并将其显示在 ListView 中?

ios - Swift 协议(protocol)中的可选闭包

json - 调用 JSONDecoder 后,对象没有明显变化

ios - Swift ios 从 pickerView 获取选定值

sql - 如何在mssql中使用左连接与json路径?