Добавить в массив из JSON API - PullRequest
0 голосов
/ 09 июня 2018

Как я могу добавить в массив, используя JSON Model Class.Вот мой запрос JSON API: https://developer.github.com/v3/search/

import Foundation

typealias GitDecode = [GitDecodeElement]

struct GitDecodeElement: Codable {
    let totalCount: Int
    let incompleteResults: Bool
    let items: [Item]

    enum CodingKeys: String, CodingKey {
        case totalCount = "total_count"
        case incompleteResults = "incomplete_results"
        case items
    }
}

struct Item: Codable {
    let id: Int
    let nodeID, name, fullName: String
    let owner: Owner
    let itemPrivate: Bool
    let htmlURL, description: String
    let fork: Bool
    let url, createdAt, updatedAt, pushedAt: String
    let homepage: String
    let size, stargazersCount, watchersCount: Int
    let language: String
    let forksCount, openIssuesCount: Int
    let masterBranch, defaultBranch: String
    let score: Double

    enum CodingKeys: String, CodingKey {
        case id
        case nodeID = "node_id"
        case name
        case fullName = "full_name"
        case owner
        case itemPrivate = "private"
        case htmlURL = "html_url"
        case description, fork, url
        case createdAt = "created_at"
        case updatedAt = "updated_at"
        case pushedAt = "pushed_at"
        case homepage, size
        case stargazersCount = "stargazers_count"
        case watchersCount = "watchers_count"
        case language
        case forksCount = "forks_count"
        case openIssuesCount = "open_issues_count"
        case masterBranch = "master_branch"
        case defaultBranch = "default_branch"
        case score
    }
}

struct Owner: Codable {
    let login: String
    let id: Int
    let nodeID, avatarURL, gravatarID, url: String
    let receivedEventsURL, type: String

    enum CodingKeys: String, CodingKey {
        case login, id
        case nodeID = "node_id"
        case avatarURL = "avatar_url"
        case gravatarID = "gravatar_id"
        case url
        case receivedEventsURL = "received_events_url"
        case type
    }
}

И вот у меня есть модель класса, где я говорю, что я хочу извлечь из этого ответа:

import Foundation

struct Git: Codable{

    let totalCount: Int
    let items: GitItem

    init ( totalCount: Int,
           itemID: Int, itemDescription: String,
          ownerID: Int, ownerAvatarURL: String) {

        self.totalCount = totalCount
        self.items = GitItem(id: itemID, description: itemDescription, owner: GitOwner(id: ownerID, avatarURL: ownerAvatarURL))
    }
}

struct GitItem: Codable{
    let id: Int
    let description: String
    let owner: GitOwner
}

struct GitOwner: Codable {
    let id: Int
    let avatarURL: String
}

СейчасЯ застреваю, когда пытаюсь добавить в свой массив все свои пользовательские свойства, потому что itemID, itemDescription, ownerID и ownerAvatarURL находятся в разных классах.

Вот как я пытаюсьчтобы получить все эти свойства из JSON с помощью JSONDecoder:

import UIKit

class MainViewController: UIViewController {

    var gitRepositoriesArray = [Git]()

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    // Download Git Repositories from API
    func parseGitRepositories(){

        let url = URL(string: "https://developer.github.com/v3/search/")
        URLSession.shared.dataTask(with: url!) { (data, response, error) in
            if error == nil{
                do{
                    let gitRepositoriesList = try JSONDecoder().decode(GitDecode.self, from: data!)
                    for eachRepo in gitRepositoriesList{

                        self.gitRepositoriesArray.append(Git(totalCount: eachRepo.totalCount,
                                                    itemID: <#T##Int#> , itemDescription: <#T##String#>, ownerID: <#T##Int#>, ownerAvatarURL: <#T##String#>))


                    }

                }catch{
                    print(error.localizedDescription)
                }
            }
        }.resume()
    }
}

Ответы [ 2 ]

0 голосов
/ 09 июня 2018

Полный код рабочей площадки:

Выполняет поиск по API для репозиториев, связанных со Swift.

Разбирает их, добавляет их в массив и распечатывает некоторую основную информацию о каждом из них.(fullName, name, avatarUrl

//: Playground - noun: a place where people can play
import PlaygroundSupport
import UIKit

struct GitDecodeElement: Codable {
    let totalCount: Int
    let incompleteResults: Bool
    let items: [Repo]

    enum CodingKeys: String, CodingKey {
        case totalCount = "total_count"
        case incompleteResults = "incomplete_results"
        case items
    }
}

struct Repo: Codable {
    let id: Int
    let nodeID, name, fullName: String
    let owner: Owner
    let itemPrivate: Bool
    let htmlURL, description: String
    let fork: Bool
    let url, createdAt, updatedAt, pushedAt: String
    let homepage: String?
    let size, stargazersCount, watchersCount: Int
    let language: String?
    let forksCount, openIssuesCount: Int
    let score: Double

    enum CodingKeys: String, CodingKey {
        case id
        case nodeID = "node_id"
        case name
        case fullName = "full_name"
        case owner
        case itemPrivate = "private"
        case htmlURL = "html_url"
        case description, fork, url
        case createdAt = "created_at"
        case updatedAt = "updated_at"
        case pushedAt = "pushed_at"
        case homepage, size
        case stargazersCount = "stargazers_count"
        case watchersCount = "watchers_count"
        case language
        case forksCount = "forks_count"
        case openIssuesCount = "open_issues_count"
        case score
    }
}

struct Owner: Codable {
    let login: String
    let id: Int
    let nodeID, avatarURL, gravatarID, url: String
    let receivedEventsURL, type: String

    enum CodingKeys: String, CodingKey {
        case login, id
        case nodeID = "node_id"
        case avatarURL = "avatar_url"
        case gravatarID = "gravatar_id"
        case url
        case receivedEventsURL = "received_events_url"
        case type
    }
}



var gitRepositoriesArray = [Repo]()

// Download Git Repositories from API
func parseGitRepositories() {

    let url = URL(string: "https://api.github.com/search/repositories?q=topic:swift+topic:ios")
    var request = URLRequest(url: url!)
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    URLSession.shared.dataTask(with: request) { (data, response, error) in

        guard error == nil else {
            print(error?.localizedDescription)
            return
        }

        do {
            let gitRepositoriesList = try JSONDecoder().decode(GitDecodeElement.self, from: data!)

            gitRepositoriesArray = gitRepositoriesArray + gitRepositoriesList.items
            print(gitRepositoriesArray.count)

            for repo in gitRepositoriesList.items {
                print("\(repo.fullName) - \(repo.name) - \(repo.owner.avatarURL)")
            }

        } catch {
            let str = String(data: data!, encoding: .utf8)
            print(str)
            print(error)
        }

    }.resume()
}

parseGitRepositories()

PlaygroundPage.current.needsIndefiniteExecution = true

Вывод:

30

justjavac/free-programming-books-zh_CN - free-programming-books-zh_CN - https://avatars1.githubusercontent.com/u/359395?v=4
dkhamsing/open-source-ios-apps - open-source-ios-apps - https://avatars0.githubusercontent.com/u/4723115?v=4
matteocrippa/awesome-swift - awesome-swift - https://avatars2.githubusercontent.com/u/475463?v=4
xitu/gold-miner - gold-miner - https://avatars2.githubusercontent.com/u/10482599?v=4
lkzhao/Hero - Hero - https://avatars1.githubusercontent.com/u/3359850?v=4
ReactiveX/RxSwift - RxSwift - https://avatars1.githubusercontent.com/u/6407041?v=4
realm/realm-cocoa - realm-cocoa - https://avatars0.githubusercontent.com/u/7575099?v=4
CocoaPods/CocoaPods - CocoaPods - https://avatars1.githubusercontent.com/u/1189714?v=4
CosmicMind/Material - Material - https://avatars1.githubusercontent.com/u/10069574?v=4
// rest truncated 

Обратите внимание, что в вашем коде я использую меньше моделей, чем вы. Нет необходимостидублируйте код, просто используйте нужные вам части, когда хотите.

0 голосов
/ 09 июня 2018

В вашей структуре Git есть проблема.Я исправил инициализатор следующим образом:

struct Git: Codable{

let totalCount: Int
var items = [GitItem]()

init(totalCount: Int, items: [Item]) {
    self.totalCount = totalCount

    for item in items {
        self.items.append(GitItem(id: item.id, description: item.description, owner: GitOwner(id: item.owner.id, avatarURL: item.owner.avatarURL)))
    }

}

Таким образом, ваш метод синтаксического анализа будет изменен соответственно:

    // Download Git Repositories from API
func parseGitRepositories(){

    let url = URL(string: "https://api.github.com/search/repositories?q=tetris+language:assembly&sort=stars&order=desc")
    URLSession.shared.dataTask(with: url!) { (data, response, error) in
        if error == nil{
            do{
                let gitRepositoriesList = try JSONDecoder().decode(GitDecode.self, from: data!)
                for eachRepo in gitRepositoriesList{
                    self.gitRepositoriesArray.append(Git(totalCount: eachRepo.totalCount, items: eachRepo.items))
                }

            }catch{
                print(error.localizedDescription)
            }
        }
        }.resume()
}

Также обратите внимание на изменение URL-адреса на https://api.github.com/search/repositories?q=tetris+language:assembly&sort=stars&order=desc.Текущий URL-адрес, который вы используете в своем коде, представляет собой HTML-страницу с примерами.Он не возвращает правильные результаты JSON.

...