The api I am calling is designed to be asynchronous but also has synchronous mode. I am using PHImageManager.requestImageDataAndOrientation
(docs) to request image files, while writing code that is more readable (linear).
let requestImageOptions = PHImageRequestOptions()
requestImageOptions.isSynchronous = true
var photos: [Data] = []
let requestIdentifier = PHImageManager.default().requestImageDataAndOrientation(for: asset, options: requestImageOptions) { [weak &photos] (imageData, dataUTI, orientation, info) in
photos.append(imageData)
}
// do stuff with photos here because the previous call is synchronous
Unfortunately the error message is not helpful: Expected name of in closure capture list
. My attempt with &photos
is to use a reference of the value typed variable, because value types cannot be referenced directly. Could someone point me in the right direction?
This may be a common question for people who mistakenly think they can get value immediately below the method call, where they think an call is synchronous but is not. In my case though, I have configured the call to be synchronous. I also know that I can do all the work in the closure, but then I won't be able to return from the function with data. And sure, I can try a class (value type) to transfer the data out of the closure.
The compiler is objecting because [weak &photos]
at the start of the closure isn't valid syntax.
You don't need to be concerned with the closure capturing the local variable photos
; it can't cause a retain loop.
You do need to conditionally unwrap imageData
though.
It is also important to note that you can only use the synchronous option if you are calling requestImageDataAndOrientation
from a background queue. Your code doesn't show a background queue dispatch. If you do execute the call on a background queue you will need to dispatch any UI updates back onto the main queue.
Given this, it is probably simpler to use the asynchronous form and simply perform your required processing in the completion closure.
let requestIdentifier = PHImageManager.default().requestImageDataAndOrientation(for: asset, options: requestImageOptions) {(imageData, dataUTI, orientation, info) in
guard let imageData = imageData else
{ return }
photos.append(imageData)
}