     #endif
     
     @objc public var exportDirectory = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("DKImageAssetExporter")
+    
+    public required override init() {
+        super.init()
+    }
+    
+    public func copy(with zone: NSZone? = nil) -> Any {
+        let copy = type(of: self).init()
+        copy.imageExportPreset = self.imageExportPreset
+        copy.videoExportPreset = self.videoExportPreset
+        copy.avOutputFileType = self.avOutputFileType
+        copy.exportDirectory = self.exportDirectory
+        
+        return copy
+    }
+}
+
+/*
+ This exporter is able to export DKAsset (PHAsset) from album (or iCloud) to app's tmp directory
+ and it will automatically cleanup when appropriate.
+ */
+@objc
+open class DKImageAssetExporter: DKBaseManager {
+    
+    static public let sharedInstance = DKImageAssetExporter(configuration: DKImageAssetExporterConfiguration())
+
+    private let configuration: DKImageAssetExporterConfiguration
     
     private var exportQueue: OperationQueue = {
         let exportQueue = OperationQueue()

                            try? fileManager.removeItem(at: tempFile)
                        }
                        
                        exportSession.outputFileType = self.avOutputFileType
                        exportSession.outputURL = tempFile
                        exportSession.shouldOptimizeForNetworkUse = true
                        exportSession.exportAsynchronously(completionHandler: {

    private var requestIDs = [DKImageRequestID : Int]()
    private var isCancelled = false
    
    public init(configuration: DKImageAssetExporterConfiguration) {
        self.configuration = configuration.copy() as! DKImageAssetExporterConfiguration
        
        super.init()
    }
    
    /// This method starts an asynchronous export operation of a batch of asset.
    @objc public func exportAssetsAsynchronously(assets: [DKAsset], completion: @escaping ((DKImageAssetExportResult) -> Void)) {
        guard assets.count > 0 else {
            return completion(.complete)
