How to check if a NSData is valid for usage in UIImage
You can use
if ([UIImage imageWithData:yourNSData]) {
// there was an image
}
If you're dealing with a single small image, you could convert Data
to an UIImage
:
if let _ = UIImage(data: data) {
print("data contains image data")
} else {
print("data does not contain image data")
}
But if you're dealing with numerous images or high definition images, you could use what's called The magic bytes
in all files, that is, the first few bytes representing a file signature.
Basically you'll just have to extract a few bytes instead of allocation a whole image.
Here is a Data
extension using this technique :
import Foundation
extension Data {
var isImageData: Bool {
let array = self.withUnsafeBytes {
[UInt8](UnsafeBufferPointer(start: $0, count: 10))
}
let intervals: [[UInt8]] = [
[0x42, 0x4D], // bmp
[0xFF, 0xD8, 0xFF], // jpg
[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A], // png
[0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20], // jpeg2000
[0x49, 0x49, 0x2A, 0x00], // tiff1
[0x4D, 0x4D, 0x00, 0x2A] // tiff2
]
for interval in intervals {
var image = true
for i in 0..<interval.count {
if array[i] != interval[i] {
image = false
break
}
}
if image { return true }
}
return false
}
}
You can add more images or imagine any file type recognition based on that code and file types (see Wikipedia list of file signatures for example).
As stated in the documentation imageWithData: returns nil if UIImage could not create an image from the data. The correct way to handle this at runtime is to provide a placeholder image when that method returns nil.
As for the diagnostic, first look at the console messages, they sometimes provide useful info. If not, your best luck is to dump the NSData to disk and compare the result to the file stored on the server. You sometimes get corrupted data, you sometimes just get an html error message where you were expecting jpeg binary data.