简体   繁体   English

无法使用 UIImage 和字符串数据对自定义 object 数组进行排序

[英]Trouble sorting array of custom object with UIImage and string data

I can not sort my array of custom objects.我无法对我的自定义对象数组进行排序。 I have tried different swiftUI sorting methods but it doesn´t work and I suspect it has something to do with the struct model I have in my array.我尝试了不同的 swiftUI 排序方法,但它不起作用,我怀疑它与我数组中的结构 model 有关。 I save images in Firebase storage and saves their url:s together with some other data in an array of ImageModel, (my imageRefCollection in StudentModel).我将图像保存在 Firebase 存储中,并将它们的 url:s 与其他一些数据一起保存在 ImageModel 数组中(我的 StudentModel 中的 imageRefCollection)。 Then I fetch the images and stores them together with the other data (time and taskNr) in an array of ImageCollectionModel (my published var imageCollection).然后我获取图像并将它们与其他数据(时间和任务编号)一起存储在 ImageCollectionModel 数组(我发布的 var imageCollection)中。 That is the array I want to sort.那就是我要排序的数组。

This is my models: `这是我的模型:`


class StudentModel: Codable { class StudentModel: Codable {

@DocumentID var id : String?
var name = ""
var district = ""
var school = ""
var courses = [Course]()
var activeCourse = Course()
var imageRefCollection = [ImageModel]()

} }


struct ImageModel: Codable {结构 ImageModel: Codable {

var time: String
var url: String
var taskNr: String

} }



struct ImageCollectionModel {
    
    var image:UIImage
    var taskNr:String
    var time:String
}

` `

And here is my variable in my contentModel:这是我的 contentModel 中的变量:

@Published var imageCollection = [ImageCollectionModel]()

And here is my function that I call onAppear of my View where I show all the images.这是我的 function,我在显示所有图像的视图中调用 onAppear。 I want to show them sorted by time (which is a string, that I can sort when I just try that in testing) but when I try to sort my ImageCollection-array, it doesnt work.我想显示它们按时间排序(这是一个字符串,当我在测试中尝试时可以排序)但是当我尝试对我的 ImageCollection 数组进行排序时,它不起作用。

` `

func getAllImages() {
        
        let storageRef = Storage.storage().reference()
        self.imageCollection = [ImageCollectionModel]()
        
        if !student.imageRefCollection.isEmpty {
            
            for image in student.imageRefCollection {
                let fileRef = storageRef.child(image.url)
                
                fileRef.getData(maxSize: 5*128*128) { imageData, error in
                    if error == nil && imageData != nil {
                        
                        let fetchedImage = UIImage(data: imageData!) ?? UIImage()
                        let taskNr = image.taskNr
                        let time = image.time
                        let imageToAdd = ImageCollectionModel(image: fetchedImage, taskNr: taskNr, time: time)
                        self.imageCollection.append(imageToAdd)
                    }
                }
            }
            imageCollection.sort {
                $0.time < $1.time
            }
        }
    }
}

` `

When I fetch the images, using the for-loop, the for loop first loops all the times and then after that it fetches the images but then in some "random" order (I guess that has something to do with the asyncronus thing that I never has really understood).当我使用 for 循环获取图像时,for 循环首先一直循环,然后它获取图像,但随后以某种“随机”顺序获取图像(我想这与我的 asyncronus 事情有关从来没有真正理解过)。 But, nevertheless, it doesnt matter if I only could sort the array after all the images has been fetched.但是,尽管如此,如果我只能在获取所有图像后对数组进行排序并不重要。 I have tried.sort, .sort(by: but I havent got it to work.我试过.sort, .sort(by: 但我还没有让它工作。

This is how my view looks with my.sort attempt (the grid displays in rows from left to right): with.sort {$0.time < $1.time}这是我的视图在尝试 my.sort 时的样子(网格从左到右按行显示): with.sort {$0.time < $1.time}

And this is how it looks with attempt imageCollection = imageCollection.sorted {$0.time < $1.time} imageCollection = imageCollection.sorted {$0.time < $1.time}这是尝试时的样子imageCollection = imageCollection.sorted {$0.time < $1.time} imageCollection = imageCollection.sorted {$0.time < $1.time}

Edit: Now I have tried to add DispatchGroup but I cant get it to work.编辑:现在我尝试添加 DispatchGroup 但我无法让它工作。 My new code is:我的新代码是:

` `

func getAllImages() {
        
        let storageRef = Storage.storage().reference()
        
        if !student.imageRefCollection.isEmpty {
            
            let group = DispatchGroup()
            
            
            for image in self.student.imageRefCollection {
                group.enter()
                let fileRef = storageRef.child(image.url)
                
                fileRef.getData(maxSize: 5*128*128) { imageData, error in
                    if error == nil && imageData != nil {
                        
                        let fetchedImage = UIImage(data: imageData!) ?? UIImage()
                        let taskNr = image.taskNr
                        let time = image.time
                        let imageToAdd = ImageCollectionModel(image: fetchedImage, taskNr: taskNr, time: time)
                        self.imageCollection.append(imageToAdd)
                    }
                }
                group.leave()
            }
            group.notify(queue: DispatchQueue.global()) {
                self.imageCollection.sort { $0.time < $1.time }
            }
        }
    }

` `

but that gives the following sort... Sort after dispatchgroup try但这给出了以下排序......在 dispatchgroup try 之后排序

What do I do wrong?我做错了什么?

You're not storing the result of your sorting in the variable.您没有将排序结果存储在变量中。 Use it like this:像这样使用它:

imageCollection = imageCollection.sort { $0.time < $1.time }

func getAllImages() {
        
  let storageRef = Storage.storage().reference()
        
  if !student.imageRefCollection.isEmpty {
            
    let group = DispatchGroup()
            
      for image in self.student.imageRefCollection {
        group.enter()
        let fileRef = storageRef.child(image.url)
        fileRef.getData(maxSize: 5*128*128) { imageData, error in
          if error == nil && imageData != nil {
            let fetchedImage = UIImage(data: imageData!) ?? UIImage()
            let taskNr = image.taskNr
            let time = image.time
            let imageToAdd = ImageCollectionModel(image: fetchedImage, taskNr: taskNr, time: time)
            self.imageCollection.append(imageToAdd)
          }
          group.leave()
        }
      }
      group.notify(queue: DispatchQueue.global()) {
        self.imageCollection.sort { $0.time < $1.time }
      }
    }
  }
}

You should move group.leave() one line up.你应该移动group.leave()一行。 It should be executed just after async method returns response and append image to collection.它应该在异步方法返回响应和 append 图像到集合之后立即执行。

You should also convert String time object to Date object. For now .sort is working on String not on Date , that's why it sorts your items in wrong order.您还应该将String time object 转换为Date object。目前.sort正在处理String而不是Date ,这就是为什么它以错误的顺序对您的项目进行排序。 Finally, check if you receive proper string dates from api.最后,检查您是否收到来自 api 的正确字符串日期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM