Search code examples
swiftios-simulatorunzipnsfilemanagerdocuments

Documents folder working in Simulator but not iPad - Swift 2.1


The below code unzips a folder of images into a folder I create. and then loops through it and adds the names to an array, then loops through this array and retrieves those file names into an array of images.

It works perfectly on the simulator, but the data is empty when I do it on the iPad, it prints out nothing. I can only assume the folder isn't accessible or is being searched before the unzip has completed, but It shouldnt as I am using NSOperationQueue with a completion block.

func unzipData(objectData: NSManagedObject) {
        var paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
        let documentsDir = paths[0]
        let zipPath = documentsDir.stringByAppendingString("MyZipFiles")
        let folderPath = documentsDir.stringByAppendingString("/docLibFiles") // My folder name in document directory
        var optData = NSData(data: objectData.valueForKey("image") as! NSData)
        print(objectData.valueForKey("imageUrl") as! String)
        optData.writeToFile(zipPath, atomically: true)
        let success = fileManager.fileExistsAtPath(zipPath) as Bool
        if success == false {
            do {
                try! fileManager.createDirectoryAtPath(folderPath, withIntermediateDirectories: true, attributes: nil)
            }
        }
        queue.addOperationWithBlock { () -> Void in
            let operation1 = NSBlockOperation(block: {
                let unZipped = SSZipArchive.unzipFileAtPath(zipPath, toDestination: folderPath)

            })
            operation1.completionBlock = {
                    dispatch_async(dispatch_get_main_queue(), {
                        if queue.operationCount == 0 {
                            self.retrieveFiles()
                        }
                    })
            }
            queue.addOperation(operation1)
        }
    }

    func getDocumentsURL() -> NSURL {
        let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
        return documentsURL
    }

    func fileInDocumentsDirectory(filename: String) -> String {
        let fileURL = getDocumentsURL().URLByAppendingPathComponent(filename)
        return fileURL.path!
    }

    func retrieveFiles() {
        var paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
        let documentsDir = paths[0]
        let zipPath = documentsDir.stringByAppendingString("MyZipFiles")
        let folderPath = documentsDir.stringByAppendingString("/docLibFiles") // My folder name in document directory
        do {
            let filelist = try fileManager.contentsOfDirectoryAtPath(folderPath)
            print(filelist)
            print("filename")
            for filename in filelist {
                fileNameArray.append(filename)
            }
        } catch let error as NSError  {
            print("Could not save \(error)")
        }
        do {
            for item in fileNameArray {
                print("item \(item)")
                let imagePath = fileInDocumentsDirectory("docLibFiles/\(item)")
                imageArray.append(UIImage(contentsOfFile: imagePath)!)
            }
            print("filename array \(fileNameArray)")
            print("image array \(imageArray)")
            unzipDelegate!.unzipSet(imageArray)
        }
    }

Solution

  • Im not exactly sure why the initial problem was there, but my code was definitely overcomplicated. Ive sorted it now, hopefully it will help someone else in swift 2.1

    class UnzipDocument {
    let queue = NSOperationQueue() // BACKGROUND THREAD
        var imageArray = [UIImage]()
        var fileNameArray = [String]()
        var fileManager = NSFileManager.defaultManager()
    
    let compressedFile = NSTemporaryDirectory().stringByAppendingString("MyZipFiles")
    let uncompressedFolder = NSTemporaryDirectory().stringByAppendingString("MyUnzippedFiles")
    
    func unzipData(objectData: NSManagedObject){ // THIS IS BASICALLY NSDATA FROM CORE DATA FOR ME
        let optData = NSData(data: objectData.valueForKey("image") as! NSData)
        let success = fileManager.fileExistsAtPath(uncompressedFolder) as Bool // CREATES THE FOLDER IF IT DOESNT EXIST
        if success == false {
            do {
                try! fileManager.createDirectoryAtPath(uncompressedFolder, withIntermediateDirectories: true, attributes: nil)
            }
        }
        optData.writeToFile(compressedFile, atomically: true)
        queue.addOperationWithBlock { () -> Void in
            let operation1 = NSBlockOperation(block: {
                SSZipArchive.unzipFileAtPath(self.compressedFile, toDestination: self.uncompressedFolder)
            })
            operation1.completionBlock = {
                if queue.operationCount == 0 {
                    dispatch_async(dispatch_get_main_queue(), {
                        if queue.operationCount == 0 {
                            self.retrieveFiles()
                        }
                    })
                }
            }
            queue.addOperation(operation1)
        }
    }
    
    func retrieveFiles() {
        do {
            let filelist = try fileManager.contentsOfDirectoryAtPath(uncompressedFolder)
            print(filelist)
            print("filename")
            for filename in filelist {
                self.fileNameArray.append(filename)
            }
        } catch let error as NSError  {
            print("Could not save \(error)")
        }
        do {
            for item in fileNameArray {
                print("item \(item)")
                let imagePath = uncompressedFolder.stringByAppendingString("/\(item)")
                imageArray.append(UIImage(contentsOfFile: imagePath)!)
            }
            print("filename array \(fileNameArray)")
            print("image array \(imageArray)")
            unzipDelegate!.unzipSet(imageArray)
        } catch {
        }
    } 
    }
    

    and to delete the temp file/folder after use, so that it can be reused without any old documents remaining

    var fileManager = NSFileManager.defaultManager()
            let compressedFile = NSTemporaryDirectory().stringByAppendingString("MyZipFiles")
            let uncompressedFolder = NSTemporaryDirectory().stringByAppendingString("MyUnzippedFiles")
            do {
               try fileManager.removeItemAtPath(compressedFile)
                  try fileManager.removeItemAtPath(uncompressedFolder)
            } catch let error as NSError  {
                print("Could not save \(error)")
            }