1

I am trying to fetch the subscription data from Wundergraph server by using URLSession to make network requests and handle the responses by enabling httpShouldUsePipelining. Here is my code

    class SubscriptionNetworkManager{
    
    private var request: URLRequest!
    
    public init(_ url: String,
                withURLParameter jsonObject: [String: Any]) {
        
        guard let jsonData = try? JSONSerialization.data(withJSONObject: jsonObject, options: []),
              let jsonString = String(data: jsonData, encoding: .utf8),
              var urlComponents = URLComponents(string: url)
        else {
            return
        }
        
        urlComponents.queryItems = [URLQueryItem(name: "wg_variables", value: jsonString)]
        
        if let finalUrl = urlComponents.url {
            self.request = URLRequest(url: finalUrl)
            print(finalUrl )
        }
        
        self.request.httpMethod = HttpMethod.get.rawValue
        self.request.httpShouldUsePipelining = true
        
        if let accessToken = UserDefaults.accessToken {
            
            let tempHeader = [
                "Authorization": "Bearer \(accessToken)"
            ]
            
            self.request.allHTTPHeaderFields = tempHeader
            
            let encoder = JSONEncoder()
            if let jsonData = try? encoder.encode(tempHeader) {
                let jsonString = String(data: jsonData, encoding: .utf8) ?? ""
                print("headers:-> ", jsonString)
            }
        } else {
            fatalError("No Header!!!")
        }
    }
    
    // Fetch data from specified url
    func fetchData<T: Codable>(withCompletion completion: @escaping (T) -> Void,
                               withCompletionWithError errors: @escaping (String) -> Void) {
        
        URLSession.shared.dataTask(with: self.request) { (data, response, error) in
            DispatchQueue.main.async {
                
                if let error = error {
                    let errorMessage = error.localizedDescription
                    errors(errorMessage)
                    return
                }
                
                guard let data = data else {
                    let errorMessage = error?.localizedDescription ?? "Failed to fetch courses"
                    errors(errorMessage)
                    return
                }
                
                self.printOutResponse(data: data, response: response)
                
                do {
                    let decodedData = try JSONDecoder().decode(T.self, from: data)
                    completion(decodedData)
                } catch {
                    errors("Error decoding data: \(error)")
                }
            }
        }.resume()
    }
    
    // MARK: Print Response from API
    private func printOutResponse(data: Data, response: URLResponse?) {
        // for printing response
        do {
            
            let json = try JSONSerialization.jsonObject(with: data, options: [])
            print(json)
        } catch {
            print(error)
        }
        
        guard let httpResponse = response as? HTTPURLResponse else { return }
        let statusCode = httpResponse.statusCode
        print("Status Code =>", statusCode)
    }
}

I have called through

let url = Urls.baseUrl + "protected/SubscribeToConversationsByChannelId"
let object = ["channel_id": "d111350f-80cb-4fab-beaa-84c090717d2f"]
    SubscriptionNetworkManager.init(url,
                                    withURLParameter: object).fetchData() { (response: ProtectedSubscribeToConversationsByChannelIdResponseDataHasuraMochiConversations) in
        print(response)
    } withCompletionWithError: { error in
        print(error)
    }
    

I repeatedly get timeout error here is the detail error

    Task <D5C6F257-DEF4-491C-89C4-77425227490A>.<4> finished with error [-1001] Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={_kCFStreamErrorCodeKey=-2102, NSUnderlyingError=0x2824b8c90 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <D5C6F257-DEF4-491C-89C4-77425227490A>.<4>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <D5C6F257-DEF4-491C-89C4-77425227490A>.<4>"
), NSLocalizedDescription=The request timed out.,

But when I tried through Postman, by providing same params, and header, I get status code 200. Here is my postman Screenshot. enter image description here Then from postman I can find cURL under Code snippet, by paste cURL on terminal, after updating server, I can see real time data in terminal. Currently, We are using WunderGraph Server. I tried a lot but can't able to fix it out. Can anyone help me to solve this issue?

Amrit Tiwari
  • 922
  • 7
  • 21
  • Look carefully at the URL you are trying to connect to. 404 is not found, so your URL isn't correct. – Paulw11 Apr 27 '23 at 05:39
  • 1
    Can you just check when you are making the URL `Urls.baseUrl + "protected/SubscribeToConversationsByChannelId"` is it adding the path component I mean the `/` between the base url and the path. – vignesh Apr 27 '23 at 05:54
  • Since the URL worked in `curl` in the terminal, carefully compare `curl` URL with the one from `print(finalURL)`... my first suspicion is a URL encoding issue that Postman is fixing for you. – Chip Jarred Apr 27 '23 at 05:54
  • The URL I am using is correct. I tried without URL encoding as well, but didn't work – Amrit Tiwari Apr 27 '23 at 06:10
  • If I send normal URL then it will work but create an error for Subscribe URL – Amrit Tiwari Apr 27 '23 at 06:12
  • @vignesh Yes I have `/` is at the end of my baseUrl – Amrit Tiwari Apr 27 '23 at 06:33
  • Can you print out `self.request` before you make the request so we can see the full request. – OneCommentMan Apr 27 '23 at 06:47
  • Sorry, My bad actually I missed `/`, but after fixing that issue i can't get success I got an error of `Task .<4> finished with error [-1001] Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={_kCFStreamErrorCodeKey=-2102, NSUnderlyingError=0x2824b8c90 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .` – Amrit Tiwari Apr 27 '23 at 06:54
  • 1
    Seeing the error of timeout, and in the POSTMAN screenshot that it took ~140s, change the timeout fo your request, since the default timeout is 60 seconds. – Larme Apr 27 '23 at 08:16
  • @Larme Postman will give `result less than 5s`. It's actually I took late screenshot. I have just updated a new screenshot please have a look. – Amrit Tiwari Apr 27 '23 at 10:14
  • @AmritTiwari you are not holding this object `SubscriptionNetworkManager.init` which might be getting deallocated before the api response reaches and therefore the request was getting cancelled, I am just guessing this. Hope you would accept the answer as your original question was resolved. – vignesh Apr 27 '23 at 10:26
  • @vignesh I tried by using making class variable which is not deallocated until the viewController which I am in. But I still get an timeout error. Actually, my initially problem was timeout issue, But while I create a project I missed `/` and I paste that code here. But after you told, I just realised and correct it. But my problem is not solved. Hope you understand. Thank you for your effort. Please help me to solve this issue. – Amrit Tiwari Apr 27 '23 at 11:25
  • 1
    Still no want to test by increasing the time out? – Larme Apr 27 '23 at 12:33
  • The 1st question was about api failure with error 404, now it’s about timeout we should not club the question or change the question on the go, any way as @Larme suggested you can try with setting time out and share the result here. – vignesh Apr 27 '23 at 17:42
  • @Larme I increase time as `configuration.timeoutIntervalForRequest = 90` and `configuration.timeoutIntervalForResource = 90` still I got, timeout error. Thank you for helping to solve my issue. – Amrit Tiwari Apr 28 '23 at 07:41

1 Answers1

0

Posting the answer based on the discussion in comments:

Issue was with code Urls.baseUrl + "protected/SubscribeToConversationsByChannelId" where the / was missing when the path component was added to the base URL.

Solution:

Urls.baseUrl + "/protected/SubscribeToConversationsByChannelId"
vignesh
  • 994
  • 10
  • 12