首页 > 解决方案 > 从 JSON API 追加到数组中

问题描述

如何使用 JSON 模型类附加到数组中。这是我的 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和位于不同的类中。itemDescriptionownerIDownerAvatarURL

以下是我尝试使用 JSONDecoder 从 JSON 获取所有属性的方法:

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()
    }
}

标签: iosarraysswiftuiviewcontrollerswift4

解决方案


完整的工作操场代码:

针对 Swift 相关存储库的 API 进行搜索。

解析它们,将它们添加到数组中并打印出每个的一些基本信息。(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 

请注意我在代码中使用的模型比您使用的模型少。无需复制代码,只需在需要时使用所需的部分。


推荐阅读