我想在核心数据中保存我的iOS应用程序中的图像,但我要保存的所有图像都是从图片库导入的。因此,保存照片库中已经存在的对该照片的引用会更有意义,而不是尝试将图像转换为NSData并将其存储在手机中。特别是因为图像占用了大量的内存,理想情况下它们不应该保存在两个地方。我正在尝试做的事情是可能的吗,或者苹果不会让我阅读照片库中照片存储位置的参考资料?
另外,如果可以从图片库中获取图像存储位置的引用,我如何在Swift中访问它?
发布于 2021-10-03 17:59:22
这是一个迟来的答案,但希望它能帮助其他人。
是的,这是可能的。您可以使用PHPickerViewController选择照片来获得PHPickerResult,它有一个assetIdentifier属性。assetIdentifier持久且唯一地标识照片。当您想要加载图像时,读取保存的assetIdentifier并使用PHAsset.fetchAssets()检索资源,然后使用PHImageManager.requestImage()获取UIImage。这样,您需要在应用程序中存储的只是assetIdentifier,而不是图像数据。
下面是一些示例代码(用于iOS15),用于选择一张照片并获取assetIdentifier
import PhotosUI
import SwiftUI
struct PhotoPicker: UIViewControllerRepresentable {
@Environment(\.dismiss) var dismiss
@Binding var assetIdentifier: String?
typealias UIViewControllerType = PHPickerViewController
func makeUIViewController(context: Context) -> PHPickerViewController {
var configuration = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
configuration.selectionLimit = 1
configuration.filter = .images
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: PHPickerViewController, context: Context) {
// Do nothing.
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UINavigationControllerDelegate, PHPickerViewControllerDelegate {
let parent: PhotoPicker
init(_ parent: PhotoPicker) {
self.parent = parent
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
parent.dismiss()
// Only 1 image can be selected, so ignore any additional elements.
guard let result = results.first else {
return
}
parent.assetIdentifier = result.assetIdentifier
}
}
}要使用它:PhotoPicker(assetIdentifier: $assetIdentifier)
然后使用以下命令从assetIdentifier检索图像:
import Photos
import SwiftUI
struct LoadedImageView: View {
@State var assetIdentifier: String
@State private var image: Image? = nil
var body: some View {
VStack {
if let image = image {
image
.resizable()
.aspectRatio(contentMode: .fit)
}
}
.onAppear(perform: loadImage)
}
func loadImage() {
let fetchResults: PHFetchResult<PHAsset> =
PHAsset.fetchAssets(withLocalIdentifiers: [assetIdentifier], options: nil)
guard let asset: PHAsset = fetchResults.firstObject else {
return
}
let manager = PHImageManager()
manager.requestImage(for: asset, targetSize: PHImageManagerMaximumSize,
contentMode: .aspectFit, options: nil) { (uiImage, _) in
if let uiImage = uiImage {
self.image = Image(uiImage: uiImage)
}
}
}
}https://stackoverflow.com/questions/45339335
复制相似问题