Created
May 29, 2019 02:09
-
-
Save fcanas/258a9f70a390598e330ba8e6aef04f29 to your computer and use it in GitHub Desktop.
Loading AVAssets from Asset Catalogs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AVAsset+Catalog.swift | |
// Micro Album | |
// | |
// Created by Fabian Canas on 5/28/19. | |
// Copyright © 2019 Fabian Canas. All rights reserved. | |
// | |
import AVFoundation | |
import MobileCoreServices | |
import UIKit | |
fileprivate let AssetCache = NSCache<NSString, AVAsset>() | |
extension AVAsset { | |
/// This method looks in in-memory and on-disk caches for an AVAsset with | |
/// the specified name. If a matching AVAsset is not already in the cache, | |
/// this method locates and loads the video data from disk or from an | |
/// asset catalog, and then caches and returns the resulting object. | |
/// | |
/// - Parameter name: The name of the video asset | |
/// - Returns: The video asset for the specified asset name, or nil if the | |
/// method could not find the specified image. | |
class func named(_ name: String) -> AVAsset? { | |
if let avAsset = AssetCache.object(forKey: name as NSString) { | |
return avAsset | |
} | |
// NSDataAsset lets us have arbitrary data in Asset Catalogs | |
guard let dataAsset = NSDataAsset(name: name) else { | |
return nil | |
} | |
let temporaryFilename = "avasset-\(name.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? ProcessInfo().globallyUniqueString)" | |
let cfExtension = UTTypeCopyPreferredTagWithClass(dataAsset.typeIdentifier as CFString, kUTTagClassFilenameExtension)?.takeRetainedValue() | |
guard let fileExtension = cfExtension as String? else { | |
// AVAsset is picky about the file extension when dealing with local | |
// files. If the extension doesn't match what's expected, it's not | |
// worth making the asset. | |
return nil | |
} | |
let fileManager = FileManager.default | |
let url = fileManager.temporaryDirectory.appendingPathComponent(temporaryFilename).appendingPathExtension(fileExtension) | |
if !fileManager.fileExists(atPath: url.path) { | |
do { | |
try dataAsset.data.write(to: url, options: .atomicWrite) | |
} catch { | |
return nil | |
} | |
} | |
let avAsset = AVAsset(url: url) | |
AssetCache.setObject(avAsset, forKey: name as NSString) | |
return avAsset | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment