I need to send images read from the Photo Library over the wire - in chunks of 5MB.
I read an image from the library using: PHImageManager.requestImageData(for:options:resultHandler:)
and get a Data
object. I would then like to efficiently split the data into chunks (without copying the memory). What would be the best way to do that?
This is what I have so far:
imageData.withUnsafeBytes { (unsafePointer: UnsafePointer<UInt8>) -> Void in
let totalSize = data.endIndex
var offset = 0
while offset < totalSize {
let chunkSize = offset + uploadChunkSize > totalSize ? totalSize - offset : uploadChunkSize
let chunk = Data(bytesNoCopy: unsafePointer, count: chunkSize, deallocator: Data.Deallocator.none)
// send the chunk...
offset += chunkSize
}
}
However I get this error at compile time:
Cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafeMutableRawPointer'
If I use mutableBytes:
data.withUnsafeMutableBytes { (unsafePointer: UnsafeMutablePointer<UInt8>) -> Void in... }
Then I get the compile-time error:
Cannot use mutating member on immutable value: 'data' is a 'let' constant
Which is correct, since I do not really want to make changes to the image data. I only want to send one chunk of it at a time.
Is there a better way to do this?
Hi there!
I need the same behaviour and came up with this solution. You pointed the error right and the solution is just to create the UnsafeMutableRawPointer with the UnsafePointer address. It's the fastest solution I found yet.
One other thing is to add the offset to the base address of the mutRawPointer when you create a chunk.
50MB data in 2MB chunks takes ~ 0.009578s
func createChunks(forData: Data) {
imageData.withUnsafeBytes { (u8Ptr: UnsafePointer<UInt8>) in
let mutRawPointer = UnsafeMutableRawPointer(mutating: u8Ptr)
let uploadChunkSize = 2097152
let totalSize = imageData.count
var offset = 0
while offset < totalSize {
let chunkSize = offset + uploadChunkSize > totalSize ? totalSize - offset : uploadChunkSize
let chunk = Data(bytesNoCopy: mutRawPointer+offset, count: chunkSize, deallocator: Data.Deallocator.none)
offset += chunkSize
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With