问题
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)
}
}
回答1:
In case of avoiding an error is generated by some trivial typos. Probably process paths in NSURL form
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let documentsDir = paths[0]
let url = NSURL(fileURLWithPath: documentsDir)
url.URLByAppendingPathComponent("MyZipFiles")
url.URLByAppendingPathComponent("docLibFiles")
回答2:
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)")
}
来源:https://stackoverflow.com/questions/35129835/documents-folder-working-in-simulator-but-not-ipad-swift-2-1