JSON-объект анализирует, но пропускает первый элемент в наборе - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь получить доступ к первому результату из этого запроса: 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'.Я неправильно разбираю это?

1 Ответ

0 голосов
/ 18 декабря 2018

Как видите, есть ключ position, вы должны предположить, что список не отсортирован.Вы должны найти 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)
}

Примечание: Некоторые изменения были внесены после принятия ответа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...