2017-06-22 4 views
1

J'ai besoin de cette fonction (qui récupère des données d'une base de données) pour renvoyer une chaîne, mais je n'arrive pas à comprendre comment. J'ai trouvé quelques questions/solutions similaires mais je suis encore du mal à mettre en œuvre une bonne solution (je suis assez nouveau avec rapide)Renvoyer la chaîne à partir de la fonction de terminaison d'URLSession Fonction Swift 3

class Helper{ 
static func pReq(jsonURL : String, col : String) -> String { 
    let config = URLSessionConfiguration.default 
    let session = URLSession(configuration: config) 
    let url = URL(string: jsonURL)! 
    let request = URLRequest(url: url) 
    var string = "" 

    let downloadTask = session.dataTask(with: request, completionHandler: {(data, response, error) in 
     if(error == nil){ 
      print("data = \(String(describing: data))") 
      do{ 
       print(jsonURL) 
       let dataDownloadedAsJson = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject] 
       print("dataDownloadedAsJson = \(dataDownloadedAsJson)") 
       do{ 

        if(dataDownloadedAsJson[col] as? String != nil){ 
         string = (dataDownloadedAsJson[col] as? String)! 

        } 
       } 
      } 
      catch{ 
      } 
     } 
     else{ 
      print("Error downloading data. Error = \(String(describing: error))") 
     } 
    }) 
    downloadTask.resume() 
    return string 
} 
} 

Merci à!

+0

assez proche dupé [de cette question connexe] (https://stackoverflow.com/questions/24647406/how-to-use-completionhandler-closure-with-return-in-swift). –

Répondre

2

Votre méthode session.dataTask(with: est asynchrone. Cela signifie qu'il va s'exécuter "en arrière-plan" et vous informer du moment où il a fini d'obtenir une réponse de son appel. Il vous informera de ceci à l'intérieur de votre bloc ci-dessous la partie session.dataTask(with: à l'intérieur du "{}". Comme si cela apparaissait, vous effectuez un traitement avec le JSON que vous recevez et le formatez dans la chaîne que vous souhaitez renvoyer depuis cette fonction. MAIS vous êtes appelé return string en bas bien avant que votre appel se termine, de sorte que vous retournerez "" rien. Ce que vous avez vraiment besoin de faire est de retourner rien de votre fonction, mais au lieu d'utiliser un bloc d'achèvement:

1) déclarer ce au sommet de votre fichier:

typealias StringCompletion  = (_ success: Bool, _ string: String) -> Void 

2) Modifier votre fonction pour prendre un paramètre pour votre fin

// This 
static func pReq(jsonURL : String, col : String) -> String 

// Becomes This 
static func pReq(jsonURL : String, col : String, completion: @escaping StringCompletion) 

3) appeler l'intérieur de votre fonction et votre fin retraverser un Bool pour indiquer qu'il était un appel réussi et retraverser la string ainsi

class Helper{ 
static func pReq(jsonURL : String, col : String, completion: @escaping StringCompletion) { 
    let config = URLSessionConfiguration.default 
    let session = URLSession(configuration: config) 
    let url = URL(string: jsonURL)! 
    let request = URLRequest(url: url) 
    var string = "" 

    let downloadTask = session.dataTask(with: request, completionHandler: {(data, response, error) in 
     if(error == nil){ 
      print("data = \(String(describing: data))") 
      do{ 
       print(jsonURL) 
       let dataDownloadedAsJson = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject] 
       print("dataDownloadedAsJson = \(dataDownloadedAsJson)") 
       do{ 

        if(dataDownloadedAsJson[col] as? String != nil){ 
         string = (dataDownloadedAsJson[col] as? String)! 
         completion(true, string) 
        } 
       } 
       catch { completion(false, string) } 
      } 
      catch{ 
       completion(false, string) 
      } 
     } 
     else{ 
      print("Error downloading data. Error = \(String(describing: error))")  
      completion(false, string) 
     } 
    }) 
    downloadTask.resume() 
} 
} 

4) Utilisation:

Helper().pReq(jsonURL: jsonURL, col: col) { (success, string) in 
    if success { 
     print("Success: \(string)") 
    } 
    else { 
     print("Failure: Unable To Get String") 
    } 
}