1

I'm writing a basic API call in Swift using URLRequests, and for whatever reason my call is never executed. I have multiple calls to an external server API using the same method and the functionality is just as expected, however, for my server running locally I get no response or even behavior within the dataTask closure.

I have tried any relevant solutions I could find online such as: Swift URL Session and URL Request not working and Swift 3, URLSession dataTask completionHandler not called. But none of these solutions seem to fix my issue. I know that the local API is working as any calls through Postman go through without fail, yet even after using the Swift snippet provided by Postman, I get no functionality.

func doFoo(id: String, completion: @escaping ([[Float]]) -> ()) {
    let semaphore = DispatchSemaphore(value: 0)
    
    var request = URLRequest(url: URL(string: "127.0.0.1:8080/doFoo/\(id)")!, timeoutInterval: Double.infinity)
    request.httpMethod = "GET"
    
    print("THIS IS REACHED")
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        print("THIS IS NEVER REACHED")
        guard let data = data else {
            self.semaphore.signal()
            return
        }
        do {
            // Decode json using JSONDecoder
            // Call completion with JSON data
        } catch {
             print(error)
        }
        self.semaphore.signal()
    }
    task.resume()
    self.semaphore.wait()
}

Other posts suggest that this could be an issue with the thread or execution completing before the closure is executed; while I am not super familiar with how the request executes and the behavior of semaphores, my understanding is that they are a way to request threads and prevent the above from happening.

If anyone more familiar with these topics could help me identify and understand why this issue is occurring, it would be greatly appreciated!

DeveloperRyan
  • 837
  • 2
  • 9
  • 22
  • try to set ```http://localhost:8080/doFoo/\(id)``` – Raja Kishan Jun 18 '21 at 18:20
  • This is what I had originally, and unfortunately it does not work either. I saw a post that said perhaps you need the actual address (127.0.0.1) so I swapped it. Unfortunately, neither of these seem to work. @RajaKishan – DeveloperRyan Jun 18 '21 at 18:21
  • did you have the actual scheme before? Be sure to include the `http://` portion – Garr Godfrey Jun 18 '21 at 18:27
  • Check this answere : https://stackoverflow.com/a/33585140/14733292 – Raja Kishan Jun 18 '21 at 18:27
  • As you have a completion handler what's the semaphore for? Don't force an asynchronous pattern to become synchronous. And – as mentioned – a valid (remote) URL must start with a scheme – vadian Jun 18 '21 at 18:29
  • By setting up the bonjour link, I have managed to somewhat resolve the issue. It appears the API calls go through, but I still do not see any of the relevant print statements nor is the completion being called.I seem to get a new error that is rather long, but the key information seems to be `nw_endpoint_handler_set_adaptive_write_handler ... unregistered notification for write_timeout failed`. I'm unsure if this is valuable or if it arises from a different issue. @RajaKishan – DeveloperRyan Jun 18 '21 at 18:59
  • Truthfully, I do not fully understand semaphores. The only thread safety strategies that I am familiar with are Mutex Locks and I am still trying to understand the purpose of semaphores. While I understand them at a basic level, I don't quite see their benefit in these API calls and just trust that the internet knows more than me. Does a completion serve a similar purpose? It seems to me that a semaphore is for thread safety and a completion is just when I wish to perform work once the task finishes. @vadian – DeveloperRyan Jun 18 '21 at 19:01
  • 1
    A semaphore is pointless if you have an asynchronous completion handler and is bad practice anyway. – vadian Jun 18 '21 at 19:26
  • I can assure you that localhost URLs do work in general. – matt Jun 18 '21 at 20:40
  • So best practice would be to just completely remove all the semaphores? @vadian – DeveloperRyan Jun 19 '21 at 01:03
  • 1
    In your case, yes. – vadian Jun 19 '21 at 06:47
  • @vadian Sorry for my delayed response. By removing the semaphores, this completely solved the issue. I noticed that non-localhost functions broke when I removed the semaphores though. They all still have completions, could you explain why this might happen? Additionally, if you wish to write a slight answer regarding semaphores, I can mark it as correct as that did solve the issue. – DeveloperRyan Jun 22 '21 at 18:43
  • `dataTask` works reliably without semaphores. Probably there is something wrong with the URL. – vadian Jun 22 '21 at 18:45
  • Calls all seem to be working fine, it seems like without semaphores blocking no longer occurs and so calls complete out of order - so while I might use one call to get a session ID, another call requiring that ID won't have it at the time of execution. @vadian – DeveloperRyan Jun 22 '21 at 18:56
  • 1
    Due to the asynchronous behavior you have to call the second task in the closure of the first one or in the custom completion handler. – vadian Jun 22 '21 at 19:04
  • I think I'm starting to understand now. Thank you so much for the help! @vadian – DeveloperRyan Jun 22 '21 at 19:26

0 Answers0