LoginSignup
6
7

More than 5 years have passed since last update.

SwiftのData内の任意の位置から数値を取り出す

Posted at

例えばファイルから読み込んだデータの3バイト目からUInt16を取り出したい場合などに利用します。

本来であれば

let amount: UInt16 = data.getValue(offset: 3)

という感じで呼び出せるようにしたかったのですが、NSDataのgetBytes()を利用するにあたってgetBytes()に渡す変数を初期化しなければならず、その初期化方法がわからなかったため、初期化用の数値を引数で渡さなければいけないという汚いコードになってしまいました。

let amount: UInt16 = data.getValue(offset: 3, initialValue: 0)

以下、Dataの拡張宣言によりgetValue()を追加しています。

extension Data {
    func getValue<T>(offset: Int, initialValue: T) -> T? {

        var data: T     = initialValue
        let itemSize    = MemoryLayout.size(ofValue: data)

        let maxOffset = count - itemSize
        guard Range(0...maxOffset).contains(offset) else {
            return nil
        }

        let nsdata = self as NSData

        nsdata.getBytes(&data, range: NSMakeRange(offset, itemSize))

        return data
    }
}

使い方

let data = Data(bytes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

let value16: UInt16? = data.getValue(offset: 1, initialValue: 0)
if let val = value16 {
    debugPrint(String(format: "value=0x%x", val))
} else {
    debugPrint("value is nil")
}

let value32: UInt32? = data.getValue(offset: 1, initialValue: 0)
if let val = value32 {
    debugPrint(String(format: "value=0x%x", val))
} else {
    debugPrint("value is nil")
}

initialValueを使わなくてもいい方法があれば教えてください!

6
7
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7