-1

Hi friends I am not understanding one thing

 static func checkAppVer() -> Bool { 
    var status = false
    API.sharedInstance.checkApp(completion: { success, response in
        if success {
            if (response) != nil {
                let apiAppVesrion = response?.configValue ?? ""
                let appVers = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
                if appVers >= apiAppVesrion {
                    status = true
                }else{
                    status = false
                }
            }
        }else{
            status =  false
        }
        
    })
    return status
}

In the given code when I add break point code run like this

  1. status var call
  2. the last return status
  3. the api result call

but code should call synchronously one by one. I am not understanding why it going on. I can handle this by using closure but I just want to know why this is going. Thanks in advance.

1 Answers1

1

First of all, you should not show pictures of code, only the code itself. Otherwise it is hard to check your code.
Next, your code does not execute synchronously by design:
The parameter completion of your function checkApp is a block that is executed asynchronously after your function finished.
So, you first call the function and let it execute independently.
Then return status is executed, which is with highest probability false.
Eventually, your function finishes and sets the value of status to whatever is the result of the function, but this is (again with highest probability) not returned.

EDIT:

If you want to wait for the completion to finish (which may be not a good idea on the main thread, because it would be blocked), you can wrap your code in a block like this:

// Before call to checkApp:
let lock = DispatchGroup.init()

// At the end of the completion block:
lock.leave()

// Before return status
let waitResult = lock.wait(timeout: .now() + 100)
if waitResult != .success { fatalError("Timeout") }
Reinhard Männer
  • 14,022
  • 5
  • 54
  • 116
  • Hi @Reinhard thanks for your reply, Can you clear one doubt of mine, according to your answer, I think my closure is an escaping closure so it is working asynchronously. So no escaping closure will work synchronously ? – user3120670 Jan 15 '22 at 20:27
  • Your question is completely justified, and maybe I am wrong, since I do not know `API.sharedInstance.checkApp`. Normally, completions are handled asynchronously. But there are exceptions, like with Coredata, where `managedContext.performAndWait` executes synchronously. So, you had to check the called function. In your case, however, it is apparently executed asynchronously. – Reinhard Männer Jan 15 '22 at 20:37
  • Thanks @Reinhard, In my case `API.sharedInstance.checkApp` is an escaping closure. So due to escaping closure it is working as asynchronously , if I use this function as non-escaping will it work synchronously? – user3120670 Jan 15 '22 at 20:44
  • No, this is independent of @escaping. For a possible solution, please see my edit above. – Reinhard Männer Jan 15 '22 at 20:50
  • *If you want to wait for the completion to finish (which may be not a good idea on the main thread*. I'm afraid it's not a good idea at all. Use the completion handler pattern or async/await in Swift 5.5. – vadian Jan 15 '22 at 20:57
  • @vadian: Good idea! Maybe you can provide an answer with a solution? – Reinhard Männer Jan 15 '22 at 21:02
  • Thanks @Reinhard according to your edited answer I have to wait for my response and according to response my return will execute.This will block my main thread for 100 seconds. One more question how would i know my code is working synchronously or asynchronously other than using `DispatchQueue.global.sync` – user3120670 Jan 15 '22 at 21:03
  • Don't `sync` and don't `lock`. Never. Please see https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function – vadian Jan 15 '22 at 21:11