I came up with the following solution to dynamically load Assets from Data after reading a thread on StackOverflow :
import Foundation
import AVFoundation
#if os(macOS)
import AppKit
#else
import UIKit
#endif
// Don't forget to set the File Type field in the asset catalog to the correct UTI string: com.apple.quicktime-movie
extension NSDataAsset:AVAssetResourceLoaderDelegate{
@objc public func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
if let infoRequest = loadingRequest.contentInformationRequest{
infoRequest.isEntireLengthAvailableOnDemand = true
infoRequest.contentType = typeIdentifier
infoRequest.contentLength = Int64(data.count)
infoRequest.isByteRangeAccessSupported = true
#if DEBUG
print(infoRequest)
#endif
}
if let dataRequest = loadingRequest.dataRequest{
#if DEBUG
print(dataRequest)
#endif
dataRequest.respond(with: data.subdata(in:Int(dataRequest.requestedOffset) ..< Int(dataRequest.requestedOffset) + dataRequest.requestedLength))
loadingRequest.finishLoading()
return true
}
return false
}
}
extension AVURLAsset{
public convenience init?(_ dataAsset:NSDataAsset){
guard let name = dataAsset.name.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed),
let url = URL(string:"NSDataAsset://\(name))")
else {return nil}
self.init(url:url) // not really used!
self.resourceLoader.setDelegate(dataAsset, queue: .main)
// Retain the weak delegate for the lifetime of AVURLAsset
objc_setAssociatedObject(self, "AVURLAsset+NSDataAsset", dataAsset, .OBJC_ASSOCIATION_RETAIN)
}
}