web-dev-qa-db-fra.com

Convertir les données en chaîne in Swift 3

Je suis très nouveau à Swift.

Je veux créer quelque chose comme une API sur Swift pour mon application éducative.

J'ai ce code:

    static func getFilm(filmID: Int) -> String {

    print("getFilm")

    let url = URL(string: "https://api.kinopoisk.cf/getFilm?filmID=\(filmID)")!
    var request = URLRequest(url: url)

    var returnData: String = ""

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if var responseVar = response, var dataVar = data {
            print(responseVar)
            returnData = String(data: dataVar, encoding: .utf8)
        } else {
            print(error)
        }
    }

    task.resume()

    return returnData
}

Et j'essaye de convertir Data en String dans cette ligne: returnData = String(data: dataVar, encoding: .utf8)

Le compilateur Swift me donne une erreur et change cette ligne en returnData = String(data: dataVar, encoding: .utf8)!, lorsque j'exécute cette ligne, la variable returnData est vide.

Si j'utilise la ligne d'exemple basique print(String(data: data, encoding: .utf8)) tout ira bien et je pourrai voir data dans la console XCode.

Alors, comment puis-je convertir des données en chaîne?

23
IlyaGutnikov

Voici un exemple utilisant un gestionnaire d'achèvement:

class func getFilm(filmID: Int, completion: @escaping (String) -> ()) {
    let url = URL(string: "https://api.kinopoisk.cf/getFilm?filmID=\(filmID)")!

    URLSession.shared.dataTask(with:url) { (data, response, error) in
      if error != nil {
        print(error!)
        completion("")
      } else {
        if let returnData = String(data: data!, encoding: .utf8) {
          completion(returnData)
        } else {
          completion("")
        }
      }
    }.resume()
}

Et vous l'appelez

MyClass.getFilm(filmID:12345) { result in
   print(result)
}

En cas d'erreur, le gestionnaire d'achèvement renvoie une chaîne vide.

MyClass est la classe englobante de la méthode getFilm. Il est fort probable que le service Web renvoie le code JSON. Vous devrez donc peut-être désérialiser le code JSON dans un tableau ou un dictionnaire.


Dans une version plus sophistiquée, créez une énumération avec deux cas et les valeurs associées.

enum ConnectionResult {
  case success(String), failure(Error)
}

Avec un peu plus d'effort démontrant le pouvoir subtil de Swift, vous pouvez renvoyer la chaîne convertie en cas de succès de l'erreur en cas d'échec dans un seul objet.

class func getFilm(filmID: Int, completion: @escaping (ConnectionResult) -> ()) {
    let url = URL(string: "https://api.kinopoisk.cf/getFilm?filmID=\(filmID)")!

    URLSession.shared.dataTask(with:url) { (data, response, error) in
      if error != nil {
        completion(.failure(error!))
      } else {
        if let returnData = String(data: data!, encoding: .utf8) {
          completion(.success(returnData))
        } else {
          completion(.failure(NSError(domain: "myDomain", code: 9999, userInfo: [NSLocalizedDescriptionKey : "The data is not converible to 'String'"])))
        }
      }
    }.resume()
}

Du côté de l'appelant, une instruction switch sépare les cas.

MyClass.getFilm(filmID:12345) { result in
    switch result {
    case .success(let string) : print(string)
    case .failure(let error) : print(error)
    }
}
36
vadian