2017-09-20 23 views
0

Swifts GCDの使用に問題があります。私は、ダウンロードタスクを配列に追加しながら、実際に画像をダウンロードする前にトークンが有効であることを確認する機能を持っています。完了前に戻る関数ブロックが終了しました

問題は、トークンが無効で、新しいものを取得しようとした後に、preloadImageコードが実行されて、requestPreloadJWTToken完了ブロックがdownloadTask変数を設定してnilでないことがわかります。

以下は、ダウンロードタスクのセットアップです。

static func preloadImage(sku: String) { 
    // If the token exists AND is VALID (not expired) - Get the image. 

    let group = DispatchGroup() 
    var downloadTask : RetrieveImageDownloadTask? = nil 

    if ImageManager.tokenExists() && ImageManager.tokenIsNotExpired(){ 

     let imageURL = ImageManager.URLBuilder(sku: sku) 

     // Create the request and add the token string to the authorization header 
     var urlRequest = try! URLRequest(url: URL(string: imageURL)!) 
     urlRequest.setValue("Bearer \(ImageManager.getTokenString()!)", forHTTPHeaderField: "Authorization") 
     downloadTask = NetRequest.downloadImage(urlRequest: urlRequest, sku: sku) 
    } 
    // Else if the token exists AND is INVALID (expired) - Delete the old token, get a new one, and fetch the image 
    else if ImageManager.tokenExists() && !ImageManager.tokenIsNotExpired(){ 
     print("Token expired... Getting new token.") 


     _ = ImageManager.deleteToken() 
     if let tokenRequest = NetRequest.newTokenRequest(url: "http://\(UrlHelper.buildUrlFrom(SettingsManager.serverURL)){ 
      group.enter() 
      tokenRequest.requestPreloadJWTToken(){ 
       let imageURL = ImageManager.URLBuilder(sku: sku) 

       // Create the request and add the token string to the authorization header 
       var urlRequest = try! URLRequest(url: URL(string: imageURL)!) 
       urlRequest.setValue("Bearer \(ImageManager.getTokenString()!)", forHTTPHeaderField: "Authorization") 

       print("Token renewed. Fetching image...") 
       downloadTask = NetRequest.downloadImage(urlRequest: urlRequest, sku: sku) 
      } 
      group.leave() 
     } 
    } 
    // If the token doesn't exist, request a new one and fetch the image. 
    else{ 
     print("Requesting new token...") 

     if let tokenRequest = NetRequest.newTokenRequest(url: "http://\(UrlHelper.buildUrlFrom(SettingsManager.serverURL)){ 
      group.enter() 
      tokenRequest.requestPreloadJWTToken() { 
       print("Token aquired. Fetching image...") 
       let imageURL = ImageManager.URLBuilder(sku: sku) 

       // Create the request and add the token string to the authorization header 
       var urlRequest = try! URLRequest(url: URL(string: imageURL)!) 
       urlRequest.setValue("Bearer \(ImageManager.getTokenString()!)", forHTTPHeaderField: "Authorization") 

       downloadTask = NetRequest.downloadImage(urlRequest: urlRequest, sku: sku) 
      } 
      group.leave() 
     } 
    } 
    // This should always happen 
    group.notify(queue: DispatchQueue.main) { 
     MainController.imageDownloadTasks.append(downloadTask!) 
    } 
} 

以下は作成されたトークン要求です。

func requestPreloadJWTToken(completionHandler: @escaping() -> (/*RetrieveImageDownloadTask*/)) 
{ 
    // Get the server name, username, and password 
    let username = SettingsManager.username 
    let password = SettingsManager.password 

    let queue = DispatchQueue(label: "Token-Request", qos: .utility, attributes: [.concurrent]) 

    // Get download directory 
    let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory, in: .userDomainMask) 

    // Create the header to be used - Add username and password 
    self.makeURLRequest() 
    self.addPreAuthentication(username, password) 

    // Make the request for the token 
    Alamofire.download("\(UrlHelper.buildUrlFrom(SettingsManager.serverURL)), method: .post, parameters: nil, headers: self.request.allHTTPHeaderFields, to: destination) 
     // Alamofires built in authentication will provide credentials when challenged for authentication 
     .authenticate(user: username, password: password) 
     .responseString(
      queue: queue, 
      completionHandler: { response in 

      DispatchQueue.main.async { 
        switch response.result { 
        // If the result was successful, the token string is saved to a file 
        case .success: 
         // Uncomment to see token string value 
         //debugPrint("Value \(response.value!)") 
         completionHandler() 
        case .failure(let error): 
         debugPrint("Failed \(error)") 
        } 
      } 
     } 
    ) 
} 

誰もが、私は素晴らしいだろうpreloadImage前に完了するrequestPreloadJWTから完了ブロックを取得することができますどのようにいくつかの洞察を持っている場合。ありがとう!

答えて

0

Alrighty。だから私はこのポストを作った直後にそれを理解した。もちろん...

とにかく。私はこれがそれに出くわす誰でも役立つことを願って

static func preloadImage(sku: String) { 
    // If the token exists AND is VALID (not expired) - Get the image. 

    let group = DispatchGroup() 
    var downloadTask : RetrieveImageDownloadTask? = nil 

    if ImageManager.tokenExists() && ImageManager.tokenIsNotExpired(){ 

     let imageURL = ImageManager.URLBuilder(sku: sku) 

     // Create the request and add the token string to the authorization header 
     var urlRequest = try! URLRequest(url: URL(string: imageURL)!) 
     urlRequest.setValue("Bearer \(ImageManager.getTokenString()!)", forHTTPHeaderField: "Authorization") 
     downloadTask = NetRequest.downloadImage(urlRequest: urlRequest, sku: sku) 
    } 
    // Else if the token exists AND is INVALID (expired) - Delete the old token, get a new one, and fetch the image 
    else if ImageManager.tokenExists() && !ImageManager.tokenIsNotExpired(){ 
     print("Token expired... Getting new token.") 


     _ = ImageManager.deleteToken() 
     if let tokenRequest = NetRequest.newTokenRequest(url: "http://\(UrlHelper.buildUrlFrom(SettingsManager.serverURL))"){ 
      group.enter() 
      tokenRequest.requestPreloadJWTToken(){ 
       let imageURL = ImageManager.URLBuilder(sku: sku) 

       // Create the request and add the token string to the authorization header 
       var urlRequest = try! URLRequest(url: URL(string: imageURL)!) 
       urlRequest.setValue("Bearer \(ImageManager.getTokenString()!)", forHTTPHeaderField: "Authorization") 

       print("Token renewed. Fetching image...") 
       downloadTask = NetRequest.downloadImage(urlRequest: urlRequest, sku: sku) 
       group.leave() 
      } 
     } 
    } 
    // If the token doesn't exist, request a new one and fetch the image. 
    else{ 
     print("Requesting new token...") 

     if let tokenRequest = NetRequest.newTokenRequest(url: "http://\(UrlHelper.buildUrlFrom(SettingsManager.serverURL))"){ 
      group.enter() 
      tokenRequest.requestPreloadJWTToken() { 
       print("Token aquired. Fetching image...") 
       let imageURL = ImageManager.URLBuilder(sku: sku) 

       // Create the request and add the token string to the authorization header 
       var urlRequest = try! URLRequest(url: URL(string: imageURL)!) 
       urlRequest.setValue("Bearer \(ImageManager.getTokenString()!)", forHTTPHeaderField: "Authorization") 

       downloadTask = NetRequest.downloadImage(urlRequest: urlRequest, sku: sku) 
       group.leave() 
      } 
     } 
    } 
    // This should always happen 
    group.notify(queue: DispatchQueue.main) { 
     MainController.imageDownloadTasks.append(downloadTask!) 
    } 
} 

:ように見えるので、私は単に私のpreloadImage方法で)(内部の閉鎖をgroup.leaveを立ち往生!

+1

は私の答えでこれに取り組んでいました。補完ブロックのそれぞれでほぼ同じことを行うので、コードをリファクタリングすることもお勧めします。そのため、すべての補完ブロックを単一の関数にまとめると便利です。 – NSGangster

+0

ありがとう。ええ、私のコードのこの部分は間違いなくリファクタリングが必要です。まだまだフィールドの新しいもの:p – Mystified

関連する問題