1

I have written this code (In the function I am using the SwiftSky Api)

// Asked question about WEATHER

public func weatherQuestion(question: String, userLatitude: Double, userLongitude: Double) -> String {

 var answer = String()

// Setting up SwiftSky

 SwiftSky.secret ="...."

 SwiftSky.language = .italian

 SwiftSky.locale = .current

 SwiftSky.units.temperature = .celsius
 SwiftSky.units.accumulation = .centimeter
 SwiftSky.units.distance = .kilometer
 SwiftSky.units.precipitation = .millimeter
 SwiftSky.units.pressure = .millibar
 SwiftSky.units.speed = .kilometerPerHour

 if question.contains("meteo") {

     SwiftSky.get([.current, .alerts, .days, .hours, .minutes], at:  Location(latitude: userLatitude, longitude: userLongitude) , on: Date() , { (result) in

         switch result {

         case .success(let forecast):

             answer = (forecast.current?.summary)!

         case .failure(let error):

             print(error)

         }

     })

 }

 return answer
}

The problem is that, when I try to use the result of the function by printing its value (using the code below)

print(weatherQuestion(question: text, userLatitude: Double(self.locationCoordinates.latitude), userLongitude: Double(self.locationCoordinates.longitude)))

it doesn't print anything. How can I use the result of the function so that when I print out the value it is not empty?

Warren Burton
  • 17,451
  • 3
  • 53
  • 73
edoriggio
  • 331
  • 3
  • 18
  • 2
    `SwiftSky` works asynchronously. You cannot return something in a function from an asynchronous task. You have to add a completion handler. – vadian Sep 03 '17 at 10:36
  • how can I do it? @vadian (Sorry but I am new to programming) – edoriggio Sep 03 '17 at 10:36
  • 1
    Please look at (for example, there are many many similar answers) https://stackoverflow.com/questions/39643334/how-do-you-write-a-completion-handler-in-swift-3/39643395#39643395 – vadian Sep 03 '17 at 10:39
  • @Moritz You're right, I knew about it... . Thank you all for the help – edoriggio Sep 03 '17 at 10:41

1 Answers1

1

SwiftSky.get works async and calls the passed closure with the result parameter when operation is done. So, weatherQuestion returns immediately.

Change method signature to:

public func weatherQuestion(question: String, userLatitude: Double, userLongitude: Double, completion: (String) -> Void)

and call it:

case .success(let forecast):
     completion(forecast.current!.summary)

Now print in completion:

weatherQuestion(question: text, userLatitude: Double(self.locationCoordinates.latitude), userLongitude: Double(self.locationCoordinates.longitude), completion: { answer in
      print(answer)
})
Orkhan Alikhanov
  • 9,122
  • 3
  • 39
  • 60