1
votes

i am decoding JSON (Decoder) string from URL repsonse as follows and get a get during the decoding process the following error messages:

Error:

typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "tags", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "Expected to decode String but found a number instead.", underlyingError: nil))

Structure:

struct Wordpress: Codable {
    let id: Int?
    let date: String?
    let date_gmt: String?
    let guid: GUID?
    let modified: String?
    let modified_gmt: String?
    let slug: String?
    let status: String?
    let type: String?
    let link: String?
    let title: Title?
    let content: Content?
    let excerpt: Excerpt?
    let author: Int?
    let featured_media: Int?
    let comment_status: String?
    let ping_status: String?
    let sticky: Bool?
    let template: String?
    let format: String?
    let meta: [String]?
    let categories: [Int]?
    let tags: [String]?
    let _links: Link?

    enum CodingKeys: String, CodingKey {
        case id = "id"
        case date = "date"
        case date_gmt = "date_gmt"
        case guid = "guid"
        case modified = "modified"
        case modified_gmt = "modified_gmt"
        case slug = "slug"
        case status = "status"
        case type = "type"
        case link = "link"
        case title = "title"
        case content = "content"
        case excerpt = "excerpt"
        case author = "author"
        case featured_media = "featured_media"
        case comment_status = "comment_status"
        case ping_status = "ping_status"
        case sticky = "sticky"
        case template = "template"
        case format = "format"
        case meta = "meta"
        case categories = "categories"
        case tags = "tags"
        case _links = "_links"
    }
}

struct GUID: Codable{
    let rendered: String?
}

struct Title: Codable{
    let rendered: String?
}

struct Content: Codable{
    let rendered: String?
    let protected: Bool?
}

struct Excerpt: Codable{
    let rendered: String?
    let protected: Bool?
}

struct Link: Codable {
    let urls: [URLString]?
    let collection: [Collection]?
    let about: [About]?
    let author: [Author]?
    let replies: [Replies]?
    let versionHistory: [Version]?
    let predecessorVersion: [Predecessor]?
    let wpFeaturedmedia: [Featured]?
    let wpAttachment: [Attachment]?
    let wpTerm: [Term]?
    let curies: [Curies]?

    enum CodingKeys: String, CodingKey {
        case urls = "urls"
        case collection = "collection"
        case about = "about"
        case author = "author"
        case replies = "replies"
        case versionHistory = "version-history"
        case predecessorVersion = "predecessor-version"
        case wpFeaturedmedia = "wp:featuredmedia"
        case wpAttachment = "wp:attachment"
        case wpTerm = "wp:term"
        case curies = "curies"
    }
}

struct About: Codable{
    let href : String?
}

struct Author: Codable {
    let embeddable: Bool?
    let href : String?
}

struct Replies: Codable {
    let embeddable: Bool?
    let href : String?
}

struct Version: Codable {
    let count: Int?
    let href : String?
}

struct Predecessor: Codable {
    let id: Int?
    let href : String?
}
struct Featured: Codable {
    let embeddable: Bool?
    let href : String?
}

struct Attachment: Codable{
    let href : String?
}

struct Term: Codable {
    let taxonomy: String?
    let embeddable: Bool?
    let href: String?
}

struct Curies: Codable {
    let name: String?
    let href: String?
    let templated: Bool?
}

My decode code:

class func path_getPosts(per_page:Int) -> URL {
        let s = APIwp.base + APIwp.posts + APIwp.per_page + "\(per_page)"
        print(s)
            return URL(string: s)!

        }


    static func getPosts(for per_page: Int, completion: @escaping ([Wordpress], Error?) -> Void) {
        taskGetPosts(url: path_getPosts(per_page: per_page), responseType: [Wordpress].self) { (response, error) in
                if let response = response {
                    completion(response, nil)
                } else {
                    completion([], error)
                }
            }
        }

    @discardableResult static func taskGetPosts<ResponseType: Decodable>(url: URL, responseType: ResponseType.Type, completion: @escaping (ResponseType?, Error?) -> Void) -> URLSessionDataTask {
        let task = URLSession.shared.dataTask(with: url) { (data, response, error)
            in
            guard let data = data else {
                DispatchQueue.main.async {
                    completion(nil, error)
                }
            return
            }

            let decoder = JSONDecoder()
            do {
                let responseObject = try decoder.decode(ResponseType.self, from: data)
                DispatchQueue.main.async { completion(responseObject, nil) }
            } catch let jsonErr {
                print("Error:=: \(jsonErr)")
                DispatchQueue.main.async { completion(nil, error) }
            }
        }
        task.resume()
        return task
    }
1
show json that you are trying to parse ? - Jawad Ali
its saying let tags: [String]? are not strings ... they are numbers ... - Jawad Ali
Your codable is trying to parse the value of tags as array of strings, but the actual tags is an array of int(number). So you may have to typecast the tags to array of string. - iamyogish

1 Answers

6
votes

Please read the error message carefully.

It tells you that the first item (_JSONKey(stringValue: "Index 0", intValue: 0)) in the array for key tags (CodingKeys(stringValue: "tags", intValue: nil) in the first item of the root object (_JSONKey(stringValue: "Index 0", intValue: 0) is not a string, it's a number (Expected to decode String but found a number instead).

So tags is probably [Int]