title: Why is async method throwing an error when decoding JSON data from an API request? Swift
body: <h1>Tldr:</h1>
  <p>*Update: Updated code and post body.</p>
  <p>I’m trying to show a table view in a new view controller, but I keep getting an error thrown from the async method <code>searchBusinesses</code> in the <code>YelpApi</code> class in <code>FetchData.swift</code>.</p>
  <p>I’ve printed the JSON response after <code>let (data, _) = try await URLSession.shared.data(for: request)</code> in <code>FetchData.swift</code>, however, the response looks fine/there doesn’t seem to be any errors or indications of a problem in it (a snippet of this response is at the bottom of the <code>Returned Print Statement</code> &quot;file&quot; at the bottom of this post).</p>
  <p>I've also printed the error description message at the bottom of this post in the <code>Returned Print Statement</code> &quot;file&quot;.</p>
  <p>Main thing I think the problem is related to:</p>
  <p>-Code wrong somehow in code for decoding data from API request in line of code: <code>let businessResults = try JSONDecoder().decode(BusinessSearchResult.self, from: data)</code> in <code>searchBusinesses</code> method in <code>FetchData.swift</code>.</p>
  <hr />
  <h1>Rest of post, including all code “files”:</h1>
  <p>This is a follow-up to the following question: <a href="https://stackoverflow.com/questions/72511642/why-isn-t-the-table-view-from-a-new-view-controller-not-showing-swift">Why isn’t the table view from a new View Controller not showing? Swift</a>.</p>
  <p>I’m trying to show a table view in a new view controller, but I keep getting an error thrown from the async method <code>searchBusinesses</code> in the <code>YelpApi</code> class in <code>FetchData.swift</code>.</p>
  <p>I also looked this problem up online, and re-read the documentation for the following topics (with the exception of JSONDecoder(); first time reading it), and still could not identify the problem:</p>
  <p>-Error Handling <a href="https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html" rel="nofollow noreferrer">https://docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html</a></p>
  <p>-URLSession <a href="https://developer.apple.com/documentation/foundation/urlsession" rel="nofollow noreferrer">https://developer.apple.com/documentation/foundation/urlsession</a></p>
  <p>-JSONDecoder() <a href="https://developer.apple.com/documentation/foundation/jsondecoder" rel="nofollow noreferrer">https://developer.apple.com/documentation/foundation/jsondecoder</a></p>
  <p><strong>I think the problem could be:</strong></p>
  <p>-The function for generating the <code>openAt</code> time parameter returns a value that somehow causes an error during the API request, and/or when decoding the data. However the print statements within this function for generating the <code>openAt</code> time indicates that the code within this function is working as it should.</p>
  <p>-Code wrong somehow when making the API request in line of code: <code>let (data, _) = try await URLSession.shared.data(for: request)</code> in <code>searchBusinesses</code> method (in the <code>YelpApi</code> class in <code>FetchData.swift</code>).</p>
  <p>-Code wrong somehow in code for decoding data from API request in line of code: <code>let businessResults = try JSONDecoder().decode(BusinessSearchResult.self, from: data)</code> in <code>searchBusinesses</code> method.</p>
  <p>*Note about code changes: I had recently changed the <code>location</code> property in my <code>Venues</code> struct which conforms to <code>Codable</code> to <code>locationOfRestaurant</code> and had forgot to update the code &quot;file&quot; here to reflect that. After receiving errors after this change, I've since changed it back to <code>location</code>. *The error description message at the bottom of this post referred to this <code>locationOfRestaurant</code> property.</p>
  <p><strong>Code:</strong></p>
  <p><code>InitialViewController.swift</code>:</p>
  <pre><code>//*Code for creating a table view that shows options to the user, for the user to select.*
  
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
          
          //*Code for assigning values to variables related to what row in the table view the user selected.*
          
          
          let storyboard = UIStoryboard(name: &quot;Main&quot;, bundle: nil)
          let newVC = storyboard.instantiateViewController(identifier: &quot;NewViewController&quot;) as! NewViewController
          newVC.modalPresentationStyle = .fullScreen
          newVC.modalTransitionStyle = .crossDissolve
          
          //Print Check.
          //Prints.
          print(&quot;Print Check: Right before code for presenting the new view controller.&quot;)
  
          navigationController?.pushViewController(newVC, animated: true)
          
      }
  </code></pre>
  <p><code>NewViewController.swift</code>:</p>
  <pre><code>import UIKit
  import CoreLocation
  
  class NewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
      
      //Print Check.
      //Prints.
      func printCheckBeforeIBOutletTableViewCode() {
          print(&quot;Print Check: Right before tableView IBOutlet code at top of NewViewController.swift file.&quot;)
      }
      
      @IBOutlet var tableView: UITableView!
      
      var venues: [Venue] = []
      
      //Print Check.
      //Prints.
      func printCheckAfterIBOutletTableViewCode() {
          print(&quot;Print Check: Right after tableView IBOutlet code at top of NewViewController.swift file.&quot;)
      }
      
      override func viewDidLoad() {
          super.viewDidLoad()
          
          //Function calls for print checks.
          //Prints.
          self.printCheckBeforeIBOutletTableViewCode()
          self.printCheckAfterIBOutletTableViewCode()
          
          tableView.register(UINib(nibName: &quot;CustomTableViewCell&quot;, bundle: nil), forCellReuseIdentifier: &quot;CustomTableViewCell&quot;)
          tableView.delegate = self
          tableView.dataSource = self
          
          //Print Check.
          //Prints.
          print(&quot;Print Check: Right before creating an instance of YelpApi class, then creating a task to make the API request.&quot;)
          
          let yelpApi = YelpApi(apiKey: &quot;Api key&quot;)
          
          Task {
              do {
                  self.venues = try await yelpApi.searchBusiness(latitude: selectedLatitude, longitude: selectedLongitude, category: &quot;category query goes here&quot;, sortBy: &quot;sort by query goes here&quot;, openAt: functionForGeneratingOpenAtParameter())
                  self.tableView.reloadData()
              } catch {
                      //Handle error here.
                      //Prints.
                      print(&quot;Error info for catch block in Task block in NewViewController.swift for making API request: \(error)&quot;)
              }
          }
      }
      
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
             return venues.count
         }
         
         func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
             let cell = tableView.dequeueReusableCell(withIdentifier: &quot;CustomTableViewCell&quot;, for: indexPath) as! CustomTableViewCell
             
             //Details for custom table view cell go here.
         }
             
         //Rest of table view protocol functions.
      
  }
  </code></pre>
  <p><code>Venue.swift</code>:</p>
  <pre><code>import Foundation
  
  // MARK: - BusinessSearchResult
  struct BusinessSearchResult: Codable {
      let total: Int
      let businesses: [Venue]
      let region: Region
  }
  
  // MARK: - Business
  struct Venue: Codable {
      let rating: Double
      let price, phone, alias: String?
      let id: String
      let isClosed: Bool?
      let categories: [Category]
      let reviewCount: Int?
      let name: String
      let url: String?
      let coordinates: Center
      let imageURL: String?
      let location: Location
      let distance: Double
      let transactions: [String]
  
      enum CodingKeys: String, CodingKey {
          case rating, price, phone, id, alias
          case isClosed
          case categories
          case reviewCount
          case name, url, coordinates
          case imageURL
          case location, distance, transactions
      }
  }
  
  // MARK: - Category
  struct Category: Codable {
      let alias, title: String
  }
  
  // MARK: - Center
  struct Center: Codable {
      let latitude, longitude: Double
  }
  
  // MARK: - Location
  struct Location: Codable {
      let city, country, address2, address3: String?
      let state, address1, zipCode: String?
  
      enum CodingKeys: String, CodingKey {
          case city, country, address2, address3, state, address1
          case zipCode
      }
  }
  
  // MARK: - Region
  struct Region: Codable {
      let center: Center
  }
  </code></pre>
  <p><code>FetchData.swift</code>:</p>
  <pre><code>import Foundation
  import CoreLocation
  
  class YelpApi {
      
      private var apiKey: String
      
      init(apiKey: String) {
          self.apiKey = apiKey
      }
      
      func searchBusiness(latitude: Double,
                          longitude: Double,
                          category: String,
                          sortBy: String,
                          openAt: Int?) async throws -&gt; [Venue] {
          
          var queryItems = [URLQueryItem]()
          queryItems.append(URLQueryItem(name:&quot;latitude&quot;,value:&quot;\(latitude)&quot;))
          queryItems.append(URLQueryItem(name:&quot;longitude&quot;,value:&quot;\(longitude)&quot;))
          queryItems.append(URLQueryItem(name:&quot;categories&quot;, value:category))
          queryItems.append(URLQueryItem(name:&quot;sort_by&quot;,value:sortBy))
          
          if let openAt = openAt {
              queryItems.append(URLQueryItem(name:&quot;open_at&quot;, value:&quot;\(openAt)&quot;))
          }
         
          var results = [Venue]()
          
          var expectedCount = 0
          let countLimit = 50
          var offset = 0
          
          queryItems.append(URLQueryItem(name:&quot;limit&quot;, value:&quot;\(countLimit)&quot;))
          
          //Print Check.
          //Prints.
          print(&quot;Print Check: Line before repeat-while loop.&quot;)
          
          repeat {
              
              //Print Check.
              //Prints.
              print(&quot;Print Check: Within repeat-while loop and before first line of code within it.&quot;)
              
              var offsetQueryItems = queryItems
              
              offsetQueryItems.append(URLQueryItem(name:&quot;offset&quot;,value: &quot;\(offset)&quot;))
              
              var urlComponents = URLComponents(string: &quot;https://api.yelp.com/v3/businesses/search&quot;)
              urlComponents?.queryItems = offsetQueryItems
              
              guard let url = urlComponents?.url else {
                  throw URLError(.badURL)
              }
              
              var request = URLRequest(url: url)
              request.setValue(&quot;Bearer \(self.apiKey)&quot;, forHTTPHeaderField: &quot;Authorization&quot;)
              
              //Print Check.
              //Prints.
              print(&quot;Print Check: Within repeat-while loop and before 'let (data, _) = try await' line of code.&quot;)
              let (data, _) = try await URLSession.shared.data(for: request)
              
              //Print Check for printing the JSON response.
              //Prints.
              print(String(decoding: data, as: UTF8.self))
              
              //Print Check.
              //Prints.
              print(&quot;Print Check: Within repeat-while loop and before 'let businessResults = try JSONDecoder()' line of code.&quot;)
              let businessResults = try JSONDecoder().decode(BusinessSearchResult.self, from:data)
              
              //Print Check.
              //Doesn't print.
              print(&quot;Print Check: Within repeat-while loop and right after 'let businessResults = try JSONDecoder()' line of code.&quot;)
  
              expectedCount = min(businessResults.total,1000)
              
              results.append(contentsOf: businessResults.businesses)
              offset += businessResults.businesses.count
          } while (results.count &lt; expectedCount)
          
          //Print Check.
          //Doesn't print.
          print(&quot;Print Check: After repeat-while loop and before 'return results' code.&quot;)
          
          return results
      }
  }
  </code></pre>
  <p><code>Returned Print Statements From Terminal, including the JSON response and catch block error description at the end</code>:</p>
  <pre><code>Print Check: Right before code for presenting the new view controller.
  Print Check: Right before tableView IBOutlet code at top of NewViewController.swift file.
  Print Check: Right after tableView IBOutlet code at top of NewViewController.swift file.
  Print Check: Right before creating an instance of YelpApi class, then creating a task to make the API request.
  Print statements from functionForGeneratingOpenAtParameter(). These print statements indicate the function is working as it should, and don't seem to indicate a problem.
  Print Check: Line before repeat-while loop.
  Print Check: Within repeat-while loop and before first line of code within it.
  Print Check: Within repeat-while loop and before 'let (data, _) = try await' line of code.
  Date and Time, Project Name, and some other info [boringssl] boringssl_metrics_log_metric_block_invoke(153) Failed to log metrics
  *Note only showed JSON response for a few businesses because of post character limit: {&quot;businesses&quot;: [{&quot;id&quot;: &quot;hZR-LKgsooHaN6a8L2dprg&quot;, &quot;alias&quot;: &quot;tako-cheena-orlando&quot;, &quot;name&quot;: &quot;Tako Cheena&quot;, &quot;image_url&quot;: &quot;https://s3-media4.fl.yelpcdn.com/bphoto/qj1uAI1X5wJZeSbfCQs17w/o.jpg&quot;, &quot;is_closed&quot;: false, &quot;url&quot;: &quot;https://www.yelp.com/biz/tako-cheena-orlando?adjust_creative=mgN_4fA5wlIrHQMgamUFAQ&amp;utm_campaign=yelp_api_v3&amp;utm_medium=api_v3_business_search&amp;utm_source=mgN_4fA5wlIrHQMgamUFAQ&quot;, &quot;review_count&quot;: 1709, &quot;categories&quot;: [{&quot;alias&quot;: &quot;asianfusion&quot;, &quot;title&quot;: &quot;Asian Fusion&quot;}, {&quot;alias&quot;: &quot;mexican&quot;, &quot;title&quot;: &quot;Mexican&quot;}, {&quot;alias&quot;: &quot;empanadas&quot;, &quot;title&quot;: &quot;Empanadas&quot;}], &quot;rating&quot;: 4.0, &quot;coordinates&quot;: {&quot;latitude&quot;: 28.558364, &quot;longitude&quot;: -81.3646545}, &quot;transactions&quot;: [&quot;pickup&quot;, &quot;delivery&quot;], &quot;price&quot;: &quot;$&quot;, &quot;location&quot;: {&quot;address1&quot;: &quot;948 N Mills Ave&quot;, &quot;address2&quot;: &quot;&quot;, &quot;address3&quot;: &quot;&quot;, &quot;city&quot;: &quot;Orlando&quot;, &quot;zip_code&quot;: &quot;32803&quot;, &quot;country&quot;: &quot;US&quot;, &quot;state&quot;: &quot;FL&quot;, &quot;display_address&quot;: [&quot;948 N Mills Ave&quot;, &quot;Orlando, FL 32803&quot;]}, &quot;phone&quot;: &quot;+14077570626&quot;, &quot;display_phone&quot;: &quot;(407) 757-0626&quot;, &quot;distance&quot;: 2650.3293007456186}, {&quot;id&quot;: &quot;KlZAG6XPK0GFLAZHkuUPNA&quot;, &quot;alias&quot;: &quot;wawa-winter-park&quot;, &quot;name&quot;: &quot;Wawa&quot;, &quot;image_url&quot;: &quot;https://s3-media1.fl.yelpcdn.com/bphoto/r5-YgTXO0ez_syOSNq9Uhg/o.jpg&quot;, &quot;is_closed&quot;: false, &quot;url&quot;: &quot;https://www.yelp.com/biz/wawa-winter-park?adjust_creative=mgN_4fA5wlIrHQMgamUFAQ&amp;utm_campaign=yelp_api_v3&amp;utm_medium=api_v3_business_search&amp;utm_source=mgN_4fA5wlIrHQMgamUFAQ&quot;, &quot;review_count&quot;: 44, &quot;categories&quot;: [{&quot;alias&quot;: &quot;servicestations&quot;, &quot;title&quot;: &quot;Gas Stations&quot;}, {&quot;alias&quot;: &quot;coffee&quot;, &quot;title&quot;: &quot;Coffee &amp; Tea&quot;}, {&quot;alias&quot;: &quot;sandwiches&quot;, &quot;title&quot;: &quot;Sandwiches&quot;}], &quot;rating&quot;: 4.5, &quot;coordinates&quot;: {&quot;latitude&quot;: 28.604943, &quot;longitude&quot;: -81.365896}, &quot;transactions&quot;: [&quot;pickup&quot;, &quot;delivery&quot;], &quot;price&quot;: &quot;$&quot;, &quot;location&quot;: {&quot;address1&quot;: &quot;901 N Orlando Ave&quot;, &quot;address2&quot;: &quot;&quot;, &quot;address3&quot;: &quot;&quot;, &quot;city&quot;: &quot;Winter Park&quot;, &quot;zip_code&quot;: &quot;32789&quot;, &quot;country&quot;: &quot;US&quot;, &quot;state&quot;: &quot;FL&quot;, &quot;display_address&quot;: [&quot;901 N Orlando Ave&quot;, &quot;Winter Park, FL 32789&quot;]}, &quot;phone&quot;: &quot;+14076290167&quot;, &quot;display_phone&quot;: &quot;(407) 629-0167&quot;, &quot;distance&quot;: 7550.802900576834}, 
  Print Check: Within repeat-while loop and before 'let businessResults = try JSONDecoder()' line of code.
  Error info for catch block in Task block in NewViewController.swift for making API request: keyNotFound(CodingKeys(stringValue: &quot;locationOfRestaurant&quot;, intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: &quot;businesses&quot;, intValue: nil), _JSONKey(stringValue: &quot;Index 0&quot;, intValue: 0)], debugDescription: &quot;No value associated with key CodingKeys(stringValue: \&quot;locationOfRestaurant\&quot;, intValue: nil) (\&quot;locationOfRestaurant\&quot;).&quot;, underlyingError: nil))
  </code></pre>
  <p>The relevant error message:</p>
  <blockquote>
  <p>Error info for catch block in Task block in NewViewController.swift for making API request: keyNotFound(CodingKeys(stringValue: &quot;locationOfRestaurant&quot;, intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: &quot;businesses&quot;, intValue: nil), _JSONKey(stringValue: &quot;Index 0&quot;, intValue: 0)], debugDescription: &quot;No value associated with key CodingKeys(stringValue: &quot;locationOfRestaurant&quot;, intValue: nil) (&quot;locationOfRestaurant&quot;).&quot;, underlyingError: nil))</p>
  </blockquote>
  <p>Thanks!</p>