breath abel
breath abel

Reputation: 31

Could not cast value of type 'Swift.String' (0x10fef45c0) to 'Swift.Error' (0x10ff2bd10). (lldb)

Below line of code is producing the error,

DispatchQueue.main.async { completion(.success(jsonData), Error as! Error) }

When print jsonData This code returns perfect result of array but getting this error,

Could not cast value of type 'Swift.String' (0x10fef45c0) to 'Swift.Error' (0x10ff2bd10). (lldb)

As the error says I understand its a cast exception, but I'm not able to modify the code to make it work. I'm kinda new to Swift, so any help would be appreciated. Below is my

import Foundation

class APIService {
    
    private var dataTask: URLSessionDataTask?
    
    func getPopularPosts(completion: @escaping (Result<Any, Error>, Error) -> Void) {
        
        let popularURL = "URL Here"
        
        guard let url = URL(string: popularURL) else {return}
        
        // Create URL Session - work on the background
        dataTask = URLSession.shared.dataTask(with: url) { (data, response, error) in
            
            // Handle Error
            if let error = error {
                completion(.failure(error), Error.self as! Error)
                print("DataTask error: \(error.localizedDescription)")
                return
            }
            
            guard let response = response as? HTTPURLResponse else {
                // Handle Empty Response
                print("Empty Response")
                return
            }
            print("Response status code: \(response.statusCode)")
            
            guard let data = data else {
                // Handle Empty Data
                print("Empty Data")
                return
            }
            
            do {
                // Parse the data
                let decoder = JSONDecoder()
                let jsonData = try decoder.decode(APIService.self, from: data)
               // print(jsonData)
                // Back to the main thread
                DispatchQueue.main.async {
                    completion(.success(jsonData), Error as! Error)
                }
            } catch let error {
                completion(.failure(error),error)
            }
            
        }
        dataTask?.resume()
    }
}

Upvotes: 0

Views: 863

Answers (1)

Frankenstein
Frankenstein

Reputation: 16341

Modify the completion block parameters, you already are returning the error inside the Result's .failure(Error) block so no need to repeat it again as another parameter in the completion parameter. Here's how you fix this:

Declaration:

class APIService {

    private var dataTask: URLSessionDataTask?

    func getPopularPosts(completion: @escaping (Result<CategoriesNewsData, Error>) -> Void) {
        let popularURL = "URL Here"
        guard let url = URL(string: popularURL) else {return}

        // Create URL Session - work on the background
        dataTask = URLSession.shared.dataTask(with: url) { (data, response, error) in

            // Handle Error
            if let error = error {
                completion(.failure(error))
                print("DataTask error: \(error.localizedDescription)")
                return
            }

            guard let response = response as? HTTPURLResponse else {
                // Handle Empty Response
                print("Empty Response") // Throw a custom error here too.
                return
            }
            print("Response status code: \(response.statusCode)")

            guard let data = data else {
                // Handle Empty Data
                print("Empty Data") // Throw a custom error here too.
                return
            }
            do {
                let decoder = JSONDecoder()
                let jsonData = try decoder.decode(CategoriesNewsData.self, from: data)
                DispatchQueue.main.async {
                    completion(.success(jsonData))
                }
            } catch let error {
                completion(.failure(error))
            }
        }
        dataTask?.resume()
    }
}

Calling:

service.getPopularPosts { result in
    switch result {
    case .success(let categoriesNewsData):
        print(categoriesNewsData)
    case .failure(let error):
        print(error)
    }
}

Upvotes: 1

Related Questions