Home > OS >  Can't Perform a URL Request SWIFT
Can't Perform a URL Request SWIFT

Time:11-02

I am trying to make an API call but it throws me a status code of 401 (which is unauthorized client response) I can't access to there JSON Data. I have tried my API Key trough the PostMan data is being represented. Maybe I am missing something.

MARK: - Error Example Status code should be 2xx but is 401 - status Code representation is based on bellow.

guard response.statusCode >= 200 && response.statusCode < 300 else {
            print("Status code should be 2xx but is \(response.statusCode)")
            return
        }

MARK: - My code

   func fetchDat() {

    guard let url = URL(string: "https://odds.p.rapidapi.com/v1/sports") else { return }

    var request = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
    request.httpMethod = "GET"
    request.setValue("c15b711e56msh05b5f41ea7d8e5dp1b1b56jsne1f975246c84", forHTTPHeaderField: "x-rapidapi-key")
    
    downloadData(fromURL: url) { returnedData in
        if let data = returnedData {
            //MARK: - JSON Decoder
            guard let newPosts = try? JSONDecoder().decode([Result].self, from: data) else { return }
                DispatchQueue.main.async { [weak self] in
                    self?.res = newPosts
                }
        } else {
            print("No data returned")
        }
    }
    
}

func downloadData(fromURL url: URL, completionHandler: @escaping(_ data: Data?) -> Void) {
    
    //MARK: - URL Session Error, data, Response Handler
    URLSession.shared.dataTask(with: url) { (data, response, error) in
        
        //MARK: - More Recommended Method
        guard
            let data = data,
            error == nil,
            let response = response as? HTTPURLResponse,
                response.statusCode >= 200 && response.statusCode < 300 else {
            print("Error Downloading Data")
            completionHandler(nil)
            return
            }
    completionHandler(data)
        }.resume()
    
    }

}

Bellow MARK: - Rapid API NSURLSESSION access Template

import Foundation

let headers = [
    "x-rapidapi-host": "odds.p.rapidapi.com",
    "x-rapidapi-key": "c15b711e56msh05b5f41ea7d8e5dp1b1b56jsne1f975246c84"
]

let request = NSMutableURLRequest(url: NSURL(string: "https://odds.p.rapidapi.com/v1/sports")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
        print(error)
    } else {
        let httpResponse = response as? HTTPURLResponse
        print(httpResponse)
    }
})

dataTask.resume()

You may refer to a screenshot bellow that my POSTMAN header is working and the link itself is working.

enter image description here

I have Updated my code and now it looks like this:

func fetchDat() {
        
        
//        guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { return }
        guard let url = URL(string: "https://odds.p.rapidapi.com/v1/sports") else { return }
        var request = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
        request.httpMethod = "GET"
        request.setValue("c15b711e56msh05b5f41ea7d8e5dp1b1b56jsne1f975246c84", forHTTPHeaderField: "x-rapidapi-key")
        request.setValue("odds.p.rapidapi.com", forHTTPHeaderField: "x-rapidapi-host")
        
            URLSession.shared.dataTask(with: request) { (data, response, error) in

     
                guard let data = data else {
                    print("No Data.")
                    return
                }
                
                guard error == nil else  {
                    print("Error: \(String(describing: error))")
                    return
                }
                guard let response = response as? HTTPURLResponse else {
                    print("Invalid Response")
                    return
                }
                guard response.statusCode >= 200 && response.statusCode < 300 else {

                print("Status code should be 2xx but is \(response.statusCode)")
                            
                        return
                    }
                    
                    guard let newPosts = try? JSONDecoder().decode([Result].self, from: data) else { return }
                    DispatchQueue.main.async { [weak self] in
                        self?.res = newPosts
                    }
    }.resume()
}
        
    }

CodePudding user response:

You are setting request.setValue("API KEY", forHTTPHeaderField: "Authorization"). However, in the example code, the API is expecting your API Key under the name x-rapidapi-key. Thus request.setValue("API KEY", forHTTPHeaderField: "x-rapidapi-key") should work. Of course do not forget to properly insert your own Key into the placeholder.

  • Related