What causes AVAssetCache to report not playable offline for a fully downloaded asset?

A coworker of mine is working on an iOS app that plays FairPlay-encrypted audio via HLS, and supports both downloading and streaming. And he is unable to play downloaded content when in airplane mode. If he creates an

AVURLAsset
from the local URL when the download completes,
asset.assetCache.isPlayableOffline
returns
NO
, and sure enough when he tries to play in airplane mode it still tries to request one of the .m3u8 playlist files.


The master playlist looks like this:

#EXTM3U
# Created with Bento4 mp4-hls.py version 1.1.0r623

#EXT-X-VERSION:5
#EXT-X-SESSION-KEY:METHOD=SAMPLE-AES,URI="skd://url/to/key?KID=foobar",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"

# Media Playlists
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=133781,BANDWIDTH=134685,CODECS="mp4a.40.2" media-1/stream.m3u8
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=67526,BANDWIDTH=67854,CODECS="mp4a.40.2" media-2/stream.m3u8

The stream playlists look like this:

#EXTM3U
#EXT-X-VERSION:5
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:30
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://url/to/key?KID=foobar",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
#EXTINF:30.000181,
#EXT-X-BYTERANGE:470290@0
media.aac
# more segments...
#EXT-X-ENDLIST

Downloading an asset:

AVURLAsset *asset = [AVURLAsset assetWithURL:myM3u8Url];
[asset.resourceLoader setDelegate:[FairPlayKeyManager instance] queue:[FairPlayKeyManager queue]];
asset.resourceLoader.preloadsEligibleContentKeys = YES;
AVAssetDownloadTask *task = [self.session assetDownloadTaskWithURLAsset:asset assetTitle:@"Track" assetArtworkData:imgData options:nil];

[task resume];


In the delegate's

URLSession:assetDownloadTask:didFinishDownloadingToURL:
:
self.downloadedPath = location.relativePath;


In the delegate's

URLSession:task:didCompleteWithError:
:
if (!error)
{
  NSString *strUrl = [NSHomeDirectory() stringByAppendingPathComponent:self.downloadedPath];
  NSURL *url = [NSURL fileURLWithPath:strUrl];
  AVURLAsset *localAsset = [AVURLAsset assetWithURL:url];
  if (!localAsset.assetCache.playableOffline)
    NSLog(@"Oh no!"); //not playable offline
}


The download doesn't give an error besides the asset cache reporting not playable offline. But if you switch to airplane mode and try to play the downloaded asset, it'll properly ask the resource loader delegate for a key (and I'm using persistent keys, so that works fine offline), then try to make a request for

media-1/stream.m3u8
.


Are there any gotchas that we are not handling here? Should the playlist file be different in some way? Is there some property on the task or asset that we are missing?


Thank you in advance for the help!

--

David