I am trying to receive API data from Finnhub and put it in a table view.
The API data I am using is Symbol Lookup, which is an API that receives the company’s detailed name and stock symbol.
It’s API data that gets the names of all companies in the world, and I want to filter only US-related company stocks and assign them to a table view. Only US-related Company.
How to filter the data coming from the API and display on the TableView?
Here’s my code
enum CompanyDataNetworkError: Error {
case networkingError
case dataError
case parseError
}
final class CompanyDataManager {
static let shared = CompanyDataManager()
private init() {}
typealias NetworkCompletion = (Result<[CompanyDataResult], CompanyDataNetworkError>) -> Void
func fetchNetwork(searchTerm: String, completion: @escaping NetworkCompletion) {
let myAPIKey = "myAPIKey"
let urlString = "https://finnhub.io/api/v1/search?q=(searchTerm)&token=(myAPIKey)"
print(urlString)
performRequest(with: urlString) { result in
completion(result)
}
}
private func performRequest(with urlString: String, completion: @escaping NetworkCompletion) {
//print(#function)
guard let url = URL(string: urlString) else { return }
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
completion(.failure(.networkingError))
print("DEBUG: Network Error")
return
}
guard let safeData = data else {
completion(.failure(.dataError))
print("DEBUG: Data Error")
return
}
if let company = self.parseJSON(safeData) {
print("Parse Success")
completion(.success(company))
} else {
print("DEBUG: Parse Failure")
completion(.failure(.parseError))
}
}
task.resume()
}
private func parseJSON(_ companyData: Data) -> [CompanyDataResult]? {
print(#function)
do {
let companyData = try JSONDecoder().decode(CompanyData.self, from: companyData)
return companyData.result
} catch {
print(error.localizedDescription)
print("DEBUG: JSON Error")
return nil
}
}
}
import UIKit
class SearchResultHomeController: UIViewController {
var companyManager = CompanyDataManager.shared
var searchTerm: String? {
didSet {
setupDatas()
}
}
var companyArray: [CompanyDataResult] = []
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
}
}
func setupDatas() {
guard let term = searchTerm else { return }
companyManager.fetchNetwork(searchTerm: term) { result in
switch result {
case .success(let companyDatas):
self.companyArray = companyDatas
DispatchQueue.main.async {
self.tableView.reloadData()
}
case .failure(let error):
print(error.localizedDescription)
}
}
}
}
extension SearchResultHomeController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return companyArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SearchResultCell", for: indexPath) as! SearchResultCell
cell.selectionStyle = .none
cell.textLabel?.text = companyArray[indexPath.row].codeName
cell.detailTextLabel?.text = companyArray[indexPath.row].detailName
return cell
}
}
extension SearchResultHomeController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let eachStockDetailVC = EachStockDetailController()
eachStockDetailVC.searchTerm = companyArray[indexPath.row].codeName
present(eachStockDetailVC, animated: true)
}
}
I tried if error.localizedDescription == "The data couldn’t be read because it isn’t in the correct format." to make it not be included in the tableview if it is wrong api, but it didn’t work out. can anyone please help me…?
2
Answers
You can use filter to get only US companies. Try this code for example:
for US exchange stocks only, use
/stock/symbol?exchange=US
api route. Although, this doesn’t allow for search terms like the endpoint your example used, it does get you the US stocksif you want to search against US stocks, I would suggest using this path, and then creating your own simple search through the data using UISearchBar / UISearchController etc with some kind of pattern matching through the data