Search code examples
iosswift

Swift 5: The given data was not valid JSON (Loading Data from API to Table View)


I'm trying to GET some data from an API. It fetches the data fine when I connect the function to an IBAction, but it doesn't work when I execute it at viewDidLoad() as a normal function.

I was hoping to generate it as the app loads up so that I can display them to a table view instead of having to click a button in order to load it every time.

I get an error after attempting to execute the function from viewDidLoad():

"The given data was not valid JSON"

Below are the codes for reference:

struct Claims: Decodable {
    let id: Int
    let submission_date: String
    let status: String
    init(json: [String:Any]) {
        id = json["id"] as? Int ?? -1
        submission_date = json["submission_date"] as? String ?? ""
        status = json["status"] as? String ?? ""
    }
}

class DashboardController: UIViewController, GIDSignInUIDelegate {
    
    var claimSummaryArray: [ClaimProperties] = []
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
        
    override func viewDidLoad() {
        getData()
    }

    func getData() {
        guard let urlString = URL(string: "https://claim.ademo.work/claims/") else { return }
        var requestAPI = URLRequest(url: urlString)
                
        requestAPI.httpMethod = "GET"
        requestAPI.addValue("application/json", forHTTPHeaderField: "Content-Type")
        requestAPI.addValue("application/json", forHTTPHeaderField: "Accept")
        requestAPI.setValue("Bearer \(appDelegate.userAppToken)", forHTTPHeaderField: "Authorization")
        
        let task = URLSession.shared.dataTask(with: requestAPI) { (data, response, error) in
            if let data = data {
                do {
                    let json = try JSONDecoder().decode([Claims].self, from: data)
                    print (json)
                } catch let error {
                    print("Seems to have an error: \(error)")
                }
            }
        }
        task.resume()
    }
}

Data variable that is returned (performed via IBAction / clicking a button):

[ClaimApp.Claims(id: 1, submission_date: "2020-02-28T13:50:41.000+08:00", status: "pending"), ClaimApp.Claims(id: 2, submission_date: "2020-02-28T13:53:38.000+08:00", status: "pending"), ClaimApp.Claims(id: 3, submission_date: "2020-02-28T14:21:46.000+08:00", status: "pending"), ClaimApp.Claims(id: 4, submission_date: "2020-02-28T14:22:07.000+08:00", status: "pending")]

Error that is returned (performed via calling a normal function from viewDidLoad()):

Seems to have an error:
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))

P.S/ I'm new here, apologies if there are any misunderstanding or confusion.


Solution

  • I think your appToken is invalid when viewDidLoad run. I see your controller is Dashboard and you get token from file so have you read it async? So you should check token have already set on appDelegate before DashboardController call viewDidLoad. Let debug or print log to see what coming first.

    If token have set after DashboardController call viewDidLoad i think you need do some loading before call that controller.