Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Daniel Lambrecht
seal-mask
PLUS
.a{fill-rule:evenodd;}techdegree
Daniel Lambrecht
iOS Development Techdegree Student 5,302 Points

SWIFT - APIClient / SWAPI my final class doesnt conform to my APIClient, but i cant figure out why?! please help :)

heres my API Client:

protocol APIClient {
    var configuration: URLSessionConfiguration { get }
    var session: URLSession { get }

    init(config: URLSessionConfiguration)

    func jsonTask(withRequest request: URLRequest, completion: @escaping JSONTaskCompletion) -> JSONTask
    func fetch<T: JSONDecodable>(request: URLRequest, parse: (JSON) -> T?, completion: (APIResult<T>) -> Void)
}



extension APIClient {
    func jsonTask(withRequest request: URLRequest, completion: @escaping JSONTaskCompletion) -> JSONTask {

        let task = session.dataTask(with: request, completionHandler: { data, response, error in

            guard let HTTPResponse = response as? HTTPURLResponse else {
                let userInfo = [
                    NSLocalizedDescriptionKey: NSLocalizedString("Missing HTTP Response", comment: "")
                ]

                let error = NSError(domain: TRENetworkingErrorDomain, code: MissingHTTPResponseError, userInfo: userInfo)
                completion(nil, nil, error)
                return
            }

            if data == nil {
                if let error = error {
                    completion(nil, HTTPResponse, error as NSError?)
                }
            } else {
                switch HTTPResponse.statusCode {
                case 200:
                    do {
                        let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String : AnyObject]
                        completion(json, HTTPResponse, nil)
                    } catch let error as NSError {
                        completion(nil, HTTPResponse, error)
                    }
                default: print("Received HTTP Response: \(HTTPResponse.statusCode) - not handled")
                }
            }
        })

        return task
    }

    func fetch<T>(_ request: URLRequest, parse: @escaping (JSON) -> T?, completion: @escaping (APIResult<T>) -> Void) {

        let task = jsonTask(withRequest: request) { json, response, error in

            DispatchQueue.main.async {
                guard let json = json else {
                    if let error = error {
                        completion(.failure(error))
                    } else {
                        // TODO: Implement Error Handling
                    }
                    return
                }

                if let value = parse(json) {
                    completion(.success(value))
                } else {
                    let error = NSError(domain: TRENetworkingErrorDomain, code: UnexpectedResponseError, userInfo: nil)
                    completion(.failure(error))
                }
            }
        }

        task.resume()
    }
}

and heres my Final class for the json, this class isnt done yet, but i had to restructure just to see if i could get it to work. But now i have spent 3-4 hours on this, and im still nowhere, the compiler still gives me this message:

Type "StarWarsAPIClient" does not conform to protocol "APIClient"

final class StarWarsAPIClient: APIClient {

    var configuration: URLSessionConfiguration
    lazy var session: URLSession = {
        return URLSession(configuration: self.configuration)
    }()


    init(config: URLSessionConfiguration) {
        self.configuration = config
    }

    convenience init() {
        self.init(config: URLSessionConfiguration.default)
    }

    func fetchStarWars(type: StarWarsType, completion: @escaping (APIResult<People>) -> Void) {
        let request = StarWarsType.people.request


        fetch(request, parse: { json -> People? in
            // parse from JSON response to Types

            if let typesDictionary = json as? [String : AnyObject] {
                return People(JSON: typesDictionary)
            } else {
                return nil
            }


        }, completion: completion)
    }
    }

if you can help i would be SO greatfull.

Also, it would be nice with an explanation, so that you do not just give me the answer :) I would like to learn about the topic :)

Thanks, and have a great day!