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?
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)
}
}