Swift 实现PHPhotoLibraryChangeObserver的结构
我的模型有一个结构,它需要符合一个仅为NSObject的协议 我正在寻找一个可行的替代方案,以将模型转换为类。这些要求是:Swift 实现PHPhotoLibraryChangeObserver的结构,swift,photokit,Swift,Photokit,我的模型有一个结构,它需要符合一个仅为NSObject的协议 我正在寻找一个可行的替代方案,以将模型转换为类。这些要求是: 将模型保持为值类型 调用photoLibraryDidChange时更新模型 如果PHPhotoLibraryChangeObserver不要求实现为NSObject,这将是理想的实现 struct Model: PHPhotoLibraryChangeObserver { var images:[UIImages] = [] fileprivate v
photoLibraryDidChange
时更新模型PHPhotoLibraryChangeObserver
不要求实现为NSObject,这将是理想的实现
struct Model: PHPhotoLibraryChangeObserver {
var images:[UIImages] = []
fileprivate var allPhotos:PHFetchResult<PHAsset>?
mutating func photoLibraryDidChange(_ changeInstance: PHChange) {
let changeResults = changeInstance.changeDetails(for: allPhotos)
allPhotos = changeResults?.fetchResultAfterChanges
updateImages()
}
mutating func updateImages() {
// update self.images
...
}
}
我在photoLibraryDidChange
中设置了一个断点,但它并没有到达那里。我还检查了pkAdapter
始终是同一个对象,并且不会在“更改时复制”时重新初始化
**编辑:添加模型视图**
这是modelview中负责模型管理的相关部分
类ModelView:ObservableObject{
@已发布的var模型=模型()
init(){
self.model.startFetching()
}
var图像:[UIImage]{
自我模型
}
...
}
编辑:解决了更新问题
这是模拟器中的一个错误。。。在一台真正的设备上,它可以工作我最终得到了两种可能的设计:
类模型视图:observeObject{
var pkSubscription:是否可以取消?
private var pkAdapter=PhotoKitAdapter()
@已发布的var模型=模型()
init(){
pkSubscription=self.pkAdapter.objectWillChange.sink{uu}in
DispatchQueue.main.async{
self.model.reset()
对于self.pkAdapter.images中的img{
self.model.append(uiimage:img)
}
}
}
self.pkAdapter.startFetching()
}
}
模型
结构模型{
专用(设置)var图像:[UIImage]=[]
变异函数追加(uiimage:uiimage){
images.append(uiimage)
}
变异函数重置(){
图像=[]
}
}
PhotoKit接口
类PhotoKitAdapter:NSObject、PHPhotoLibraryChangeObserver、ObservableObject{
var allPhotos:PHFetchResult?
变量图像:[UIImage]=[]
func photoLibraryDidChange(changeInstance:PHChange){
DispatchQueue.main.async{
如果让changeResults=changeInstance.changeDetails(对于:self.allPhotos!){
self.allPhotos=changeResults.fetchResultAfterChanges
self.updateImages()
self.objectWillChange.send()
}
}
}
func startFetching(){
PHPhotoLibrary.requestAuthorization{状态在中
如果状态==。已授权{
让allPhotosOptions=PHFetchOptions()
AllPhotoOptions.sortDescriptors=[NSSortDescriptor(键:“creationDate”,升序:false)]
self.allPhotos=PHAsset.fetchAssets(带:allphotoOptions)
PHPhotoLibrary.shared()寄存器(自)
self.updateImages()
}
}
}
fileprivate func appendImage(p:PHAsset){
//这实际上会附加图像的多个副本,因为
//对于同一资产,它会被多次调用。
//需要对资产进行适当的跟踪
设pm=PHImageManager.default()
如果p.mediaType==.image{
requestImage(for:p,targetSize:CGSize(宽:1024,高:768),contentMode:.默认值,选项:nil){
图像,在
如果让im=image{
self.images.append(im)
self.objectWillChange.send()
}
}
}
}
fileprivate func updateImages(){
self.images=[]
如果让ap=所有照片{
对于0中的索引。我正在尝试将PhotoKit必须更改的唯一可变数据推送到充当委托的引用类型属性。模型的其余部分可以异步处理它,以便它可以访问委托中的数据,而无需传递self(模型)到PhotoKit。我写了到目前为止的结果。似乎是可行的,除了photoLibraryDidChange
没有被调用…肯定有一个愚蠢的错误,我只是看不出它可能取决于你的结构是如何传递的?记住,它是一个结构,所以每个任务都会复制一个。你能展示更多关于模型是如何维护的,以及如何为我调试并检查了适配器类是否多次实例化。Swift在更改时进行复制时,应将指向引用类型属性的指针转移到新值。情况似乎是这样。我还显式请求了适配器对象的id,在对模型进行了多次变异后,它是相同的。因此排除多个副本和丢失的参考。模拟器错误。在真实的设备上它可以工作…真是浪费时间