title: Wait for asynchronous request result
body: <p>I would like somehow to asynchronously validate the pin in ABPadLockScreen since pins are not saved on the device. I'm using Alamofire for http requests along with PromiseKit to have promises. </p>
  
  <p>I have tried to use <code>AwaitKit</code> but the problem is that i get into a deadlock. </p>
  
  <p>I have also tried to use <code>semaphore</code> as well, but the result is the same. Since i can't change the ABPadLock method to accommodate something like a completion handler i need some solution, it doesn't matter if it blocks the main thread, just that it works.</p>
  
  <blockquote>
    <p>Alamofire request method: </p>
  </blockquote>
  
  <pre><code>public func loginAsync(pinCode: String?, apiPath: String?) -&gt; Promise&lt;LoginResult&gt;{
      return Promise { fullfil, reject in
          let params = [
              "Pin": pinCode!
          ]
  
          Alamofire.request(.POST, "\(baseUrl!)/\(apiPath!)", parameters: params).responseObject{(response: Response&lt;LoginResult, NSError&gt;) in
              let serverResponse = response.response
  
              if serverResponse!.statusCode != 200 {
                  reject(NSError(domain: "http", code: serverResponse!.statusCode, userInfo: nil))
              }
  
              if let loginResult = response.result.value {
                  fullfil(loginResult)
              }
          }
      }
  }
  </code></pre>
  
  <blockquote>
    <p>ABPadLockScreen pin validation method: </p>
  </blockquote>
  
  <pre><code>public func padLockScreenViewController(padLockScreenViewController: ABPadLockScreenViewController!, validatePin pin: String!) -&gt; Bool {
      let pinCode = pin!
      let defaults = NSUserDefaults.standardUserDefaults()
      let serverUrl = defaults.stringForKey(Util.serverUrlKey)
      let service = AirpharmService(baseUrl: serverUrl)
  
      service.loginAsync(pinCode, apiPath: "sw/airpharm/login").then { loginResult -&gt; Void in
          if loginResult.code == HTTPStatusCode.OK {
              AirpharmService.id = loginResult.result!.id
          }
      }
  
      return false // how do i get the result of above async method here?
  }
  </code></pre>
  
  <blockquote>
    <p>With semaphore:</p>
  </blockquote>
  
  <pre><code>public func padLockScreenViewController(padLockScreenViewController: ABPadLockScreenViewController!, validatePin pin: String!) -&gt; Bool {
  
      var loginResult: LoginResult?
  
      let defaults = NSUserDefaults.standardUserDefaults()
  
      let baseUrl = defaults.stringForKey(Util.serverUrlKey)
  
      let service = AirpharmService(baseUrl: baseUrl)
  
      let semaphore: dispatch_semaphore_t = dispatch_semaphore_create(0)
  
      service.loginAsync(pin, apiPath: "sw/airpharm/login").then { loginResultRaw -&gt; Void in
          loginResult = loginResultRaw
          dispatch_semaphore_signal(semaphore)//after a suggestion from Josip B.
      }
  
      dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
  
      return loginResult != nil // rudimentary check for now
  }
  </code></pre>
  
  <p>EDIT: </p>
  
  <blockquote>
    <p>After a suggestion from Josip B. i added semaphore signal in then, but it still doesn't work</p>
  </blockquote>
  
  <p><code>AirpharmService</code> is a class that contains a static property called id, and the <code>Alamofire</code> request method.</p>
  
  <p><code>ABPadLockScreen</code> pin validation is done on main thread in a <code>ViewController</code></p>
  
  <p>SOLVED EDIT:</p>
  
  <p>Thanks to everyone for being so patient with me and my, not so good, knowledge of swift and iOS. There are a lot of good answers here and in the end i just went with, in my opinion, simplest solution. I listened to <a href="https://stackoverflow.com/users/765298/losiowaty">Losiowaty</a>-s suggestion; implemented a spinner and manually dismissed the lock screen when i get the response from the server. I've used a <a href="https://github.com/icanzilb/SwiftSpinner" rel="nofollow noreferrer">SwiftSpinner</a>. The final solution looked like this:</p>
  
  <pre><code>public func padLockScreenViewController(padLockScreenViewController: ABPadLockScreenViewController!, validatePin pin: String!) -&gt; Bool {
      let defaults = NSUserDefaults.standardUserDefaults()
      let baseUrl = defaults.stringForKey(Util.serverUrlKey)
  
      let service = AirpharmService(baseUrl: baseUrl)
      SwiftSpinner.show("Logging in. Please wait...")
      service.loginAsync(pin, apiPath: "sw/airpharm/login").then { loginResult -&gt; Void in
          if loginResult.code == HTTPStatusCode.OK {
              SwiftSpinner.hide()
              AirpharmService.id = loginResult.result!.id
              self.unlockWasSuccessfulForPadLockScreenViewController(padLockScreenViewController)
          } else if loginResult.code == HTTPStatusCode.Unauthorized {
              let toast = JLToast.makeText("Invalid pin, please try again", duration: 5)
              toast.show()
              SwiftSpinner.hide()
          } else {
              let toast = JLToast.makeText("\(loginResult.code) sent from server. Please try again.", duration: 5)
              toast.show()
              SwiftSpinner.hide()
          }
      }.error { error in
          let toast = JLToast.makeText("\((error as NSError).code) sent from server. Please try again.", duration: 5)
          toast.show()
          SwiftSpinner.hide()
      }
  
      return false
  }
  </code></pre>