简体   繁体   中英

Swift 5 Json parsing error "dataCorrupted"

I tried every solution but none of them resolved my problem getting below error while parsing. can anybody find the fault in this code

Error serializing json: dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Unable to convert data to string around character 2643." UserInfo={NSDebugDescription=Unable to convert data to string around character 2643.})))

struct Facts:Codable {
    let title: String
    let rows: [Rows]
}
struct Rows:Codable {
    var title: String
    var description: String
    var imageHref: String
}


class ViewController: UIViewController {


    override func viewDidLoad() {
        super.viewDidLoad()

        let jsonUrlString = "https://dl.dropboxusercontent.com/s/2iodh4vg0eortkl/facts.json"

        guard let url = URL(string: jsonUrlString) else{return}
        URLSession.shared.dataTask(with: url) { (data, response, error) in

            guard let data = data else { return }

            do{
                let facts = try JSONDecoder().decode(Facts.self, from: data)
                print(facts)

            }catch let jsonErr{
                print("Error serializing json:", jsonErr)
            }
        }.resume()

    }

}

// problem in response type and encoding. It should be application/json and //unicode but actually it is: //response content-type: text/plain; charset=ISO-8859-1


struct Facts:Codable {
    let title: String
    let rows: [Rows]!
}
struct Rows:Codable {
    var title: String?
    var description: String?
    var imageHref: String?
}


class ViewController: UIViewController {


    override func viewDidLoad() {
        super.viewDidLoad()

        let jsonUrlString = "https://dl.dropboxusercontent.com/s/2iodh4vg0eortkl/facts.json"

        guard let url = URL(string: jsonUrlString) else{return}
//        var request = URLRequest(url: url)
//        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")  // the request is JSON
//        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")        // the expected response is also JSON


        URLSession.shared.dataTask(with: url) { (data, response, error) in
        guard let data = data else { return }
        guard let string = String(data: data, encoding: String.Encoding.isoLatin1) else { return }
        guard let properData = string.data(using: .utf8, allowLossyConversion: true) else { return }
        do{
        let facts = try JSONDecoder().decode(Facts.self, from: properData)
        //dump(facts)
            print(facts.title)
            for row in facts.rows {
            print(row.title ?? "no title")
            print(row.description ?? "no description")
            print(row.imageHref ?? "no img url")
            print("---")



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


    }

}    

I have solved this problem by doing one extra step: First convert the data in to string which we get in closures then again convert this string to data back and this will 100% work.

    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)

    guard let request = requestObj.request else {
        return
    }
    
    let task = session.dataTask(with: request) { (data, response, error) in
        if let data = data {
            let str = String(decoding: Data(data), as: UTF8.self)
            **if let data = str.data(using: String.Encoding.utf8 ) {**
                
                if error != nil {
                    if let err = error as NSError? {
                        failure(err)
                    }
                }
                
                if let httpResponse = response as? HTTPURLResponse {
                    let code = httpResponse.statusCode
                    switch code {
                    case HttpStatusCode.success:
                        success(data)
                    default:
                        failure(NSError(domain: "", code: code, userInfo: [NSLocalizedDescriptionKey: "Something went wrong"]))
                    }
                }
            }
        }
    }
    // execute the HTTP request
    task.resume()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM