@@ -5,6 +5,8 @@ import UIKit
55
66public class PIImageCache {
77
8+ //initialize
9+
810 private func myInit( ) {
911 folderCreate ( )
1012 prefetchQueueInit ( )
@@ -28,7 +30,28 @@ public class PIImageCache {
2830 Static . instance. myInit ( )
2931 return Static . instance
3032 }
31-
33+
34+ //public config method
35+
36+ public class Config {
37+ public var maxMemorySum : Int = 10 // 10 images
38+ public var limitByteSize : Int = 3 * 1024 * 1024 //3MB
39+ public var usingDiskCache : Bool = true
40+ public var diskCacheExpireMinutes : Int = 24 * 60 // 1 day
41+ public var prefetchOprationCount : Int = 5
42+ public var cacheRootDirectory : String = NSTemporaryDirectory ( )
43+ public var cacheFolderName : String = " PIImageCache "
44+ }
45+
46+ public func setConfig( config : Config ) {
47+ dispatch_semaphore_wait ( memorySemaphore, DISPATCH_TIME_FOREVER)
48+ self . config = config
49+ myInit ( )
50+ dispatch_semaphore_signal ( memorySemaphore)
51+ }
52+
53+ //public download method
54+
3255 public func get( url: NSURL ) -> UIImage ? {
3356 return perform ( url) . 0
3457 }
@@ -44,40 +67,76 @@ public class PIImageCache {
4467 }
4568 }
4669
47- private struct memoryCacheImage {
48- let image : UIImage
49- var timeStamp : Double
50- let url : NSURL
70+ public func prefetch ( urls : [ NSURL ] ) {
71+ for url in urls {
72+ prefetch ( url )
73+ }
5174 }
5275
53- private var now : Double {
54- get {
55- return NSDate ( ) . timeIntervalSince1970
76+ public func prefetch( url: NSURL ) {
77+ var op = NSOperation ( )
78+ op. completionBlock = {
79+ [ weak self] in
80+ self ? . downloadToDisk ( url)
5681 }
82+ prefetchQueue. addOperation ( op)
5783 }
5884
59- private var config : Config = Config ( )
60- public class Config {
61- public var maxMemorySum : Int = 10 // 10 images
62- public var limitByteSize : Int = 3 * 1024 * 1024 //3MB
63- public var usingDiskCache : Bool = true
64- public var diskCacheExpireMinutes : Int = 24 * 60 // 1 day
65- public var prefetchOprationCount : Int = 5
66- public var cacheRootDirectory : String = NSTemporaryDirectory ( )
67- public var cacheFolderName : String = " PIImageCache "
68- }
85+ //public delete method
6986
70- public func setConfig( config : Config ) {
71- dispatch_semaphore_wait ( memorySemaphore, DISPATCH_TIME_FOREVER)
72- self . config = config
73- myInit ( )
87+ public func allMemoryCacheDelete( ) {
88+ dispatch_semaphore_wait ( memorySemaphore, DISPATCH_TIME_FOREVER)
89+ memoryCache. removeAll ( keepCapacity: false )
7490 dispatch_semaphore_signal ( memorySemaphore)
7591 }
7692
93+ public func allDiskCacheDelete( ) {
94+ let path = PIImageCache . folderPath ( config)
95+ dispatch_semaphore_wait ( diskSemaphore, DISPATCH_TIME_FOREVER)
96+ let allFileName : [ String ] ? = fileManager. contentsOfDirectoryAtPath ( path, error: nil ) as? [ String ]
97+ if let all = allFileName {
98+ for fileName in all {
99+ fileManager. removeItemAtPath ( path + fileName, error: nil )
100+ }
101+ }
102+ folderCreate ( )
103+ dispatch_semaphore_signal ( diskSemaphore)
104+ }
105+
106+ public func oldDiskCacheDelete( ) {
107+ let path = PIImageCache . folderPath ( config)
108+ dispatch_semaphore_wait ( diskSemaphore, DISPATCH_TIME_FOREVER)
109+ let allFileName : [ String ] ? = fileManager. contentsOfDirectoryAtPath ( path, error: nil ) as? [ String ]
110+ if let all = allFileName {
111+ for fileName in all {
112+ if let attr = fileManager. attributesOfItemAtPath ( path + fileName, error: nil ) {
113+ let diff = NSDate ( ) . timeIntervalSinceDate ( ( attr [ NSFileModificationDate] as? NSDate ) ?? NSDate ( ) )
114+ if Double ( diff) > Double ( config. diskCacheExpireMinutes * 60 ) {
115+ fileManager. removeItemAtPath ( path + fileName, error: nil )
116+ }
117+ }
118+ }
119+ }
120+ folderCreate ( )
121+ dispatch_semaphore_signal ( diskSemaphore)
122+ }
123+
124+ //member
125+
126+ private var config : Config = Config ( )
77127 private var memoryCache : [ memoryCacheImage ] = [ ]
78128 private var memorySemaphore = dispatch_semaphore_create ( 1 )
79129 private var diskSemaphore = dispatch_semaphore_create ( 1 )
80130 private let fileManager = NSFileManager . defaultManager ( )
131+ private let prefetchQueue = NSOperationQueue ( )
132+
133+ private struct memoryCacheImage {
134+ let image : UIImage
135+ var timeStamp : Double
136+ let url : NSURL
137+ }
138+
139+ // memory cache
81140
82141 private func memoryCacheRead( url: NSURL ) -> UIImage ? {
83142 for var i= 0 ; i< memoryCache. count; i++ {
@@ -116,29 +175,8 @@ public class PIImageCache {
116175 }
117176 }
118177
119- private func folderCreate( ) {
120- let path = " \( config. cacheRootDirectory) \( config. cacheFolderName) / "
121- if fileManager. createDirectoryAtPath (
122- path,
123- withIntermediateDirectories: false ,
124- attributes: nil ,
125- error: nil ) { }
126- }
127-
128- private class func filePath( url: NSURL , config: Config ) -> String ? {
129- if let urlstr = url. absoluteString {
130- var code = " "
131- for char in urlstr. utf8 {
132- code = code + " u \( char) "
133- }
134- return " \( config. cacheRootDirectory) \( config. cacheFolderName) / \( code) "
135- }
136- return nil
137- }
178+ //disk cache
138179
139- private class func folderPath( config: Config ) -> String {
140- return " \( config. cacheRootDirectory) \( config. cacheFolderName) / "
141- }
142180
143181 private func diskCacheRead( url: NSURL ) -> UIImage ? {
144182 if let path = PIImageCache . filePath ( url, config: config) {
@@ -153,41 +191,10 @@ public class PIImageCache {
153191 }
154192 }
155193
156- public func allDiskCacheDelete( ) {
157- let path = PIImageCache . folderPath ( config)
158- dispatch_semaphore_wait ( diskSemaphore, DISPATCH_TIME_FOREVER)
159- let allFileName : [ String ] ? = fileManager. contentsOfDirectoryAtPath ( path, error: nil ) as? [ String ]
160- if let all = allFileName {
161- for fileName in all {
162- fileManager. removeItemAtPath ( path + fileName, error: nil )
163- }
164- }
165- folderCreate ( )
166- dispatch_semaphore_signal ( diskSemaphore)
167- }
168-
169- public func oldDiskCacheDelete( ) {
170- let path = PIImageCache . folderPath ( config)
171- dispatch_semaphore_wait ( diskSemaphore, DISPATCH_TIME_FOREVER)
172- let allFileName : [ String ] ? = fileManager. contentsOfDirectoryAtPath ( path, error: nil ) as? [ String ]
173- if let all = allFileName {
174- for fileName in all {
175- if let attr = fileManager. attributesOfItemAtPath ( path + fileName, error: nil ) {
176- let diff = NSDate ( ) . timeIntervalSinceDate ( ( attr [ NSFileModificationDate] as? NSDate ) ?? NSDate ( ) )
177- if Double ( diff) > Double ( config. diskCacheExpireMinutes * 60 ) {
178- fileManager. removeItemAtPath ( path + fileName, error: nil )
179- }
180- }
181- }
182- }
183- folderCreate ( )
184- dispatch_semaphore_signal ( diskSemaphore)
185- }
194+ //private download
186195
187- public func allMemoryCacheDelete( ) {
188- dispatch_semaphore_wait ( memorySemaphore, DISPATCH_TIME_FOREVER)
189- memoryCache. removeAll ( keepCapacity: false )
190- dispatch_semaphore_signal ( memorySemaphore)
196+ internal enum Result {
197+ case Mishit, MemoryHit, DiskHit
191198 }
192199
193200 internal func download( url: NSURL ) -> ( UIImage , byteSize: Int ) ? {
@@ -203,10 +210,6 @@ public class PIImageCache {
203210 return nil
204211 }
205212
206- internal enum Result {
207- case Mishit, MemoryHit, DiskHit
208- }
209-
210213 internal func perform( url: NSURL ) -> ( UIImage ? , Result ) {
211214
212215 //memory read
@@ -254,28 +257,6 @@ public class PIImageCache {
254257 return ( maybeImage? . 0 , . Mishit)
255258 }
256259
257- let prefetchQueue = NSOperationQueue ( )
258-
259- private func prefetchQueueInit( ) {
260- prefetchQueue. maxConcurrentOperationCount = config. prefetchOprationCount
261- prefetchQueue. qualityOfService = NSQualityOfService . Background
262- }
263-
264- public func prefetch( urls: [ NSURL ] ) {
265- for url in urls {
266- prefetch ( url)
267- }
268- }
269-
270- public func prefetch( url: NSURL ) {
271- var op = NSOperation ( )
272- op. completionBlock = {
273- [ weak self] in
274- self ? . downloadToDisk ( url)
275- }
276- prefetchQueue. addOperation ( op)
277- }
278-
279260 private func downloadToDisk( url: NSURL ) {
280261 let path = PIImageCache . filePath ( url, config: config)
281262 if path == nil { return }
@@ -290,4 +271,41 @@ public class PIImageCache {
290271 }
291272 }
292273
274+ //util
275+
276+ private var now : Double {
277+ get {
278+ return NSDate ( ) . timeIntervalSince1970
279+ }
280+ }
281+
282+ private func folderCreate( ) {
283+ let path = " \( config. cacheRootDirectory) \( config. cacheFolderName) / "
284+ if fileManager. createDirectoryAtPath (
285+ path,
286+ withIntermediateDirectories: false ,
287+ attributes: nil ,
288+ error: nil ) { }
289+ }
290+
291+ private class func filePath( url: NSURL , config: Config ) -> String ? {
292+ if let urlstr = url. absoluteString {
293+ var code = " "
294+ for char in urlstr. utf8 {
295+ code = code + " u \( char) "
296+ }
297+ return " \( config. cacheRootDirectory) \( config. cacheFolderName) / \( code) "
298+ }
299+ return nil
300+ }
301+
302+ private class func folderPath( config: Config ) -> String {
303+ return " \( config. cacheRootDirectory) \( config. cacheFolderName) / "
304+ }
305+
306+ private func prefetchQueueInit( ) {
307+ prefetchQueue. maxConcurrentOperationCount = config. prefetchOprationCount
308+ prefetchQueue. qualityOfService = NSQualityOfService . Background
309+ }
310+
293311}
0 commit comments