iosswift

Swift 5 API call data variable nil but API proved working


I ran in some trouble while trying go get my iOS App talking to my express backend.

I'm just starting with swift and iOS development but in my opinion this should work:

func fetchLoc() {
    var currentLoc: CLLocation!
    
    currentLoc = locationManager.location
    
    let latitude = String(currentLoc.coordinate.latitude)
    let longitude = String(currentLoc.coordinate.longitude)
    
    //let url = URL(string: "a542cd3116ed.ngrok.io/api/v1/public/location/66.68994/10.249066/50")!
    let url = URL(string: "http://a542cd3116ed.ngrok.io/api/v1/public/" + "location/" + latitude + "/" + longitude + "/100")!

    var request = URLRequest(url: url)
    request.httpMethod = "GET"

    let session = URLSession.shared
    let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
        do {
            if((data) != nil) {
                let json = try JSONSerialization.jsonObject(with: data!) as! Dictionary<String, AnyObject>
                print(json)
            }
        } catch {
            print("error")
        }
    })

    task.resume()
}

The problem is, Data is always nil. As you can see I already tried inserting the complete URL for testing. But it doesn't make any difference. It has to be a problem with my code because I can call the API from Insomnia just fine. The answer looks like this, so its proper JSON:

[
  {
    "location": {
      "type": "Point",
      "coordinates": [
        66.68994,
        10.249066
      ]
    },
    "type": "shop",
    "name": "Laden weg 60",
    "description": null,
    "status": "active",
    "taxRates": [
      0.19,
      0.07
    ],
    "currency": "EUR",
    "_id": "602e390b7c760032c0cc74d7",
    "address": {
      "street": "abc1",
      "number": null,
      "city": null,
      "zip": null,
      "country": "DE",
      "_id": "602e390b7c760032c0cc74d8"
    },
    "__v": 0
  }
]

I hope I'm just overseeing something obvious here. Thank you in advance!

Postman generated this code:

import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

var semaphore = DispatchSemaphore (value: 0)

var request = URLRequest(url: URL(string: "http://a542cd3116ed.ngrok.io/api/v1/public/location/66.68994/10.249066/50")!,timeoutInterval: Double.infinity)
request.httpMethod = "GET"

let task = URLSession.shared.dataTask(with: request) { data, response, error in 
  guard let data = data else {
    print(String(describing: error))
    semaphore.signal()
    return
  }
  print(String(data: data, encoding: .utf8)!)
  semaphore.signal()
}

task.resume()
semaphore.wait()

Solution

  • The solution Postman generated works for me:

    import Foundation
    #if canImport(FoundationNetworking)
    import FoundationNetworking
    #endif
    
    var semaphore = DispatchSemaphore (value: 0)
    
    var request = URLRequest(url: URL(string: "http://a542cd3116ed.ngrok.io/api/v1/public/location/66.68994/10.249066/50")!,timeoutInterval: Double.infinity)
    request.httpMethod = "GET"
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in 
      guard let data = data else {
        print(String(describing: error))
        semaphore.signal()
        return
      }
      print(String(data: data, encoding: .utf8)!)
      semaphore.signal()
    }
    
    task.resume()
    semaphore.wait()