how to convert Data to Int in swift

11,935

Solution 1

first convert your data into string like blow and then use that string to initialize int

let stringInt = String.init(data: yourdata, encoding: String.Encoding.utf8)
let int = Int.init(stringInt ?? "")

this will return an optional value which you can unwrap to use further

Solution 2

one can use withUnsafeBytes to get the pointer and load the integer

let x = data.withUnsafeBytes({

        (rawPtr: UnsafeRawBufferPointer) in
        return rawPtr.load(as: Int32.self)

        })

rawPtr is unsaferawbufferpointer and the load() helps to return the value to x. This can be used for getting any integer. The rawPtr is a temporary pointer and it must not be used outside the block.

This is available since Swift 5 and the older version had

public func withUnsafeBytes<ResultType, ContentType>(_ body: (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType

which is deprecated.

Solution 3

As I wrote in my comment, your server sends text representation of an integer.

You need to write something like this:

if error != nil
{
    //...
    return
}
else
{
    if let data = data {
        //First convert the data into String
        if let text = String(data: data, encoding: .utf8) {
            //And then into Int
            if let value = Int(text) {
                print(value)
                //... use the value
            } else {
                print("text cannot be converted to Int")
            }
        } else {
            print("data is not in UTF-8")
        }
    } else {
        print("data == nil")
    }
}

The code above might be simpler, if you do not need some prints.


Using guard as suggested by Martin R, the code above looks something like this:

    guard let data = data else {
        print("data == nil")
        return
    }
    guard let text = String(data: data, encoding: .utf8) else {
        print("data is not in UTF-8")
        return
    }
    guard let value = Int(text) else {
        print("text cannot be converted to Int")
        return
    }
    print(value)
    //... use the value

You can avoid deeply nested code using guard. (You can use guard for checking error != nil, but I leave that for you.)

Solution 4

try this:

let intValue: Int = yourData.withUnsafeBytes { $0.pointee }

withUnsafeBytes { $0.pointee } will return a generic type, you can cast it to your known type.

Share:
11,935
Am1rFT
Author by

Am1rFT

Updated on June 16, 2022

Comments

  • Am1rFT
    Am1rFT almost 2 years

    I'm coding in Swift. API returns a Data which need to be converted to Int! what should I do?

    the response that I need looks like::

    12345

    but the think I get when I print data is :

    Optional(5 bytes)

    API returns an Int (not JSON)

    //send HTTP req to register user
            let myUrl = URL(string: "http://app.avatejaratsaba1.com/api/Person/Create")
            var request = URLRequest(url: myUrl!)
            request.httpMethod = "POST" // compose a query string
            request.addValue("application/json", forHTTPHeaderField: "content-type")
            request.addValue("application/json", forHTTPHeaderField: "Accept")
    
            let postString = ["name" : name.text!,
                              "isLegal" : FinalLegalSegment,
                              "codeMelli" : National_ID.text! ] as [String : Any]
    
    
    do {
                request.httpBody = try JSONSerialization.data(withJSONObject: postString, options: .prettyPrinted)
            }catch let error {
                print(error.localizedDescription)
                self.DisplayMessage(UserMessage: "1Something went wrong , please try again!")
                return
            }
    
            let task = URLSession.shared.dataTask(with: request)
            {
                (data : Data? , response : URLResponse? , error : Error?) in
    
                self.removeActivtyIndicator(activityIndicator: MyActivityIndicator)
    
                if error != nil
                {
                    self.DisplayMessage(UserMessage: "2Could not successfully perform this request , please try again later.")
                    print("error = \(String(describing : error))")
                    return
                }
                else
                {
    
                    print("////////////////////////////////")
                    print("data has been sent")
    
                }
            }
    
    
    
            task.resume()
    
  • Martin R
    Martin R almost 6 years
    Those .init s are not needed. Note also that Int.init(stringInt) won't compile because stringInt is an optional.
  • Devil Decoder
    Devil Decoder almost 6 years
    yes you can use it without init like java style but that how i write code for getting know that something it getting initialized here
  • Devil Decoder
    Devil Decoder almost 6 years
    and for optionals i have already mentioned that above sentences will return optional values and you have to unwrap it
  • OOPer
    OOPer almost 6 years
    @MartinR, nice suggestion, I'v almost forgotten.
  • Martin R
    Martin R almost 6 years
    An answer is more helpful (to OP and to future readers) if it explains the problem and the solution, instead of dumping some code only
  • dquijada
    dquijada over 5 years
    You should add a longer explanation to why this would help, and how/where to use it. It avoids people just copy/paste-ing code without actually understanding it
  • Nico Haase
    Nico Haase over 5 years
    Additionally, please add such explanation to the answer itself, not to the comment section
  • TomH
    TomH about 4 years
    'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead