nitinsh92

Networking.m

Dec 1st, 2016
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 9.15 KB | None | 0 0
  1. //
  2. //  VeloxDownloadManager.swift
  3. //  VeloxDownloader
  4. //
  5. //  Created by Nitin Sharma on 11/28/16.
  6. //  Copyright © 2016 Nitin Sharma. All rights reserved.
  7. //
  8.  
  9. import Foundation
  10. import CoreGraphics
  11.  
  12.  
  13. protocol DownloadManagerDelegate {
  14.     func downloadItemAdded(downloadInstance : VeloxDownloadInstance)
  15.     func downloadItemRemoved(downloadInstance : VeloxDownloadInstance)
  16.  
  17. }
  18.  
  19. class VeloxDownloadManager : NSObject,URLSessionDelegate,URLSessionDownloadDelegate
  20.  
  21. {
  22.    
  23.     var currentDownloads : Array<String>?
  24.     var backgroundTransferCompletionHandler :( () -> ())?
  25.     var session : URLSession?
  26.     var backgroundSession : URLSession?
  27.     static var downloadInstanceDictionary : Dictionary<String, VeloxDownloadInstance>?
  28.    
  29.     var delegate : DownloadManagerDelegate?
  30.    
  31.     static let singleton = VeloxDownloadManager()
  32.    
  33.     override private init() {
  34.        
  35.         super.init()
  36.         let configuration = URLSessionConfiguration.default
  37.         self.session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
  38.        
  39.         let backgroundConfiguration  = URLSessionConfiguration.background(withIdentifier: "com.sharmanitin.VeloxDownloader")
  40.         self.backgroundSession = URLSession(configuration: backgroundConfiguration, delegate: self, delegateQueue: nil)
  41.         self.currentDownloads = Array<String>()
  42.        
  43.        
  44.     }
  45.    
  46.    
  47.     func downloadFile(
  48.         withURL: URL,
  49.         name : String,
  50.         directoryName:String?,
  51.         friendlyName : String?,
  52.         progressBlock : @escaping (CGFloat,VeloxDownloadInstance)->(Void),
  53.         remaingTimeBlock : @escaping (CGFloat) -> (Void),
  54.         completionStatus : @escaping (Bool) -> (Void),
  55.         backgroundingMode :Bool
  56.        
  57.         ) -> Void {
  58.        
  59.         if(VeloxDownloadManager.downloadInstanceDictionary == nil)
  60.         {
  61.             VeloxDownloadManager.downloadInstanceDictionary = Dictionary<String,VeloxDownloadInstance>()
  62.         }
  63.        
  64.         //notify the observers
  65.        
  66.  
  67.         //Do the Session networking here
  68.         var fileName  = name
  69.         let url  = withURL
  70.         var friendlyName = friendlyName
  71.         var directoryName = directoryName
  72.  
  73.         if (fileName.isEmpty) {
  74.             fileName = withURL.lastPathComponent
  75.         }
  76.        
  77.         if (friendlyName == nil) {
  78.             friendlyName = fileName;
  79.         }
  80.        
  81.         if (directoryName == nil)
  82.         {
  83.             directoryName = VeloxCacheManagement.cachesDirectoryURlPath().appendingPathComponent(name).absoluteString
  84.         }
  85.        
  86.         if(VeloxCacheManagement.fileDownloadCompletedForURL(url: url))
  87.         {
  88.             print("file is finished downloading")
  89.         }
  90.         else if(!(VeloxCacheManagement.fileExistForURL(url: url, directory: directoryName)))
  91.         {
  92.             self.cleanTempDirectory()
  93.            
  94.             let request = URLRequest(url: url)
  95.             let downloadTask : URLSessionDownloadTask
  96.             if(backgroundingMode)
  97.             {
  98.                  downloadTask = self.backgroundSession!.downloadTask(with: request)
  99.             }
  100.             else
  101.             {
  102.                  downloadTask  = self.session!.downloadTask(with: request)
  103.             }
  104.            
  105.             let downloadInstance = VeloxDownloadInstance(withDownloadTask: downloadTask, remainingTime: remaingTimeBlock, progess: progressBlock, status: completionStatus, name: fileName, friendlyName: friendlyName!, path: directoryName!, date: Date())
  106.  
  107.             VeloxDownloadManager.downloadInstanceDictionary![url.lastPathComponent] = downloadInstance
  108.             if(delegate != nil)
  109.             {
  110.             delegate?.downloadItemAdded(downloadInstance: downloadInstance)
  111.             }
  112.  
  113.                 downloadTask.resume()
  114.  
  115.            
  116.         }
  117.         else
  118.         {
  119.             print("file already exists")
  120.  
  121.         }
  122.  
  123.     }
  124.    
  125.    
  126.     //MARK : Session
  127.    
  128.     func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
  129.        
  130.        
  131.         //print("data written \(totalBytesWritten)")
  132.         let fileIdentifier  = downloadTask.originalRequest!.url!.lastPathComponent
  133.         let dowloadInstace = VeloxDownloadManager.downloadInstanceDictionary![fileIdentifier]
  134.         let  progress = CGFloat.init(totalBytesWritten) / CGFloat.init(totalBytesExpectedToWrite)
  135.        
  136.         //print("progress is   \(progress)")
  137.  
  138.         DispatchQueue.main.async {
  139.             dowloadInstace!.currentProgressClosure(CGFloat(progress),dowloadInstace!)
  140.         }
  141.        
  142.         let remainingTime = self.remainingTimeForDownload(downloadInstace: dowloadInstace!, totalBytesTransferred: totalBytesWritten, totalBytesExpectedToWrite: totalBytesExpectedToWrite)
  143.        
  144.        
  145.         DispatchQueue.main.async {
  146.             dowloadInstace!.remainingTimeClosure (remainingTime)
  147.         }
  148.     }
  149.    
  150.     func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
  151.        
  152.        
  153.         let fileIdentifier  = downloadTask.originalRequest!.url!.lastPathComponent
  154.         let dowloadInstace = VeloxDownloadManager.downloadInstanceDictionary![fileIdentifier]
  155.         var destinationLocation : URL  = VeloxCacheManagement.cachesDirectoryURlPath()
  156.        
  157.         if(dowloadInstace!.filePath.isEmpty){
  158.            
  159.            
  160.             destinationLocation = destinationLocation.appendingPathComponent(fileIdentifier)
  161.         }
  162.         else{
  163.            
  164.             destinationLocation = URL(string: dowloadInstace!.filePath)!
  165.         }
  166.        
  167.         var success = true
  168.  
  169.         let response  = downloadTask.response! as! HTTPURLResponse
  170.         let statusCode = response.statusCode
  171.      
  172.             if (statusCode >= 400) {
  173.                 success = false
  174.             }
  175.        
  176.        
  177.         if (success) {
  178.            
  179.            
  180.             if(delegate != nil)
  181.             {
  182.                 delegate?.downloadItemRemoved(downloadInstance: dowloadInstace!)
  183.             }
  184.             do
  185.             {
  186.           if(VeloxCacheManagement.fileExistWithName(name: dowloadInstace!.filename))
  187.                
  188.                 {
  189.                     try  FileManager.default.removeItem(at: destinationLocation)
  190.  
  191.                 }
  192.                 try  FileManager.default.moveItem(at: location, to: destinationLocation)
  193.  
  194.             }
  195.             catch let error as NSError
  196.             {
  197.                 print("error occured \(error.localizedDescription)")
  198.             }
  199.         }
  200.        
  201.  
  202.  
  203.      
  204.        
  205.        //do a local notification
  206.     }
  207.    
  208.     func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
  209.        
  210.         if let localError = error
  211.         {
  212.             print("error iss : \(localError.localizedDescription)")
  213.         }
  214.         let fileIdentifier  = task.originalRequest!.url!.lastPathComponent
  215.         let dowloadInstace = VeloxDownloadManager.downloadInstanceDictionary![fileIdentifier]
  216.        
  217.         DispatchQueue.main.async {
  218.             dowloadInstace!.downloadStatusClosure (true)
  219.         }
  220.         VeloxDownloadManager.downloadInstanceDictionary!.removeValue(forKey: fileIdentifier)
  221.  
  222.     }
  223.    
  224.  
  225.  
  226.    
  227.     func remainingTimeForDownload(downloadInstace : VeloxDownloadInstance, totalBytesTransferred : Int64,totalBytesExpectedToWrite : Int64) -> CGFloat {
  228.        
  229.         let timeInterval : TimeInterval  = Date().timeIntervalSince(downloadInstace.downloadDate)
  230.        
  231.         let speed  = CGFloat.init(totalBytesTransferred) / CGFloat.init(timeInterval)
  232.         let remainingBytes = totalBytesExpectedToWrite - totalBytesTransferred
  233.         let remainingTime = CGFloat.init(remainingBytes) / CGFloat.init(speed)
  234.         return  remainingTime
  235.     }
  236.    
  237.    
  238.  
  239.  
  240.    
  241.     //MARK : Clean directory
  242.    
  243.    
  244.     func cleanTempDirectory() -> Void {
  245.         do {
  246.             let tempDirectory = try FileManager.default.contentsOfDirectory(atPath: NSTemporaryDirectory())
  247.             for file in tempDirectory
  248.             {
  249.                 do {
  250.                     try
  251.                         FileManager.default.removeItem(atPath: NSTemporaryDirectory().appending(file))
  252.                 } catch let error as NSError {
  253.                 }
  254.             }
  255.         } catch let error as NSError {
  256.         }
  257.        
  258.     }
  259.  
  260.     //MARK : Finish Session
  261.    
  262.     func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
  263.         session.getAllTasks { (taskArray) in
  264.             if(taskArray.count == 0)
  265.             {
  266.                 if(self.backgroundTransferCompletionHandler != nil)
  267.                 {
  268.                     let completer = self.backgroundTransferCompletionHandler
  269.                    
  270.                     OperationQueue().addOperation(
  271.                         completer!
  272.                     )
  273.                    
  274.                     self.backgroundTransferCompletionHandler = nil;
  275.  
  276.                 }
  277.             }
  278.         }
  279.     }
  280.    
  281.    
  282.  
  283.  
  284.  
  285.    
  286. }
Advertisement
Add Comment
Please, Sign In to add comment