I'm trying to use the MPMediaEntity.enumerateValues(forProperties:using:)
method from Apple's Media Player framework but I'm encountering an issue that I believe is related to Swift's Objective-C interoperability.
When I execute this code:
MPMediaQuery.playlists().collections!.forEach {
$0.enumerateValues(
forProperties: [MPMediaPlaylistPropertyDescriptionText],
using: { property, value, stop in
print("running block")
})
}
I get a crash with an EXC_BAD_ACCESS signal at the address 0x0 (i.e. a null pointer dereference). However, if I execute the following Objective-C code:
MPMediaQuery *playlistsQuery = [MPMediaQuery playlistsQuery];
NSArray<MPMediaItemCollection *> *playlists = [playlistsQuery collections];
NSSet<NSString *> *set = [NSSet setWithObject:MPMediaPlaylistPropertyDescriptionText];
[playlists enumerateObjectsUsingBlock:^(MPMediaItemCollection *obj, NSUInteger idx, BOOL *stop) {
[obj enumerateValuesForProperties:set usingBlock:^(NSString *property, id value, BOOL *stop) {
NSLog(@"%@", value ? @"value is not nil" : @"value is nil");
}];
}];
then the program does not crash. Furthermore, the output of the Objective-C program shows that value
is sometimes nil, despite Swift importing the parameter as a non-null Any
. I hypothesize that the crash is caused by Swift trying to convert an Objective-C class into an Any
existential without checking whether the pointer is nil.
I have a two questions:
- Regarding the
value
parameter of the block being imported into Swift asAny
instead ofAny?
, is this a bug? Or is it intentional? - Is there a way to avoid this crash?
A few other notes:
- I tried passing in a closure that operates on
Any?
instead ofAny
(i.e.using: { (property, value: Any?, stop) in ... }
), but it still crashed. - I did check that permission to use the music library was granted for both the Swift and Objective-C programs.
- The
MPMediaEntity.value(forProperty:)
method, which provides similar functionality, does useAny?
instead ofAny
for its return type. However, it's less efficient for accessing multiple properties, so it's suboptimal for my use case. - It seems that nil is only returned if the playlist description is empty. However, some playlists with an empty description return an empty string instead of nil. Playlist folders seem to always return nil for their description, but I'm not 100% sure.