Proyectos de Subversion Iphone Microlearning - Nuevo Interface

Rev

Rev 11 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

//
//  ImageLoader.swift
//  twogetskills
//
//  Created by Efrain Yanez Recanatini on 3/9/22.
//

import Combine
import UIKit
import var CommonCrypto.CC_MD5_DIGEST_LENGTH
import func CommonCrypto.CC_MD5
import typealias CommonCrypto.CC_LONG


class ImageLoader: ObservableObject {
    @Published var image: UIImage?
    
    private let appData = AppData.sharedInstance
    private(set) var isLoading = false
    
    private let url: URL
    private var cache: ImageCache?
    //private var cancellable: AnyCancellable?
    
    //private static let imageProcessingQueue = DispatchQueue(label: "image-processing")
    
    init(url: URL, cache: ImageCache? = nil) {
        self.url = url
        self.cache = cache
    }
    
    /*
    deinit {
        cancel()
    }
 */
    
    func load() {
       
        
        let urlString : String = url.absoluteString
        
        print("ImageLoader URL : \(urlString) ")
        
        //guard !isLoading else { return }

        
        let md5Data = MD5(string: urlString)
        let key =  md5Data.map {
            String(format: "%02hhx", $0)
        
        }.joined()
        
        if let image = cache?[key as NSString] {
            print("ImageLoader in Cache")
            self.image = image
            return
        }
        
        print("ImageLoader not in Cache")
        
        
        var request = URLRequest(url: url)
  
        let headerSecurity = HeaderSecurity()

        request.httpMethod = "GET"
        request.addValue(appData.deviceUuid, forHTTPHeaderField: Constants.HTTP_HEADER_SECURITY_TOKEN)
        request.addValue(headerSecurity.secret, forHTTPHeaderField: Constants.HTTP_HEADER_SECURITY_SECRET)
        request.addValue(String(headerSecurity.created), forHTTPHeaderField: Constants.HTTP_HEADER_SECURITY_CREATED)
        request.addValue(String(headerSecurity.rand), forHTTPHeaderField: Constants.HTTP_HEADER_SECURITY_RAND)

            
        print("ImageLoader Header \(Constants.HTTP_HEADER_SECURITY_TOKEN) =  \(appData.deviceUuid) ")
        print("ImageLoader Header \( Constants.HTTP_HEADER_SECURITY_SECRET) =  \(headerSecurity.secret) ")
        print("ImageLoader Header \(Constants.HTTP_HEADER_SECURITY_CREATED) =  \(headerSecurity.created) ")
        print("ImageLoader Header \(Constants.HTTP_HEADER_SECURITY_RAND) =  \(headerSecurity.rand) ")
        
        /*
        cancellable = URLSession.shared.dataTaskPublisher(for: request)
            .map { UIImage(data: $0.data) }
            .replaceError(with: nil)
            .handleEvents(receiveSubscription: { [weak self] _ in self?.onStart() },
                          receiveOutput: { [weak self] in self?.cache($0) },
                          receiveCompletion: { [weak self] _ in self?.onFinish() },
                          receiveCancel: { [weak self] in self?.onFinish() })
            .subscribe(on: Self.imageProcessingQueue)
            .receive(on: DispatchQueue.main)
            .sink { [weak self] in self?.image = $0 }*/
        
        let task = URLSession.shared.dataTask(with: request, completionHandler: setImageFromData)
        task.resume()
    }
    
    private func setImageFromData(data: Data?, urlResponse: URLResponse?, error: Error?) {
            guard error == nil else {
                print("\(error!)")
                return
            }
            
            guard let content = data else {
                print("No data")
                return
            }
            
            DispatchQueue.main.async {
                self.image = UIImage(data: content)
               // self.dataHasLoaded = true
            }
        }
    
    /*
    func cancel() {
        cancellable?.cancel()
    }
    
    private func onStart() {
        isLoading = true
    }
    
    private func onFinish() {
        isLoading = false
    }*/
    
    private func cache(_ image: UIImage?) {
        let urlString : String = url.absoluteString
        
        print("ImageLoader URL : \(urlString) ")
        
        //guard !isLoading else { return }

        
        let md5Data = MD5(string: urlString)
        let key =  md5Data.map {
            String(format: "%02hhx", $0)
        
        }.joined()
        
        
        image.map { cache?[key as NSString] = $0 }
    }
    
    private func MD5(string: String) -> Data {
        let length = Int(CC_MD5_DIGEST_LENGTH)
        let messageData = string.data(using:.utf8)!
        var digestData = Data(count: length)

        _ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in
        messageData.withUnsafeBytes { messageBytes -> UInt8 in
        if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress {
                let messageLength = CC_LONG(messageData.count)
                    CC_MD5(messageBytesBaseAddress, messageLength, digestBytesBlindMemory)
                }
            return 0
            }
        }
        return digestData
    }
    
}