如何在Swift中使用async/await来进行for循环。

huangapple go评论89阅读模式
英文:

How to use async/await in for by Swift

问题

我想知道如何在Swift中使用async/await。

var data = [String]()
func uploadImage(images: [UIImage]) async -> [String] {
    
    for image in images{
        
        let imageUrl = await ImageUploader.uploadImages(image: image, type: .post)
        data.append(imageUrl)
    }
    return data
}
static func uploadImages(image: UIImage, type: UploadType) async -> String {
    guard let imageData = image.jpegData(compressionQuality: 0.5) else { return "" }
    let ref = type.filePath
    
    do {
        let uploadTask = try await ref.putData(imageData, metadata: nil)
        let _ = try await uploadTask.get()
        
        let url = try await ref.downloadURL()
        let imageUrl = url.absoluteString
        return imageUrl
    } catch {
        print("DEBUG: Failed to upload image \(error.localizedDescription)")
        return ""
    }
}

当我调用uploadImage函数时,现在会等待self.data.append(imageUrl),然后返回包含uploadImagesimageUrl的数组。

我希望这对你有所帮助。谢谢。

英文:

I want to know how to use async/await in for by Swift.

var data = [String]()
    func uploadImage(images: [UIImage]) async -> Array<String> {
        
        for image in images{
            
                 ImageUploader.uploadImages(image: image, type: .post) { imageUrl async in
                    await self.data.append(imageUrl)
                }
            
        }
        return data
    }
static func uploadImages(image: UIImage,type: UploadType,completion: @escaping(String) -> Void) async{
        guard let imageData = image.jpegData(compressionQuality: 0.5) else{return}
        let ref = type.filePath
        
        ref.putData(imageData,metadata: nil){ _, error in
            if let error = error{
                print("DEBUG: Failed to upload image\(error.localizedDescription)")
                return
            }
            
            print("Successfully uploaded image")
            
            ref.downloadURL{ url, _ in
                guard let imageUrl = url?.absoluteString else {return}
                completion(imageUrl)
            }
        }
    }

When I call the func uploadImage, not waiting for self.data.append(imageUrl) The data return empty array.

I want for uploadImage to wait append,then the string array should return array including uploadImages'imageUrl.

How should I correct this. Thank you.

答案1

得分: 1

以下是您要翻译的部分:

看起来自从我上次查看 Firebase API 以来,Firebase 提供了自己的 `async/await` 方法。用于上传图像的方法是 `imageRef.putDataAsync(imageData)`

/// 将数据上传到 `FirebaseStorage` 中指定的路径
static func upload(imageData: Data, path: String) async throws -> URL {
    let storageRef = storage.reference()
    let imageRef = storageRef.child(path)

    let metadata = try await imageRef.putDataAsync(imageData)
    return try await imageRef.downloadURL()
}

然后,您可以使用 `withThrowingTaskGroup` 同时上传,或使用常规的 `for` 循环逐个上传。

import UIKit
import FirebaseStorageSwift
import FirebaseStorage
struct ImageStorageService {
    static private let storage = Storage.storage()
    /// 上传多个图像作为 JPEG 并返回图像的 URL
    /// 同时运行上传操作
    static func uploadAsJPEG(images: [UIImage], path: String, compressionQuality: CGFloat = 1) async throws -> [URL] {
        return try await withThrowingTaskGroup(of: URL.self, body: { group in
            for image in images {
                group.addTask {
                    return try await uploadAsJPEG(image: image, path: path, compressionQuality: compressionQuality)
                }
            }
            var urls: [URL] = []
            for try await url in group {
                urls.append(url)
            }

            return urls
        })
    }

    /// 上传多个图像作为 JPEG 并返回图像的 URL
    /// 逐个运行上传操作
    static func uploadAsJPEG1x1(images: [UIImage], path: String, compressionQuality: CGFloat = 1) async throws -> [URL] {
        var urls: [URL] = []
        for image in images {
            let url = try await uploadAsJPEG(image: image, path: path, compressionQuality: compressionQuality)
            urls.append(url)
        }
        return urls
    }
    /// 上传单个图像作为 JPG 并返回图像的 URL
    /// 同时运行上传操作
    static func uploadAsJPEG(image: UIImage, path: String, compressionQuality: CGFloat = 1) async throws -> URL {
        guard let data = image.jpegData(compressionQuality: compressionQuality) else {
            throw ServiceError.unableToGetData
        }

        return try await upload(imageData: data, path: path)
    }
    /// 将数据上传到 `FirebaseStorage` 中指定的路径
    static func upload(imageData: Data, path: String) async throws -> URL {
        let storageRef = storage.reference()
        let imageRef = storageRef.child(path)

        let metadata = try await imageRef.putDataAsync(imageData)
        return try await imageRef.downloadURL()
    }

    enum ServiceError: LocalizedError {
        case unableToGetData
    }
}
英文:

It looks like since the last time I looked at the API Firebase has provided its own async/await methods. For uploading images it is imageRef.putDataAsync(imageData).

///Uploads Data to the designated path in `FirebaseStorage`
static func upload(imageData: Data, path: String) async throws -> URL{
let storageRef = storage.reference()
let imageRef = storageRef.child(path)
let metadata = try await imageRef.putDataAsync(imageData)
return try await imageRef.downloadURL()
}

Then you can use withThrowingTaskGroup to upload simultaneously or use a regular for loop to upload 1x1.

import UIKit
import FirebaseStorageSwift
import FirebaseStorage
struct ImageStorageService{
static private let storage = Storage.storage()
///Uploads a multiple images as JPEGs and returns the URLs for the images
///Runs the uploads simultaneously
static func uploadAsJPEG(images: [UIImage], path: String, compressionQuality: CGFloat = 1) async throws -> [URL]{
return try await withThrowingTaskGroup(of: URL.self, body: { group in
for image in images {
group.addTask {
return try await uploadAsJPEG(image: image, path: path, compressionQuality: compressionQuality)
}
}
var urls: [URL] = []
for try await url in group{
urls.append(url)
}
return urls
})
}
///Uploads a multiple images as JPEGs and returns the URLs for the images
///Runs the uploads one by one
static func uploadAsJPEG1x1(images: [UIImage], path: String, compressionQuality: CGFloat = 1) async throws -> [URL]{
var urls: [URL] = []
for image in images {
let url = try await uploadAsJPEG(image: image, path: path, compressionQuality: compressionQuality)
urls.append(url)
}
return urls
}
///Uploads a single image as a JPG and returns the URL for the image
///Runs the uploads simultaneously
static func uploadAsJPEG(image: UIImage, path: String, compressionQuality: CGFloat = 1) async throws -> URL{
guard let data = image.jpegData(compressionQuality: compressionQuality) else{
throw ServiceError.unableToGetData
}
return try await upload(imageData: data, path: path)
}
///Uploads Data to the designated path in `FirebaseStorage`
static func upload(imageData: Data, path: String) async throws -> URL{
let storageRef = storage.reference()
let imageRef = storageRef.child(path)
let metadata = try await imageRef.putDataAsync(imageData)
return try await imageRef.downloadURL()
}
enum ServiceError: LocalizedError{
case unableToGetData
}
}

huangapple
  • 本文由 发表于 2023年2月27日 01:19:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75573740.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定