0

Est-il possible d'accéder à un DispatchGroup d'une autre classe? Dire que j'ai la fonction suivante dans la classe Loginfunctions.swift (avec un var loginQueue = DispatchGroup.init() défini sur la func):Accéder à DispatchGroup depuis une autre classe

func logUserIn(emaila: String!, passworda: String!, urlPath: String!, completionHandler:@escaping (NSDictionary) -> Void) { 
    DispatchQueue.global(qos: .userInitiated).async { 

    let requestURL = NSURL(string: urlPath)! 
    let request = NSMutableURLRequest(url: requestURL as URL) 
    request.httpMethod = "POST" 
    let emailtext = emaila 
    let passwordtext = passworda 

    let postParameters = "email="+emailtext!+"&password="+passwordtext!; 
    request.httpBody = postParameters.data(using: .utf8) 

    DispatchGroup.enter(loginQueue)() 

    //creating a task to send the post request 
    let task = URLSession.shared.dataTask(with: request as URLRequest) { 
     data, response, error in 

     if error != nil{ 
      print("error is \(error)") 
      return; 
     } 

     do { 
      //converting resonse to NSDictionary 
      let myJSON = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary 
      DispatchGroup.wait(self.loginQueue)() 
       DispatchQueue.main.async { 
        completionHandler(myJSON) 
       } 
     } catch { 
      print(error) 
     } 
    } 

    //executing the task 
    task.resume() 
    DispatchGroup.leave(self.loginQueue)() 
    } 
} 

Appeler les éléments suivants d'une autre classe (LoginViewController.swift) donne lieu à des valeurs différentes pour TEMP_VAR_FOR_LOGIN (instance en LoginViewController.swift):

@IBAction func userLogin(_ sender: UIButton) { 
      self.loginFunctions.logUserIn(emaila: self.email.text, passworda: self.password.text, urlPath: "URL_PATH_WAS_ENTERED_HERE") { 
       (completionHandler) in 
       self.TEMP_VAR_FOR_LOGIN = completionHandler 
       print("*****************") 
       print(self.TEMP_VAR_FOR_LOGIN) 
      } 

      print("################") 
      print(TEMP_VAR_FOR_LOGIN) 
} 

La sortie de la console est

Some other stuff... 
################# 
{ 
} 
More other stuff... 
***************** 
{ 
The Data I need : Out of the Closure 
} 

Toute aide où le problème est?

P.S. Rookie ici;)

+0

Il y a beaucoup d'erreurs dans votre utilisation de 'DispatchGroup' ici – KrishnaCA

+0

@KrishnaCA Je crois que vous: D Pouvez-vous me aider où exactement? – Omep2005

+0

Chaque appel de 'DispatchGroup.enter()' doit être équilibré par 'DispatchGroup.leave()' lorsque l'appel asynchrone est terminé. Vous appelez 'DispatchGroup.leave()' avant même que la tâche soit terminée ici. Pouvez-vous s'il vous plaît me dire exactement ce que vous essayez de résoudre ici? Essayez-vous d'utiliser DispatchGroup.notify() quelque part? Si oui, où et quel est le but? – KrishnaCA

Répondre

0

URLSessionTask La méthode elle-même est une tâche asynchrone. Donc, il n'y a pas besoin d'utiliser DispatchGroup ici. La fonction logUserIn peut être modifiée comme suit:

func logUserIn(emaila: String!, passworda: String!, urlPath: String!, completionHandler:@escaping (NSDictionary) -> Void) { 

    let emailtext = emaila 
    let passwordtext = passworda 

    let postParameters = "email="+emailtext!+"&password="+passwordtext!; 

    let requestURL = URL(string: urlPath)! 
    var request = URLRequest(url: requestURL) 
    request.httpMethod = "POST" 
    request.httpBody = postParameters.data(using: .utf8) 

    //creating a task to send the post request 
    let session = URLSession(configuration: URLSessionConfiguration.default) 
    let task: URLSessionDataTask = session.dataTask(with: request, completionHandler: { data, response, error in 

     if error != nil { 
      print(error) 
     }else { 
      do { 
       //converting resonse to NSDictionary 
       let myJSON = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary 
       DispatchQueue.main.async { 
        completionHandler(myJSON) 
       } 
      } catch { 
       print(error) 
      } 
     } 
    }) 

    task.resume() 
} 

En second lieu, la façon dont vous utilisez closure ici est faux. Il est utilisé comme ci-dessous:

var dictionaryObj:NSMutableDictionary = NSMutableDictionary() //global - defined outside functions 

self.logUserIn(emaila: "lal", passworda: "lal", urlPath: "lal", completionHandler: { dictionaryObj in 
    self.dictionaryObj = dictionaryObj as! NSMutableDictionary 
    print(dictionaryObj) 
    print(self.dictionaryObj) 
}) 
+0

Je t'aime frère. Merci beaucoup! Dernière question: Savez-vous comment sortir la valeur dictionaryObj de la fermeture? J'ai essayé de définir une instance puis de mettre à jour la valeur dans la fermeture, mais comme async ne fonctionne pas. – Omep2005

+0

J'ai essayé que ce n'est pas le cas:/Dans la fermeture, la valeur n'est pas vide, mais appeler print (dictionaryObj) hors de la fermeture donne un dictionnaire vide – Omep2005

+0

Vous n'êtes pas censé essayer de l'imprimer juste après 'task .resume() 'ligne. C'est un processus asynchrone. La valeur ne sera capturée qu'une fois le processus terminé. Je pense que vous devez d'abord en savoir plus sur les méthodes asynchrones. S'il vous plaît regarder dans ces articles. http://swiftable.io/2016/06/dispatch-queues-swift-3/ – KrishnaCA