I'm trying to add an extension to PHFetchResult to pull the result objects out as a correctly typed array - and so far I can't figure out how to avoid the replication seen below. Aside from the type constraint the following extensions are identical. If I use PHObject as the constraint it would work, but the result would need to be cast to the more specific type...
extension PHFetchResult where ObjectType == PHAsset {
var objects: [ObjectType] {
var _objects: [ObjectType] = []
enumerateObjects { (object, _, _) in
_objects.append(object)
}
return _objects
}
}
extension PHFetchResult where ObjectType == PHCollection {
var objects: [ObjectType] {
var _objects: [ObjectType] = []
enumerateObjects { (object, _, _) in
_objects.append(object)
}
return _objects
}
}
extension PHFetchResult where ObjectType == PHAssetCollection {
var objects: [ObjectType] {
var _objects: [ObjectType] = []
enumerateObjects { (object, _, _) in
_objects.append(object)
}
return _objects
}
}
This is a general issue with generic types defined in ObjC and imported to Swift. Some relevant compiler bugs:
In short: ObjC generics are type-erasing, Swift generics are type-preserving. You need the latter for tasks like defining type-constrained extensions, but you can't because Swift doesn't know anything about the ObjectType of any particular PHFetchResult instance.
The swift-evolution proposal that brought widespread ObjC generics import to Swift 3 included a provision for letting ObjC classes provide information about their generic type parameters at runtime... but as of today, that provision has never been implemented.
AFIAK, there's not really a solution to this problem (short of working on the Swift compiler project to improve ObjC generics support), nor similar problems like making PHFetchResult conform to Sequence or Collection.
(I've tried a few angles on extending PhotoKit classes to be more Swifty myself, without much success. About the only thing I haven't tried — largely because it's such a drastic measure — is wrapping/replacing large chunks of the API. In theory, though, you could wrap PHFetchResult in a non-generic ObjC class, then wrap that in a generic Swift type, and replace all of the PhotoKit fetch methods with ones that provide appropriately specialized versions of your wrapper type.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With