首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在调用performSegue之前,我如何检查是否所有照片都上传到了防火墙

在调用performSegue之前,我如何检查是否所有照片都上传到了防火墙
EN

Stack Overflow用户
提问于 2017-09-06 14:24:09
回答 2查看 211关注 0票数 3

我正在制作一张表格,上传3-4张照片到火柴仓库。在上传完所有照片后,我想要执行一个segue

代码语言:javascript
复制
self.performSegue(withIdentifier: "createClubToClubDetail", sender: self)

在打电话给performSegue之前,我如何检查是否所有的照片都被上传到了火场。

将上面的代码放在for循环之后不能工作,因为上传照片在不同的线程中运行(?)

代码语言:javascript
复制
let storageRef = Storage.storage().reference(forURL: "xxxxx.appspot.com").child("club_photo").child(clubRef.key)

            for p in selectedImage {
                let imageData = UIImageJPEGRepresentation(p.value, 0.005)
                let storageImgRef = storageRef.child(p.key + ".jpg")
                storageImgRef.putData(imageData!, metadata: nil) { (metadata, error) in
                    if error != nil {
                        print(error!)
                        return
                    }
                    let downloadURL = metadata?.downloadURL()?.absoluteString
                    var photoRef: DatabaseReference!
                    if p.key == "main" {
                            photoRef = ref.child("photo").child(clubRef.key).child("main")
                    }
                    if p.key == "sub1" {
                        photoRef = ref.child("photo").child(clubRef.key).child("sub1")
                    }
                    if p.key == "sub2" {
                        photoRef = ref.child("photo").child(clubRef.key).child("sub2")
                    }
                    if p.key == "sub3" {
                        photoRef = ref.child("photo").child(clubRef.key).child("sub3")
                    }

                    photoRef.setValue(downloadURL)
                    print("Upload photo: \(p.key)")


                }

            }


 self.performSegue(withIdentifier: "createClubToClubDetail", sender: self)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-07 00:24:05

如前所述,标准的DispatchGroup API能够为您的问题提供一个很好的解决方案。由于您可能在应用程序的其他地方也需要此功能,所以我尝试将基于DispatchGroup的解决方案封装在一个很好的助手类中:

代码语言:javascript
复制
//
// UploadTracker.swift
//

import Foundation 
import FirebaseDatabase

class UploadTracker {
    private let group = DispatchGroup()

    fileprivate func trackSetValue(_ value: Any?, ref: DatabaseReference) {
        group.enter()
        ref.setValue(value) { (error, _) in
            assert(error != nil, "\(error)")
            self.group.leave()
        }
    }

    func uploadDidFinish(block: @escaping () -> Void) {
        group.notify(queue: .main) { block() }
    }
}

extension DatabaseReference {
    func setValue(_ value: Any?, trackedBy tracker: UploadTracker) {
        tracker.trackSetValue(value, ref: self)
    }
}

在您的原始代码中,其用法是:

代码语言:javascript
复制
let uploadTracker = UploadTracker()
for p in selectedImage {
    ...
    photoRef.setValue(downloadURL, trackedBy: uploadTracker)
}
uploadTracker.uploadDidFinish {
    self.performSegue(withIdentifier: "createClubToClubDetail", sender: self)
}
票数 2
EN

Stack Overflow用户

发布于 2017-10-24 12:41:23

我已经尝试了下面的代码上传多个图像,并在上次上传完成后执行segue,虽然这是一个临时修复,但它有效。

当用户希望将多个映像保存到firebase存储时,将调用saveToServerButtonPressed方法。selectedImagesUiImage类型的数组,具有用户希望上载的所有图像。保留var counter仅仅是为了捕获最后一个图像的成功上传,这样用户就可以导航到其他屏幕/任何其他任务,而这些任务只有在所有上传完成之后才能完成。

代码语言:javascript
复制
@IBAction func saveToServerButtonPressed(_ sender: Any) {
    var counter = 0
    for image in selectedImages {
        uploadImage(image, progressBlock: { (progressValue) in
            self.progressStatus.text = "\(progressValue)%"
        }) { (downloadUrl, error) in
            if error == nil {
                if let downloadUrl1 = downloadUrl
                {
                    counter += 1
                    self.imagesUrls.append(downloadUrl1)
                    if counter == self.selectedImages.count {
                        self.performSegue(withIdentifier: "showDownloadedSegue", sender: self)
                    }
                }
            } else {
                print("Error Occured \(String(describing: error))")
            }
        }
    }
}

方法,该方法将图像实际上载到firebase上。

代码语言:javascript
复制
func uploadImage(_ image: UIImage, progressBlock: @escaping (_ percentage: Double) -> Void, completionBlock: @escaping (_ url: URL?, _ errorMessage: String?) -> Void) {
    let storage = FIRStorage.storage()
    let storageReference = storage.reference()
    let imageName = "\(Date().timeIntervalSince1970).jpg"
    let imagesReference = storageReference.child(imageName)

    if let imageData = UIImageJPEGRepresentation(image, 0.8) {
        let metadata = FIRStorageMetadata()
        metadata.contentType = "image/jpeg"
        let uploadTask = imagesReference.put(imageData, metadata: metadata, completion: { (metadata, error) in
            if let metadata = metadata {
                completionBlock(metadata.downloadURL(), nil)
            } else {
                completionBlock(nil, error?.localizedDescription)
            }
        })
        uploadTask.observe(.progress, handler: { (snapshot) in
            guard let progress = snapshot.progress else {
                return
            }
            let percentage = (Double(progress.completedUnitCount) / Double(progress.totalUnitCount)) * 100
            progressBlock(percentage)
        })
    } else {
        completionBlock(nil, "Image couldn't be converted to Data.")
    }
}
}

注意:这段代码在Swift 4上运行良好

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46077763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档