Swift将Phasset数组转换为URL阵列



我有一个PHAssets的数组,所以我想将其转换为URL

的数组
func getURL(ofPhotoWith mPhasset: PHAsset, completionHandler : @escaping ((_ responseURL : URL?) -> Void)) {
    let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
    options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
        return true
    }
    mPhasset.requestContentEditingInput(with: options, completionHandler: { (contentEditingInput, info) in
        completionHandler(contentEditingInput!.fullSizeImageURL)
    })
}

func getUrlsFromPHAssets(assets:[PHAsset], completion: @escaping ((_ urls:[URL]) -> ())){
    var arrUrl:[URL] = []
    for asset in assets {
        self.getURL(ofPhotoWith: asset) { (url) in
            arrUrl.append(url!)
        }
    }
    completion(arrUrl)
}

我在下面在下面调用功能。

self.getUrlsFromPHAssets(assets: assets, completion: { (urls) in
            print(urls)
}) 

因此,在函数 getUrlsFromPHAssets中,如何等待附加URL的循环到URL的数组完成,然后返回。

更新功能getUrlsFromPHAssets

func getUrlsFromPHAssets(assets:[PHAsset], completion: @escaping ((_ urls:[URL]) -> ())){
    var arrUrl:[URL] = []
    var index:Int = 0
    for asset in assets {
        self.getURL(ofPhotoWith: asset, completionHandler: { (url) in
            arrUrl.append(url!)
            if index == assets.count - 1 {
                completion(arrUrl)
            }
            index = index + 1
        })
    }
}

更新功能后,结果似乎还可以,但是我不确定它是否会随时更正。

在您的第二个功能中,您使用for循环执行一堆异步功能。每当您具有多个同步函数时,其完成的函数彼此彼此依赖,您可能想要DispatchGroup。此对象可以调用enter()表示异步块正在启动,并且leave()一旦完成了异步块。

func getUrlsFromPHAssets(assets: [PHAsset], completion: @escaping ((_ urls:[URL]) -> ())) {
    var array: [URL] = []
    let group = DispatchGroup()
    for asset in assets {
        group.enter()
        self.getURL(ofPhotoWith: asset) { (url) in
            // I changed this from force unwrapping.
            // Seems like it's totally possible to get back a nil URL,
            // in which case, you don't want to crash
            if let url = url {
                array.append(url)
            }
            group.leave()
        }
    }
    // This closure will be called once group.leave() is called
    // for every asset in the above for loop
    group.notify(queue: .main) {
        completion(array)
    }
}

最新更新