Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • How to download data Using NSOperations and NSOperationQueue

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 2.67k
    Comment on it

    Hi Readers,

    It is sometimes required to download files or images from server into local. We can perform these tasks by NSOperation and NSOperationQueue efficiently. The basic idea is to create each download operation separately and add these operations into our queue which maintain these operation execution. Lets look at an example of downloading images from URLs. All you need to install Alamofire pod into your project. You can find many links to see how to install it. After installing please follow these steps:

    Create a different class as DownloadOperation in which you define your obejct for downloading as PhotoRecord, OperationQueue as PendingOperations and NSOperation as Download like: 

    enum PhotoRecordState {
        case New, Downloaded, Filtered, Failed
    }
    
    class PhotoRecord {
        let name:String
        let url:NSURL
        
        var image = UIImage(named: "Placeholder")
        var imageview : UIImageView
        var state = PhotoRecordState.New
        init(name:String, url:NSURL, imageview:UIImageView) {
            self.name = name
            self.url = url
            self.imageview = imageview
        }
    }
    
    class PendingOperations {
        lazy var downloadsInProgress = [Int:NSOperation]()
        lazy var downloadQueue:NSOperationQueue = {
            var queue = NSOperationQueue()
            queue.name = "Download queue"
            queue.maxConcurrentOperationCount = 1
            return queue
        }()
    }
    
    class Download: NSOperation {
     
        let photoRecord: PhotoRecord
        
        //2
        init(photoRecord: PhotoRecord) {
            self.photoRecord = photoRecord
        }
        
        
        func filepath(filename:String) -> String {
            let documentsDirectoryURL = try! NSFileManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
            // create a name for your image
            let fileURL = documentsDirectoryURL.URLByAppendingPathComponent(filename)
            return fileURL.path!
            //if !NSFileManager.defaultManager().fileExistsAtPath(fileURL.path!) {
                
        }
        override func main() {
            
            if self.cancelled {
                return
            }
            
            
          var localPath: NSURL?
            
          let response =  Alamofire.download(.GET,
                self.photoRecord.url,
                destination: { (temporaryURL, response) in
                    let directoryURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
                    let pathComponent = response.suggestedFilename
                    
                    localPath = directoryURL.URLByAppendingPathComponent(pathComponent!)
                    return localPath!
                    
          }).progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
            print(bytesRead)
            // This closure is NOT called on the main queue for performance
            // reasons. To update your ui, dispatch to the main queue.
            dispatch_async(dispatch_get_main_queue()) {
                print("Total bytes read on main queue: \(totalBytesRead)")
            }
            }.response()
            
            if let error = response.error {
                print("Failed with error: \(error)")
            } else {
                print("Downloaded file successfully")
            }
            
            dispatch_async(dispatch_get_main_queue(), {
                self.photoRecord.imageview.image = UIImage(contentsOfFile: (localPath?.path)!)
                self.photoRecord.imageview.setNeedsDisplay()
            })
            
            
            if self.cancelled {
                return
            }
            
        }
    }
    

    In above code we have we create an enum as PhotoRecordState which can be used to get state of the downloading process. PhotoRecord class has init method to set downloading URL and corresponding imageview. You can see class PendingOperation which is used to create operation queue object, later we add operations into this queue. Download is a subclass of NSOperation, when it comes to start state, main() called after it. So we override main() function in which we put code for downloading provided by Alamofire. All images will be downloaded into your local directory or document directory which can be used later.

    Now we all set for adding operation into our operation queue. Add following code into your controller where you need to perform operations like:

    let task1: PhotoRecord = PhotoRecord(name: "test1", url: NSURL(string:"https://static.pexels.com/photos/909/flowers-garden-colorful-colourful.jpg")!,imageview: iamge1)
            let task2: PhotoRecord = PhotoRecord(name: "test2", url: NSURL(string:"http://www.sxc.hu/pic/m/r/ra/ralu/120621_maya_ruins4.jpg")!,imageview: iamge2)
            let task3: PhotoRecord = PhotoRecord(name: "test3", url: NSURL(string:"https://static.pexels.com/photos/909/flowers-garden-colorful-colourful.jpg")!,imageview: iamge3)
            let task4: PhotoRecord = PhotoRecord(name: "test4", url: NSURL(string:"http://www.sxc.hu/pic/m/r/re/renato2004/243221_coliseu_de_roma.jpg")!,imageview: iamge4)
            let task5: PhotoRecord = PhotoRecord(name: "test5", url: NSURL(string:"https://static.pexels.com/photos/909/flowers-garden-colorful-colourful.jpg")!,imageview: iamge5)
            let task6: PhotoRecord = PhotoRecord(name: "test6", url: NSURL(string:"http://webneel.com/wallpaper/sites/default/files/images/01-2014/12-flower-wallpaper.jpg")!,imageview: iamge6)
            let task7: PhotoRecord = PhotoRecord(name: "test7", url: NSURL(string:"http://newflowerwallpaper.com/download/indian-flowers-images-and-wallpapers/indian-flowers-images-and-wallpapers-27.jpg")!,imageview: iamge7)
            let task8: PhotoRecord = PhotoRecord(name: "test8", url: NSURL(string:"https://static.pexels.com/photos/909/flowers-garden-colorful-colourful.jpg")!,imageview: iamge8)
            
            let downloadtask1 = Download(photoRecord: task1)
            let downloadtask2 = Download(photoRecord: task2)
            let downloadtask3 = Download(photoRecord: task3)
            let downloadtask4 = Download(photoRecord: task4)
            let downloadtask5 = Download(photoRecord: task5)
            let downloadtask6 = Download(photoRecord: task6)
            let downloadtask7 = Download(photoRecord: task7)
            let downloadtask8 = Download(photoRecord: task8)
            
            var nsoperationque = [NSOperation]()
            nsoperationque.append(downloadtask1)
            nsoperationque.append(downloadtask2)
            nsoperationque.append(downloadtask3)
            nsoperationque.append(downloadtask4)
            nsoperationque.append(downloadtask5)
            nsoperationque.append(downloadtask6)
            nsoperationque.append(downloadtask7)
            nsoperationque.append(downloadtask8)
            
            
            for (var i = nsoperationque.count-1 ; i > 0 ; i -= 1 )
            {
                var x = i - 1
                
                nsoperationque[x].addDependency(nsoperationque[i])
            }
            
            pendingOperations.downloadQueue.addOperations(nsoperationque, waitUntilFinished: false)

    These are some sample images url which we used for downloading. You can choose these according to your requirement. Now you can easily do things with downloaded data. Same approach will be followed to download either pdf, doc, image, audio and video file also. You can change URL of file accordingly.

    Hope it helps. Thanks for reading.

     

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: