Converting NSData to Integer in Swift

后端 未结 7 2085
予麋鹿
予麋鹿 2021-01-05 02:29

In Objective-C the code looked liked this and worked flawlessly,

NSInteger random = arc4random_uniform(99) + 1 
NSData *data = [NSData dataWithBytes:& ra         


        
7条回答
  •  一生所求
    2021-01-05 03:23

    In Swift 4:

    There are a couple of things to consider when extracting an integer value from a Data stream. Signedness and Endianess. So I came up with a function in an extension to Data that infers Signedness from the type of integer you want to extract and passes Endianess and Index as parameters. The types of integers that can be extracted are all that conform to FixedWidthInteger protocol.

    Reminder: This function will not check if the Index range is inside the bounds of the Data buffer so it may crash depending on the size of the type being extracted in relation to the end of the buffer.

    extension Data {
        enum Endianness {
            case BigEndian
            case LittleEndian
        }
        func scanValue(at index: Data.Index, endianess: Endianness) -> T {
            let number: T = self.subdata(in: index...size).withUnsafeBytes({ $0.pointee })
            switch endianess {
            case .BigEndian:
                return number.bigEndian
            case .LittleEndian:
                return number.littleEndian
            }
        }
    }
    

    Example:

    let data = Data(bytes: [0xFF,0x1F,0x1F,0xFF])
    
    let number1 = data.scanValue(at: 0, endianess: .LittleEndian) as UInt16
    let number2 = data.scanValue(at: 0, endianess: .BigEndian) as UInt16
    
    let number3: Int16 = data.scanValue(at: 2, endianess: .LittleEndian)
    let number4: Int16 = data.scanValue(at: 2, endianess: .BigEndian)
    

    Results:

    number1 is 8191
    number2 is 65311
    number3 is -225
    number4 is 8191

    Observe the function calls to see how the type to be extracted is inferred. Of course Endianess doesn't make sense for Int8 or UInt8, but the function works as expected.

    Values can later be cast to Int if needed.

提交回复
热议问题