Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Data to String in Swift 3

I am very new to Swift.

I want to create something like API on Swift for my educational app.

I have this 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 } 

And I try to convert Data to String in this line: returnData = String(data: dataVar, encoding: .utf8)

Swift compiler gives me an error, and change this line to returnData = String(data: dataVar, encoding: .utf8)! , when I execute this line I get empty returnData variable.

If I use basic example line print(String(data: data, encoding: .utf8)) everything will be OK and I can see data in XCode console.

So, how I can convert Data to String?

like image 549
IlyaGutnikov Avatar asked Oct 21 '16 19:10

IlyaGutnikov


People also ask

How do you convert something to a string in Swift?

To convert an Int value to a String value in Swift, use String(). String() accepts integer as argument and returns a String value created using the given integer value.

What is NSData in iOS?

A static byte buffer that bridges to Data ; use NSData when you need reference semantics or other Foundation-specific behavior. iOS 2.0+ iPadOS 2.0+ macOS 10.0+ Mac Catalyst 13.0+ tvOS 9.0+ watchOS 2.0+

What is utf8 in Swift?

UTF8View Elements Match Encoded C Strings When you call a C function using a String , Swift automatically creates a buffer of UTF-8 code units and passes a pointer to that buffer. The code units of that buffer match the code units in the string's utf8 view.

What is data in Swift?

Data in Swift 3 is a struct that conforms to collection protocol. It is a collection of bytes ( [UInt8] array of unsigned integer 8 bits 0-255). – Leo Dabus.


2 Answers

This is an example using a completion handler:

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

And you call it

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

In case of an error the completion handler returns an empty string.

MyClass is the enclosing class of getFilm method. Most likely the web service will return JSON, so you might need to deserialize the JSON to an array or dictionary.


In a more sophisticated version create an enum with two cases and associated values

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

With a little more effort demonstrating the subtle power of Swift you can return either the converted string on success of the error on failure in a single object.

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

On the caller side a switch statement separates the cases.

MyClass.getFilm(filmID:12345) { result in     switch result {     case .success(let string) : print(string)     case .failure(let error) : print(error)     } } 
like image 53
vadian Avatar answered Oct 13 '22 22:10

vadian


I had this problem, you can't use encoding: .utf8 for unpredictable data. It will return nil every time.

Use this instead:

String(decoding: data, as: UTF8.self)

like image 20
redbastie Avatar answered Oct 13 '22 20:10

redbastie