private void HandlePersistableContentKeyRequest(AVPersistableContentKeyRequest keyRequest)
        {
            /*
             * The key ID is the URI from the EXT-X-KEY tag in the playlist (e.g. "skd://key65") and the
             * asset ID in this case is "key65".
             */

            var contentKeyIdentifierString = keyRequest.Identifier as NSString;

            if (contentKeyIdentifierString == null)
            {
                Debug.WriteLine("Failed to retrieve the assetID from the keyRequest!");
                return;
            }

            var contentKeyIdentifierUrl = new NSUrl(contentKeyIdentifierString);
            var assetIdString           = contentKeyIdentifierUrl.Host;
            var assetIdData             = NSData.FromString(assetIdString, NSStringEncoding.UTF8);

            Action <NSData, NSError> completionHandler = async(data, error) =>
            {
                if (error != null)
                {
                    keyRequest.Process(error);
                    pendingPersistableContentKeyIdentifiers.Remove(assetIdString);
                    return;
                }

                if (data == null)
                {
                    return;
                }

                try
                {
                    var ckcData = await RequestContentKeyFromKeySecurityModule(data, assetIdString);

                    NSData persistentKey = keyRequest.GetPersistableContentKey(ckcData, null, out error);

                    WritePersistableContentKey(persistentKey, new NSString(assetIdString));

                    /*
                     * AVContentKeyResponse is used to represent the data returned from the key server when requesting a key for
                     * decrypting content.
                     */
                    var keyResponse = AVContentKeyResponse.Create(persistentKey);

                    /*
                     * Provide the content key response to make protected content available for processing.
                     */
                    keyRequest.Process(keyResponse);

                    string assetName    = string.Empty;
                    bool   assetRemoved = false;

                    if (contentKeyToStreamNameMap.TryGetValue(assetIdString, out assetName))
                    {
                        assetRemoved = contentKeyToStreamNameMap.Remove(assetIdString);
                    }

                    if (!string.IsNullOrWhiteSpace(assetName) && assetRemoved && !contentKeyToStreamNameMap.ContainsKey(assetIdString))
                    {
                        var userInfo = new Dictionary <string, object>();
                        userInfo["name"] = assetName;

                        var userInfoDictionary = NSDictionary.FromObjectsAndKeys(userInfo.Values.ToArray(), userInfo.Keys.ToArray());
                        NSNotificationCenter.DefaultCenter.PostNotificationName(ContentKeyDelegate.DidSaveAllPersistableContentKey, null, userInfoDictionary);
                    }

                    pendingPersistableContentKeyIdentifiers.Remove(assetIdString);
                }
                catch (Exception ex)
                {
                    pendingPersistableContentKeyIdentifiers.Remove(assetIdString);
                    Debug.WriteLine(ex.Message);
                }
            };

            try
            {
                var applicationCertificate = RequestApplicationCertificate();

                var keys    = new[] { new NSString(AVContentKeyRequest.ProtocolVersions) };
                var numbers = new NSMutableArray <NSNumber>();
                numbers.Add(new NSNumber(1));
                var objects = new NSObject[] { numbers };
                var options = new NSDictionary <NSString, NSObject>(keys, objects);

                if (PersistableContentKeyExistsOnDisk(assetIdString))
                {
                    var urlToPersistableKey = CreateUrlForPersistableContentKey(assetIdString);
                    var contentKey          = NSFileManager.DefaultManager.Contents(urlToPersistableKey.Path);

                    if (contentKey == null)
                    {
                        pendingPersistableContentKeyIdentifiers.Remove(assetIdString);

                        /*
                         * Key requests should never be left dangling.
                         * Attempt to create a new persistable key.
                         */
                        keyRequest.MakeStreamingContentKeyRequestData(applicationCertificate, assetIdData, options, completionHandler);

                        return;
                    }

                    /*
                     * Create an AVContentKeyResponse from the persistent key data to use for requesting a key for
                     * decrypting content.
                     */

                    var keyResponse = AVContentKeyResponse.Create(contentKey);
                    keyRequest.Process(keyResponse);

                    return;
                }

                keyRequest.MakeStreamingContentKeyRequestData(applicationCertificate, assetIdData, options, completionHandler);
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Failure responding to an AVPersistableContentKeyRequest when attemping to determine if key is already available for use on disk. {ex.Message}");
            }
        }
 public override void DidProvidePersistableContentKeyRequest(AVContentKeySession session, AVPersistableContentKeyRequest keyRequest)
 {
     HandlePersistableContentKeyRequest(keyRequest);
 }