My app allows users to select and save images from the Photos app.
The saved image is stored in the core data as a Binary Data type, and when I show the image, I use a GeometryReader to downsample the image to a certain size and show the image. However, I feel that the performance of the app is not good and I want to improve it, but I don't know how to improve it.
I would be grateful if you could give me some advice to improve it.
struct ContextView: View {
@State private var seletedItem: Item?
var body: some View {
MainListView()
.sheet(item: $seletedItem) { item in
GeometryProxy { proxy in
let size = proxy.size
DetailImageView(item: item, size: size)
.ignoresSafeArea(.container, edges: .top)
}
}
}
}
struct DetailImageView: View {
var item: Item
var size: CGSize
private var imageHeight: CGFloat {
size.height * 0.56
}
@State private var uiImage: UIImage? = nil
var body: some View {
ScrollView {
GeometryReader { proxy in
let childSize = proxy.size
if let uiImage {
Image(uiImage: uiImage)
.resizable()
.scaledToFill()
.frame(width: childSize.width, height: childSize.height)
}
}
.frame(height: size.height)
}
.coordinateSpace(name: "scroll")
.task(id: size) {
uiImage = downsampleImage(imageData: item.imageData,
to: CGSize(width: size.width, height: imageHeight))
}
.onChange(of: item.unwrappedImageData) { newImageData in
updateImage(data: newImageData, width: size.width, height: imageHeight)
}
.onDisappear {
uiImage = nil
}
}
private func downsampleImage(imageData: Data, to pointSize: CGSize, scale: CGFloat = UIScreen.main.scale) -> UIImage {
let imageSourceOptions = [kCGImageSourceShouldCache: false] as CFDictionary
guard let imageSource = CGImageSourceCreateWithData(imageData as CFData, imageSourceOptions) else { return UIImage() }
let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale
let downsampleOptions = [
kCGImageSourceCreateThumbnailFromImageAlways: true,
kCGImageSourceShouldCacheImmediately: true,
kCGImageSourceCreateThumbnailWithTransform: true,
kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels
] as CFDictionary
guard let downsampledImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampleOptions) else { return UIImage() }
return UIImage(cgImage: downsampledImage)
}
}