✂️
Data - 指定したサイズに分割し取得
敬意
Dataに指定した特定のバイナリデータを分割取得する必要があり
調べたところ、Objective-Cでの例は存在しましたが
Swiftでの記事がなかったため、こちらに残します。(Objective-Cをやったことある人からしたら、簡単に変換できるかと思いますが悪しからず。)
実装
extension Data {
func splitData(size: Int) -> [Self] {
var dataRange = NSRange(location: .zero, length: size)
let dataSize = self.count
let dataSplitCount = dataSize / size
var dataArray: [Self] = []
for _ in .zero ..< dataSplitCount {
guard let range = Range(dataRange) else { return [] }
dataArray.append(self.subdata(in: range))
dataRange.location += size
}
let remainder = dataSize % size
guard remainder != .zero else { return dataArray }
dataRange.length = remainder
guard let range = Range(dataRange) else { return [] }
dataArray.append(self.subdata(in: range))
return dataArray
}
}
説明
var dataRange = NSRange(location: .zero, length: size)
let dataSize = self.count
let dataSplitCount = dataSize / size
1: まず、指定したサイズのNSRangeインスタンスを生成
2: 分割する元のDataSizeを指定
3: 2で指定したDataSize / 分割するSize
var dataArray: [Self] = []
for _ in .zero ..< dataSplitCount {
guard let range = Range(dataRange) else { return [] }
dataArray.append(self.subdata(in: range))
dataRange.location += size
}
4: for文で、指定した分割Size分処理を実施
5: NSRangeインスタンスをRangeに変換
6: 指定した範囲のDataを配列に格納
7: 次の処理実施前に、範囲開始地点を変更する
let remainder = dataSize % size
guard remainder != .zero else { return dataArray }
dataRange.length = remainder
guard let range = Range(dataRange) else { return [] }
dataArray.append(self.subdata(in: range))
return dataArray
8: まず、剰余があるか確認し、ない場合は6で格納した配列を返却
9: 剰余がある場合は、配列の最後尾に追加し、配列を返却
※使用例
let datada = Data(bytes: [0x00, 0x01, 0x02, 0x10, 0x1B, 0xA1])
print(datada.splitData(size: 2)) // [2 bytes, 2 bytes, 2 bytes]
print(datada.splitData(size: 4)) // [4 bytes, 2 bytes]
参考
Discussion