2017-12-29 23 views
0

JSONDecoder를 사용하여 JSON을 Swift의 Structs로 변환하려고 했으므로 모든 Structs를 작성하고 몇 시간 동안 수정했으며 여전히이 오류를 표시합니다. 이 줄을 볼 수있는 방법이 있는지 나는 모른다. 아래에 제 구조체를 게시하고 Json File 링크를 게시합니다.Swift JSONDecoder typeMismatch 오류

전체 오류 설명 :

typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", 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]? 
} 




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

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

+0

작동하지 않는 것은'Array'입니다. –

+1

첫 번째 JSON은 사전을 최상위 객체로 사용하고 두 번째 JSON은 배열을 나타냅니다. 오류 메시지에서 분명히 나타내는 것처럼. –

답변

1

당신은 아마 지금이 권리를하고있는 :

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

을하는 괜찮습니다 최상위 레벨 Object를 사용한 응답. 당신은 어떤 키의 숫자 또는 문자열을 포함 할 수있는 문제가 JSON가있는 경우

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

, 당신은없이 객체를 디코딩 할 수 있습니다

대신 다음과 같은 코드를 사용, 최상위 배열은 JSON 응답을 디코딩하는 방법 해당 속성을 해독 한 후 해당 속성을 수동으로 설정하십시오.

예를 들어, Vehicle 클래스의 내부에 HistoryItem이 있습니다. Vehiclemodel_year에는 String 또는 비어 있지 않은 Int이 비어있을 수 있습니다. 여기에서 modelYear을 수동으로 NSDictionary을 사용하여 디코딩하고 Int을 얻으려고합니다. Swift 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) 
} 

HistoryItem 내부에 포함되어 내 Vehicle 클래스 :

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" 
    } 
} 

보시다시피, CodingKeys에는 model_year 키가 없습니다.