Sfoglia il codice sorgente

Merge pull request #158 from onevcat/AdventureProjects-master

Adventure projects master
Wei Wang 10 anni fa
parent
commit
e924867fd3
2 ha cambiato i file con 88 aggiunte e 79 eliminazioni
  1. 82 79
      Kingfisher/ImageCache.swift
  2. 6 0
      KingfisherTests/ImageCacheTests.swift

+ 82 - 79
Kingfisher/ImageCache.swift

@@ -79,9 +79,11 @@ public class ImageCache {
     
     //Disk
     private let ioQueue: dispatch_queue_t
-    private let diskCachePath: String
     private var fileManager: NSFileManager!
     
+    ///The disk cache location.
+    public let diskCachePath: String
+    
     /// The longest time duration of the cache being stored in disk. Default is 1 week.
     public var maxCachePeriodInSecond = defaultMaxCachePeriodInSecond
     
@@ -98,11 +100,13 @@ public class ImageCache {
     /**
     Init method. Passing a name for the cache. It represents a cache folder in the memory and disk.
     
-    - parameter name: Name of the cache. It will be used as the memory cache name and the disk cache folder name. This value should not be an empty string.
+    - parameter name: Name of the cache. It will be used as the memory cache name and the disk cache folder name appending to the cache path. This value should not be an empty string.
+    - parameter path: Optional - Location of cache path on disk. If `nil` is passed (the default value), 
+                      the cache folder in of your app will be used. If you want to cache some user generating images, you could pass the Documentation path here.
     
     - returns: The cache object.
     */
-    public init(name: String) {
+    public init(name: String, path: String? = nil) {
         
         if name.isEmpty {
             fatalError("[Kingfisher] You should specify a name for the cache. A cache with empty name is not permitted.")
@@ -111,8 +115,8 @@ public class ImageCache {
         let cacheName = cacheReverseDNS + name
         memoryCache.name = cacheName
         
-        let paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true)
-        diskCachePath = (paths.first! as NSString).stringByAppendingPathComponent(cacheName)
+        let dstPath = path ?? NSSearchPathForDirectoriesInDomains(.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true).first!
+        diskCachePath = (dstPath as NSString).stringByAppendingPathComponent(cacheName)
         
         ioQueue = dispatch_queue_create(ioQueueName + name, DISPATCH_QUEUE_SERIAL)
         processQueue = dispatch_queue_create(processQueueName + name, DISPATCH_QUEUE_CONCURRENT)
@@ -401,101 +405,100 @@ extension ImageCache {
         // Do things in cocurrent io queue
         dispatch_async(ioQueue, { () -> Void in
             let diskCacheURL = NSURL(fileURLWithPath: self.diskCachePath)
-                
-                let resourceKeys = [NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey]
-                let expiredDate = NSDate(timeIntervalSinceNow: -self.maxCachePeriodInSecond)
-                var cachedFiles = [NSURL: [NSObject: AnyObject]]()
-                var URLsToDelete = [NSURL]()
-                
-                var diskCacheSize: UInt = 0
-                
-                if let fileEnumerator = self.fileManager.enumeratorAtURL(diskCacheURL, includingPropertiesForKeys: resourceKeys, options: NSDirectoryEnumerationOptions.SkipsHiddenFiles, errorHandler: nil),
-                                 urls = fileEnumerator.allObjects as? [NSURL] {
-                    for fileURL in urls {
-                            
-                        do {
-                            let resourceValues = try fileURL.resourceValuesForKeys(resourceKeys)
-                            // If it is a Directory. Continue to next file URL.
-                            if let isDirectory = resourceValues[NSURLIsDirectoryKey] as? NSNumber {
-                                if isDirectory.boolValue {
-                                    continue
-                                }
-                            }
+            let resourceKeys = [NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey]
+            let expiredDate = NSDate(timeIntervalSinceNow: -self.maxCachePeriodInSecond)
+            var cachedFiles = [NSURL: [NSObject: AnyObject]]()
+            var URLsToDelete = [NSURL]()
+            
+            var diskCacheSize: UInt = 0
+            
+            if let fileEnumerator = self.fileManager.enumeratorAtURL(diskCacheURL, includingPropertiesForKeys: resourceKeys, options: NSDirectoryEnumerationOptions.SkipsHiddenFiles, errorHandler: nil),
+                             urls = fileEnumerator.allObjects as? [NSURL] {
+                for fileURL in urls {
                             
-                            // If this file is expired, add it to URLsToDelete
-                            if let modificationDate = resourceValues[NSURLContentModificationDateKey] as? NSDate {
-                                if modificationDate.laterDate(expiredDate) == expiredDate {
-                                    URLsToDelete.append(fileURL)
-                                    continue
-                                }
+                    do {
+                        let resourceValues = try fileURL.resourceValuesForKeys(resourceKeys)
+                        // If it is a Directory. Continue to next file URL.
+                        if let isDirectory = resourceValues[NSURLIsDirectoryKey] as? NSNumber {
+                            if isDirectory.boolValue {
+                                continue
                             }
+                        }
                             
-                            if let fileSize = resourceValues[NSURLTotalFileAllocatedSizeKey] as? NSNumber {
-                                diskCacheSize += fileSize.unsignedLongValue
-                                cachedFiles[fileURL] = resourceValues
+                        // If this file is expired, add it to URLsToDelete
+                        if let modificationDate = resourceValues[NSURLContentModificationDateKey] as? NSDate {
+                            if modificationDate.laterDate(expiredDate) == expiredDate {
+                                URLsToDelete.append(fileURL)
+                                continue
                             }
-                        } catch _ {
                         }
                         
+                        if let fileSize = resourceValues[NSURLTotalFileAllocatedSizeKey] as? NSNumber {
+                            diskCacheSize += fileSize.unsignedLongValue
+                            cachedFiles[fileURL] = resourceValues
+                        }
+                    } catch _ {
                     }
+                        
                 }
+            }
                 
-                for fileURL in URLsToDelete {
-                    do {
-                        try self.fileManager.removeItemAtURL(fileURL)
-                    } catch _ {
-                    }
+            for fileURL in URLsToDelete {
+                do {
+                    try self.fileManager.removeItemAtURL(fileURL)
+                } catch _ {
                 }
+            }
                 
-                if self.maxDiskCacheSize > 0 && diskCacheSize > self.maxDiskCacheSize {
-                    let targetSize = self.maxDiskCacheSize / 2
+            if self.maxDiskCacheSize > 0 && diskCacheSize > self.maxDiskCacheSize {
+                let targetSize = self.maxDiskCacheSize / 2
                     
-                    // Sort files by last modify date. We want to clean from the oldest files.
-                    let sortedFiles = cachedFiles.keysSortedByValue({ (resourceValue1, resourceValue2) -> Bool in
-
-                        if let date1 = resourceValue1[NSURLContentModificationDateKey] as? NSDate {
-                            if let date2 = resourceValue2[NSURLContentModificationDateKey] as? NSDate {
-                                return date1.compare(date2) == .OrderedAscending
-                            }
-                        }
-                        // Not valid date information. This should not happen. Just in case.
-                        return true
-                    })
+                // Sort files by last modify date. We want to clean from the oldest files.
+                let sortedFiles = cachedFiles.keysSortedByValue({ (resourceValue1, resourceValue2) -> Bool in
                     
-                    for fileURL in sortedFiles {
-                        
-                        do {
-                            try self.fileManager.removeItemAtURL(fileURL)
-                        } catch {
-                            
-                        }
-                        
-                        URLsToDelete.append(fileURL)
-                        
-                        if let fileSize = cachedFiles[fileURL]?[NSURLTotalFileAllocatedSizeKey] as? NSNumber {
-                            diskCacheSize -= fileSize.unsignedLongValue
-                        }
-                        
-                        if diskCacheSize < targetSize {
-                            break
+                    if let date1 = resourceValue1[NSURLContentModificationDateKey] as? NSDate {
+                        if let date2 = resourceValue2[NSURLContentModificationDateKey] as? NSDate {
+                            return date1.compare(date2) == .OrderedAscending
                         }
                     }
-                }
+                    // Not valid date information. This should not happen. Just in case.
+                    return true
+                })
                 
-                dispatch_async(dispatch_get_main_queue(), { () -> Void in
+                for fileURL in sortedFiles {
                     
-                    if URLsToDelete.count != 0 {
-                        let cleanedHashes = URLsToDelete.map({ (url) -> String in
-                            return url.lastPathComponent!
-                        })
+                    do {
+                        try self.fileManager.removeItemAtURL(fileURL)
+                    } catch {
                         
-                        NSNotificationCenter.defaultCenter().postNotificationName(KingfisherDidCleanDiskCacheNotification, object: self, userInfo: [KingfisherDiskCacheCleanedHashKey: cleanedHashes])
                     }
+                        
+                    URLsToDelete.append(fileURL)
                     
-                    if let completionHandler = completionHandler {
-                        completionHandler()
+                    if let fileSize = cachedFiles[fileURL]?[NSURLTotalFileAllocatedSizeKey] as? NSNumber {
+                        diskCacheSize -= fileSize.unsignedLongValue
                     }
-                })
+                    
+                    if diskCacheSize < targetSize {
+                        break
+                    }
+                }
+            }
+                
+            dispatch_async(dispatch_get_main_queue(), { () -> Void in
+                
+                if URLsToDelete.count != 0 {
+                    let cleanedHashes = URLsToDelete.map({ (url) -> String in
+                        return url.lastPathComponent!
+                    })
+                    
+                    NSNotificationCenter.defaultCenter().postNotificationName(KingfisherDidCleanDiskCacheNotification, object: self, userInfo: [KingfisherDiskCacheCleanedHashKey: cleanedHashes])
+                }
+                
+                if let completionHandler = completionHandler {
+                    completionHandler()
+                }
+            })
         })
     }
     

+ 6 - 0
KingfisherTests/ImageCacheTests.swift

@@ -51,6 +51,12 @@ class ImageCacheTests: XCTestCase {
         observer = nil
     }
     
+    func testCustomCachePath() {
+        let customPath = "/path/to/image/cache"
+        let cache = ImageCache(name: "test", path: customPath)
+        XCTAssertEqual(cache.diskCachePath, customPath + "/com.onevcat.Kingfisher.ImageCache.test", "Custom disk cache path set correctly")
+    }
+    
     func testMaxCachePeriodInSecond() {
         cache.maxCachePeriodInSecond = 1
         XCTAssert(cache.maxCachePeriodInSecond == 1, "maxCachePeriodInSecond should be able to be set.")