How to convert data to types like Doubles, Ints and Strings in Swift?

I am working on creating a special file opener in iOS Swift for shapefiles (a GIS format that is not particularly relevant to this issue). These files have a header length of 100 bytes. I can read this in 4 byte arrays that store the information I want. I can convert these arrays to Swift Data and NSData types and have several other options for converting them (e.g. Base64EncodedString ). But I am having problems converting these raw arrays or data or any of the formats into useful attributes such as Double , Int and String .

 import Foundation struct ShapeReader { var shapeFile = FileHandle(forReadingAtPath: "/Users/christopherjlowrie/Documents/Shapes/SF_Neighborhoods/Planning_Zones.shp") var fileHeader: String{ let header = shapeFile?.readData(ofLength: 100) let headerStream = InputStream(data: header!) headerStream.open() var buffer = [UInt8](repeating: 0, count: 4) while (headerStream.hasBytesAvailable){ headerStream.read(&buffer, maxLength: buffer.count) print(buffer) let x = Data(buffer) print(x) } return "A" } } 

Currently only returns A, because for testing reasons I am returning a string

How to open files and read their raw bytes in types ( Doubles , Ints , Strings ) in Swift?

+6
swift
Apr 05 '17 at 21:21
source share
1 answer

You can do it as follows:

To convert from String, Int, or Double to Data:

Xcode 9 β€’ Swift 4 // for the old Swift 3 syntax click here

 extension String { var data: Data { return Data(utf8) } } extension Numeric { var data: Data { var source = self // This will return 1 byte for 8-bit, 2 bytes for 16-bit, 4 bytes for 32-bit and 8 bytes for 64-bit binary integers. For floating point types it will return 4 bytes for single-precision, 8 bytes for double-precision and 16 bytes for extended precision. return Data(bytes: &source, count: MemoryLayout<Self>.size) } } 

To convert data back to String, Int, or Double:

Swift 4.2 or earlier

 extension Data { var integer: Int { return withUnsafeBytes { $0.pointee } } var int32: Int32 { return withUnsafeBytes { $0.pointee } } var float: Float { return withUnsafeBytes { $0.pointee } } var float80: Float80 { return withUnsafeBytes { $0.pointee } } var double: Double { return withUnsafeBytes { $0.pointee } } var string: String { return String(data: self, encoding: .utf8) ?? "" } } 



edit / update Swift 5

 extension Data { var integer: Int { return withUnsafeBytes { $0.load(as: Int.self) } } var int32: Int32 { return withUnsafeBytes { $0.load(as: Int32.self) } } var float: Float { return withUnsafeBytes { $0.load(as: Float.self) } } var float80: Float80 { return withUnsafeBytes { $0.load(as: Float80.self) } } var double: Double { return withUnsafeBytes { $0.load(as: Double.self) } } var string: String { return String(data: self, encoding: .utf8) ?? "" } } 



Playground Testing




 let intData = 1_234_567_890_123_456_789.data // 8 bytes (64 bit Integer) let dataToInt = intData.integer // 1234567890123456789 let intMinData = Int.min.data // 8 bytes (64 bit Integer) let backToIntMin = intMinData.integer // -9223372036854775808 let intMaxData = Int.max.data // 8 bytes (64 bit Integer) let backToIntMax = intMaxData.integer // 9223372036854775807 



 let myInt32Data = Int32(1_234_567_890).data // 4 bytes (32 bit Integer) let backToInt32 = myInt32Data.int32 // 1234567890 let int32MinData = Int32.min.data // 4 bytes (32 bit Integer) let backToInt32Min = int32MinData.int32 // -2147483648 let int32MaxData = Int32.max.data // 4 bytes (32 bit Integer) let backToInt32Max = int32MaxData.int32 // 2147483647 



 let myFloatData = Float.pi.data // 4 bytes (32 bit single=precison FloatingPoint) let backToFloat = myFloatData.float // 3.141593 backToFloat == .pi // true let myDoubleData = Double.pi.data // 8 bytes (64 bit double-precision FloatingPoint) let backToDouble = myDoubleData.double // 3.141592653589793 backToDouble == .pi // true let myFloat80Data = Float80.pi.data // 16 bytes (128 bit extended-precision FloatingPoint) let backToFloat80 = myFloat80Data.float80 // 3.141592653589793116 backToFloat80 == .pi // true 



 let myStringData = Data("Hello World !!!".data.prefix(4)) // 4 bytes let backToString = myStringData.string // "Hell" 
+12
Apr 6 '17 at 3:07 on
source share



All Articles