Swift JSONDecoder typeMismatch错误

时间:2017-12-29 13:06:01

标签: json swift

我正在尝试使用JSONDecoder将JSON转换为Swift中的Structs,因此我编写了所有Structs,将它们修改了几个小时,它仍然给了我这个错误。我不知道是否有办法看到这条线。 我将在下面发布我的结构,然后发布Json文件链接。

完整的错误说明是:

  

typeMismatch(Swift.Dictionary< Swift.String,Any>,   Swift.DecodingError.Context(codingPath:[],debugDescription:   “预计将解码Dictionary< String,Any>但是找到了一个数组   相反。“,underlyingError:nil))

//  Created by Breno Ramos on 28/12/17.
//  Copyright © 2017 brenor2. All rights reserved.
//

import Foundation

struct Owner:Decodable {
    let login               : String?
    let id                  : Double?
    let avatar_url          : String?
    let gravatar_id         : String?
    let url                 : String?
    let html_url            : String?
    let followers_url       : String?
    let following_url       : String?
    let gists_url           : String?
    let starred_url         : String?
    let subscriptions_url   : String?
    let organizations_url   : String?
    let repos_url           : String?
    let events_url          : String?
    let received_events_url : String?
    let type                : String?
    let site_admin          : Bool?
}

struct License:Decodable {
    let key     : String?
    let name    : String?
    let spdx_id : String?
    let url     : String?
}

struct Repo:Decodable {
    let id                : Double?
    let name              : String?
    let full_name         : String?
    let owner             : Owner?
    let `private`         : Bool?
    let html_url          : String?
    let description       : String?
    let fork              : Bool?
    let url               : String?
    let forks_url         : String?
    let keys_url          : String?
    let collaborators_url : String?
    let teams_url         : String?
    let hooks_url         : String?
    let issue_events_url  : String?
    let events_url        : String?
    let assignees_url     : String?
    let branches_url      : String?
    let tags_url          : String?
    let blobs_url         : String?
    let git_tags_url      : String?
    let git_refs_url      : String?
    let trees_url         : String?
    let statuses_url      : String?
    let languages_url     : String?
    let stargazers_url    : String?
    let contributors_url  : String?
    let subscribers_url   : String?
    let subscription_url  : String?
    let commits_url       : String?
    let git_commits_url   : String?
    let comments_url      : String?
    let issue_comment_url : String?
    let contents_url      : String?
    let compare_url       : String?
    let merges_url        : String?
    let archive_url       : String?
    let downloads_url     : String?
    let issues_url        : String?
    let pulls_url         : String?
    let milestones_url    : String?
    let notifications_url : String?
    let labels_url        : String?
    let releases_url      : String?
    let deployments_url   : String?
    let created_at        : String?
    let updated_at        : String?
    let pushed_at         : String?
    let git_url           : String?
    let ssh_url           : String?
    let clone_url         : String?
    let svn_url           : String?
    let homepage          : String?
    let size              : Double?
    let stargazers_count  : Double?
    let watchers_count    : Double?
    let language          : String?
    let has_issues        : Bool?
    let has_projects      : Bool?
    let has_downloads     : Bool?
    let has_wiki          : Bool?
    let has_pages         : Bool?
    let forks_count       : Double?
    let mirror_url        : String?
    let archived          : Bool?
    let open_issues_count : Double?
    let license           : License?
    let forks             : Double?
    let open_issues       : Double?
    let topics            : Topic?
    let permissions       : Permissions?
    let watchers          : Double?
    let default_branch    : String?
    //    let score             : Double?
    //    let subscribers_count : Double?
    //    let network_count     : Double?
    //    let allow_rebase_merge: Bool?
    //    let allow_squash_merge: Bool?
    //    let allow_merge_commit: Bool?

}

struct Topic:Decodable {
    let topics : [String]?
}

struct Permissions:Decodable {
    let admin : Bool
    let push  : Bool
    let pull  : Bool
}

struct RepoList:Decodable{
    let total_count        : Int?
    let incomplete_results : Bool?
    let items              : [Repo]?
}

struct User:Decodable {
    let login: String?
    let id: Double?
    let avatar_url: String?
    let gravatar_id: String?
    let url: String?
    let html_url: String?
    let followers_url: String?
    let following_url: String?
    let gists_url: String?
    let starred_url: String?
    let subscriptions_url: String?
    let organizations_url: String?
    let repos_url: String?
    let events_url: String?
    let received_events_url: String?
    let type: String?
    let site_admin: Bool?
}

struct Creator:Decodable {
    let login: String?
    let id: Double?
    let avatar_url: String?
    let gravatar_id: String?
    let url: String?
    let html_url: String?
    let followers_url: String?
    let following_url: String?
    let gists_url: String?
    let starred_url: String?
    let subscriptions_url: String?
    let organizations_url: String?
    let repos_url: String?
    let events_url: String?
    let received_events_url: String?
    let type: String?
    let site_admin: Bool?
}

struct Link:Decodable {
    let href :String?
}

struct _Links:Decodable {
    let `self`           :Link?
    let html             :Link?
    let issue            :Link?
    let comments         :Link?
    let review_comments  :Link?
    let review_comment   :Link?
    let commits          :Link?
    let statuses         :Link?
}

struct Base:Decodable {
    let label :String?
    let ref   :String?
    let sha   :String?
    let user  :User?
    let repo  :Repo?
}

struct Head:Decodable {
    let label :String?
    let ref   :String?
    let sha   :String?
    let user  :User?
    let repo  :Repo?
}

struct Milestone:Decodable {
    let url:String?
    let html_url:String?
    let labels_url:String?
    let id: Double?
    let number:Double?
    let title:String?
    let description:String?
    let creator:Creator?
    let open_issues:Double?
    let closed_issues:Double?
    let state:String?
    let created_at:String?
    let updated_at:String?
    let closed_at:String?
    let due_on:String?
}

struct Assignee:Decodable {
    let login               :String?
    let id                  :Double?
    let avatar_url          :String?
    let gravatar_id         :String?
    let url                 :String?
    let html_url            :String?
    let followers_url       :String?
    let following_url       :String?
    let gists_url           :String?
    let starred_url         :String?
    let subscriptions_url   :String?
    let organizations_url   :String?
    let repos_url           :String?
    let events_url          :String?
    let received_events_url :String?
    let type                :String?
    let site_admin          :Bool?
}

struct Reviewers:Decodable {
    let login: String?
    let id: Double?
    let avatar_url: String?
    let gravatar_id: String?
    let url: String?
    let html_url: String?
    let followers_url: String?
    let following_url: String?
    let gists_url: String?
    let starred_url: String?
    let subscriptions_url: String?
    let organizations_url: String?
    let repos_url: String?
    let events_url: String?
    let received_events_url: String?
    let type: String?
    let site_admin: Bool?
}

struct Pull:Decodable {
    let id: Double?
    let url:String?
    let html_url:String?
    let diff_url:String?
    let patch_url:String?
    let issue_url:String?
    let number:Double?
    let state:String?
    let locked:Bool?
    let title:String?
    let user:User?
    let body:String?
    let created_at:String?
    let updated_at:String?
    let closed_at:String?
    let merged_at:String?
    let merge_commit_sha: String?
    let assignee: Assignee?
    let assignees: [Assignee]?
    let requested_reviewers: [Reviewers]?
    let milestone:Milestone?
    let commits_url:String?
    let review_comments_url:String?
    let review_comment_url:String?
    let comments_url:String?
    let statuses_url:String?
    let head:Head?
    let base:Base?
    let _links:_Links?
    let author_association:String?
}

struct PullList:Decodable {
    let pulls:[Pull]?
}




/////////////////////////////////////////////////////////

// Created by Breno Ramos on 28/12/17. // Copyright © 2017 brenor2. All rights reserved. // import Foundation struct Owner:Decodable { let login : String? let id : Double? let avatar_url : String? let gravatar_id : String? let url : String? let html_url : String? let followers_url : String? let following_url : String? let gists_url : String? let starred_url : String? let subscriptions_url : String? let organizations_url : String? let repos_url : String? let events_url : String? let received_events_url : String? let type : String? let site_admin : Bool? } struct License:Decodable { let key : String? let name : String? let spdx_id : String? let url : String? } struct Repo:Decodable { let id : Double? let name : String? let full_name : String? let owner : Owner? let `private` : Bool? let html_url : String? let description : String? let fork : Bool? let url : String? let forks_url : String? let keys_url : String? let collaborators_url : String? let teams_url : String? let hooks_url : String? let issue_events_url : String? let events_url : String? let assignees_url : String? let branches_url : String? let tags_url : String? let blobs_url : String? let git_tags_url : String? let git_refs_url : String? let trees_url : String? let statuses_url : String? let languages_url : String? let stargazers_url : String? let contributors_url : String? let subscribers_url : String? let subscription_url : String? let commits_url : String? let git_commits_url : String? let comments_url : String? let issue_comment_url : String? let contents_url : String? let compare_url : String? let merges_url : String? let archive_url : String? let downloads_url : String? let issues_url : String? let pulls_url : String? let milestones_url : String? let notifications_url : String? let labels_url : String? let releases_url : String? let deployments_url : String? let created_at : String? let updated_at : String? let pushed_at : String? let git_url : String? let ssh_url : String? let clone_url : String? let svn_url : String? let homepage : String? let size : Double? let stargazers_count : Double? let watchers_count : Double? let language : String? let has_issues : Bool? let has_projects : Bool? let has_downloads : Bool? let has_wiki : Bool? let has_pages : Bool? let forks_count : Double? let mirror_url : String? let archived : Bool? let open_issues_count : Double? let license : License? let forks : Double? let open_issues : Double? let topics : Topic? let permissions : Permissions? let watchers : Double? let default_branch : String? // let score : Double? // let subscribers_count : Double? // let network_count : Double? // let allow_rebase_merge: Bool? // let allow_squash_merge: Bool? // let allow_merge_commit: Bool? } struct Topic:Decodable { let topics : [String]? } struct Permissions:Decodable { let admin : Bool let push : Bool let pull : Bool } struct RepoList:Decodable{ let total_count : Int? let incomplete_results : Bool? let items : [Repo]? } struct User:Decodable { let login: String? let id: Double? let avatar_url: String? let gravatar_id: String? let url: String? let html_url: String? let followers_url: String? let following_url: String? let gists_url: String? let starred_url: String? let subscriptions_url: String? let organizations_url: String? let repos_url: String? let events_url: String? let received_events_url: String? let type: String? let site_admin: Bool? } struct Creator:Decodable { let login: String? let id: Double? let avatar_url: String? let gravatar_id: String? let url: String? let html_url: String? let followers_url: String? let following_url: String? let gists_url: String? let starred_url: String? let subscriptions_url: String? let organizations_url: String? let repos_url: String? let events_url: String? let received_events_url: String? let type: String? let site_admin: Bool? } struct Link:Decodable { let href :String? } struct _Links:Decodable { let `self` :Link? let html :Link? let issue :Link? let comments :Link? let review_comments :Link? let review_comment :Link? let commits :Link? let statuses :Link? } struct Base:Decodable { let label :String? let ref :String? let sha :String? let user :User? let repo :Repo? } struct Head:Decodable { let label :String? let ref :String? let sha :String? let user :User? let repo :Repo? } struct Milestone:Decodable { let url:String? let html_url:String? let labels_url:String? let id: Double? let number:Double? let title:String? let description:String? let creator:Creator? let open_issues:Double? let closed_issues:Double? let state:String? let created_at:String? let updated_at:String? let closed_at:String? let due_on:String? } struct Assignee:Decodable { let login :String? let id :Double? let avatar_url :String? let gravatar_id :String? let url :String? let html_url :String? let followers_url :String? let following_url :String? let gists_url :String? let starred_url :String? let subscriptions_url :String? let organizations_url :String? let repos_url :String? let events_url :String? let received_events_url :String? let type :String? let site_admin :Bool? } struct Reviewers:Decodable { let login: String? let id: Double? let avatar_url: String? let gravatar_id: String? let url: String? let html_url: String? let followers_url: String? let following_url: String? let gists_url: String? let starred_url: String? let subscriptions_url: String? let organizations_url: String? let repos_url: String? let events_url: String? let received_events_url: String? let type: String? let site_admin: Bool? } struct Pull:Decodable { let id: Double? let url:String? let html_url:String? let diff_url:String? let patch_url:String? let issue_url:String? let number:Double? let state:String? let locked:Bool? let title:String? let user:User? let body:String? let created_at:String? let updated_at:String? let closed_at:String? let merged_at:String? let merge_commit_sha: String? let assignee: Assignee? let assignees: [Assignee]? let requested_reviewers: [Reviewers]? let milestone:Milestone? let commits_url:String? let review_comments_url:String? let review_comment_url:String? let comments_url:String? let statuses_url:String? let head:Head? let base:Base? let _links:_Links? let author_association:String? } struct PullList:Decodable { let pulls:[Pull]? } /////////////////////////////////////////////////////////

1。This one is working fine with this structs: 2。This one is the one that gives the typeMismatch error

2 个答案:

答案 0 :(得分:9)

你现在可能正在这样做:

let decoder = JSONDecoder()
let repoList = decoder.decode(RepoList.self, from: data)

对于使用顶级对象的响应很好。

要解码作为顶级数组的JSON响应,请使用以下代码:

let decoder = JSONDecoder()
let repos = decoder.decode([Repo].self, from: data)

答案 1 :(得分:0)

如果您有一个有问题的JSON,它可以包含某些键的数字或字符串,您可以解码没有该属性的对象,并在解码后手动设置该属性。

例如,我在Vehicle内有HistoryItem个班级。在Vehicle model_year中可以为空String或非空Int。在这里,我使用modelYear手动解码NSDictionary并尝试获取IntSwift 4无法自动执行此操作。

do {
    // Decoding HistoryItem from JSON
    let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
    let decoder = JSONDecoder()
    let historyItem = try decoder.decode(HistoryItem.self, from: jsonData)
    if let modelYear = (dict as NSDictionary).value(forKeyPath: "vehicle.model_year") as? Int {
        historyItem.vehicle?.modelYear = modelYear
    }

    // Saving HistoryItem to Realm
    let realm = try! Realm()
    try! realm.write {
        realm.add(historyItem, update: true)
    }

} catch {
    print(error.localizedDescription)
}

这是Vehicle中包含的HistoryItem类:

class Vehicle: Object, Codable {
    @objc dynamic var VIN: String = ""
    @objc dynamic var make: String?
    @objc dynamic var modelName: String?
    @objc dynamic var recallCount: Int = 0
    @objc dynamic var modelYear: Int = 0

    override static func primaryKey() -> String? {
        return "VIN"
    }

    private enum CodingKeys: String, CodingKey {
        case VIN = "vin"
        case make
        case modelName = "model_name"
        case recallCount = "recall_count"
    }
}

如您所见,model_year中没有CodingKeys个键。