For循环不考虑所有项目?

Posted

技术标签:

【中文标题】For循环不考虑所有项目?【英文标题】:For loop not accounting for all items? 【发布时间】:2021-10-31 13:18:28 【问题描述】:

我有一个多选图像选择器,旨在允许用户选择多个资产,然后将每个资产上传到数据库。在完成处理程序中,我获取所有选定的资产并将它们传递给自定义函数:uploadImageAssets(assets: [PHAsset], projectRef: DocumentReference),上传开始的地方。

在函数中,我使用 for 循环单独上传每个资产。虽然资产已正确上传,但并非所有资产都已上传。假设我选择了 5 个资产...只有 4 个会出现在数据库中,它们都是相同的图像,重复。知道为什么会这样吗?下面是我的代码:

图像选择器选择:

@IBAction func uploadProjectTapped(_ sender: Any) 
    
    let imagePicker = ImagePickerController()
    imagePicker.settings.selection.max = 10
    imagePicker.settings.theme.selectionStyle = .numbered
    imagePicker.settings.fetch.assets.supportedMediaTypes = [.image, .video]
    imagePicker.settings.selection.unselectOnReachingMax = false

    let start = Date()
    self.presentImagePicker(imagePicker, select:  (asset) in
        print("Selected: \(asset)")
    , deselect:  (asset) in
        print("Deselected: \(asset)")
    , cancel:  (assets) in
        print("Canceled with selections: \(assets)")
    , finish:  (assets) in
        print("Finished with selections: \(assets)")
        self.getAssetThumbnail(assets: assets)
    , completion: 
        let finish = Date()
        print(finish.timeIntervalSince(start))
    )
    

并且,将它们添加到 Firestore 的功能:

func uploadImageAsset(assets: [PHAsset], projectRef: DocumentReference) 
    let userID = Auth.auth().currentUser?.uid
    let db = Firestore.firestore()
    let manager = PHImageManager.default()
    let option = PHImageRequestOptions()
    option.isSynchronous = false
    option.isNetworkAccessAllowed = true
    option.resizeMode = .exact
    option.version = .original
    option.deliveryMode = .highQualityFormat
    let uniqueImageID = NSUUID().uuidString
    let storageRef = Storage.storage().reference().child("project-images").child("\(uniqueImageID).jpeg")
    
    for asset in assets 
        let imageSize = CGSize(width: asset.pixelWidth, height: asset.pixelHeight)
        
        manager.requestImage(for: asset, targetSize: imageSize, contentMode: .aspectFill, options: option)  (image, info) in
            let uploadData = image?.jpegData(compressionQuality: 0.6)
            storageRef.putData(uploadData!, metadata: nil, completion: 
                (metadata, error) in

                if error != nil 
                    return
                 else 
                    storageRef.getMetadata(completion:  (metadata, err) in
                        if let error = err 
                            print(error)
                         else 
                            storageRef.downloadURL(completion:  (url, err) in
                                if let error = err 
                                    print(error)
                                 else 
                                    self.imageAssetURLs.append((url?.absoluteString)!)
                                    guard let url = url?.absoluteString else  return 
                                    
                                    
                                    projectRef.updateData(["images": FieldValue.arrayUnion([url])], completion:  (err) in
                                        if err != nil 
                                            print(err)
                                         else 
                                            self.dismiss(animated: true, completion: nil)
                                        
                                    )
                                    
                                    
                                
                            )
                        
                    )
                
            )
            
        
        
    

我有一种强烈的感觉,错误在于这一行:

self.imageAssetURLs.append((url?.absoluteString)!)
                                guard let url = url?.absoluteString else  return 

【问题讨论】:

调试和检查,资产中的所有图像都变得不同了吗? @NikunjGangani 是的,所以它们肯定都是不同的资产。我已经检查过了。只是循环本身不断上传相同的资产 不要使用 for 循环。做递归函数,比for要好。 这只是一个想法,但也许在func uploadImageAsset(...)let uniqueImageID =...let storageRef = ... 应该在storageRef.putData(..) 之前的循环内 您能否在self.imageAssetURLs.append((url?.absoluteString)!) 之前添加一个 print("--> url: \(url)") 并告诉我们它打印的内容。最后你需要先做警卫,然后是self.imageAssetURLs.append(..) 【参考方案1】:

func uploadImageAsset(...)

let uniqueImageID = NSUUID().uuidString

let storageRef = Storage.storage().reference().child("project-images").child("\(uniqueImageID).jpeg")

应该在循环之前

storageRef.putData(..) 

【讨论】:

以上是关于For循环不考虑所有项目?的主要内容,如果未能解决你的问题,请参考以下文章

在 for 循环中不转换到下一个

For 循环的返回值

javascript 使用for循环遍历所有数组的项目

for循环和while循环的区别?

for循环和while循环的区别?

1.10 print triger(for循环嵌套 && print 输出格式)