Home > Software design >  errors in swift Value of type 'URLSession' has no member 'request'
errors in swift Value of type 'URLSession' has no member 'request'

Time:11-12

I am receiving three errors in my viewController and I can not figure out how to fix them these errors are 1.) extension Declaration is only valid at file scope, 2.)Value of type 'Unable to infer type of a closure parameter 'result' in the current context ' 3.) URLSession has no member 'request'. None of these errors make any sense to me because I have already defined result as a member of URLSession. Im not sure if Xcode is glitching, or if these errors are present in my code and if so can anyone point them out and how to fix?

import UIKit
import Foundation

enum NetworkError: Error {
    case badRequest
    case decodingError 
}

struct  Category: Codable  {
    let   CategoryId: String
    let  CategoryThumb: String
    let  CategoryDescription: String
    let categories: [Category]
    
    class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
        struct Constants {
            
            
            static let categoriesurl = URL(string: "https://www.themealdb.com/api/json/v1/1/categories.php")
            static let filterListurl = URL(string: "https://www.themealdb.com/api/json/v1/1/filter.php?c=Beef")
            static let mealByIdurl = URL(string: "https://www.themealdb.com/api/json/v1/1/lookup.php?i=52874")
        }
        
        //create table view to test results from API endpoint
        let table: UITableView = {
            let table = UITableView()
            table.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
            return table
        }()
        private var categories: [Category] = []
        override func viewDidLoad() {
            super.viewDidLoad()
            view.addSubview(table)
            table.delegate = self
            table.dataSource = self
            fetch()
        }
        override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
            table.frame = view.bounds
        }
        
        func fetch() {
            
            URLSession.shared.request(url: Constants.categoriesurl, returning: [Category].self
            ) {[weak self] result in
                switch result {
                case.success(let category):
                    DispatchQueue.main.async {
                        self?.category = category
                        self?.table.reloadData()
                    }
                case.failure(let error):
                    print(error )
                }
                
            }
            
        }
        
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return categories.count
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = table.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.text = categories[indexPath.row].CategoryId
            return cell
        }
    }
    extension URLSession {
        
        func request<T: Codable>(url: URL?,returning: T.Type,completion: @escaping (Result<T, Error>) -> Void) {
            guard let url = url else {
                
                //we create a enum for network error that will return an error if the API end point is a bad request,or if unable decoding the  Json data
                //Create a urls that fetches the data from each API end points
                
                NetworkError.badRequest
                return
            }
            
            let task = dataTask(with: url) {data, _, error in
                guard let data = data else {
                    if let  error = error {
                        NetworkError.badRequest
                    } else {
                        
                        NetworkError.decodingError
                    }
                    return
                }      //if your data is return sucessfully from the API
                do {
                    let Result = try! JSONDecoder().decode(returning, from: data)
                    completion(.success(Result))
                }
                catch {
                    NetworkError.badRequest
                } //if the data does not return an error will be met
                
            }
            task.resume()
        }
    }
}

CodePudding user response:

  1. You're declaring an extension within the scope of a struct declaration. Your extension has to be declared outside of any other scope.

  2. Because you extension was rejected, The system doesn't know what kind of parameter request should take and since you haven't declared the type of result inside the closure, it has no way to infer what what type it should have and the error message tells you just that

  3. URLSession does not have a member named request because your extension was rejected (because of error #1).

The first step to fix this would be to move your extension outside of the scope of struct Category

CodePudding user response:

  1. extension Declaration is only valid at file scope - Extension go inside a struct or a class, here you are declaring urlSession extension inside Category struct, please declare it outside.
  2. Value of type 'Unable to infer type of a closure parameter 'result' in the current context ' - Please let us know the line of error, mostly this type of error would require to handle do-try-catch.
  3. When the extension is placed outside the struct, this error would go.
  • Related