@@ -8,6 +8,8 @@ private let networkSession: URLSession = {
88} ( )
99
1010private let imageCache = NSCache < NSString , UIImage > ( )
11+ private let imageFetchQueue = DispatchQueue ( label: " arkit.imageFetchQueue " )
12+ private var pendingImageRequests : [ String : [ ( UIImage ? ) -> Void ] ] = [ : ]
1113
1214func prefetchImagesIfNeeded( _ names: [ String ] , completion: @escaping ( ) -> Void ) {
1315 let urls = names. compactMap { URL ( string: $0) } . filter {
@@ -40,6 +42,20 @@ func fetchNetworkImageIfNeeded(_ url: URL, completion: @escaping (UIImage?) -> V
4042 completion ( cached)
4143 return
4244 }
45+ let cacheKey = url. absoluteString
46+ var shouldStartRequest = false
47+ imageFetchQueue. sync {
48+ if pendingImageRequests [ cacheKey] != nil {
49+ pendingImageRequests [ cacheKey] ? . append ( completion)
50+ } else {
51+ pendingImageRequests [ cacheKey] = [ completion]
52+ shouldStartRequest = true
53+ }
54+ }
55+ if !shouldStartRequest {
56+ return
57+ }
58+
4359 var request = URLRequest ( url: url)
4460 request. cachePolicy = . reloadIgnoringLocalCacheData
4561 request. setValue ( " Mozilla/5.0 " , forHTTPHeaderField: " User-Agent " )
@@ -58,13 +74,15 @@ func fetchNetworkImageIfNeeded(_ url: URL, completion: @escaping (UIImage?) -> V
5874 " domain: \( nsError. domain) code: \( nsError. code) " +
5975 " userInfo: \( nsError. userInfo) "
6076 )
61- completion ( nil )
77+ let completions = imageFetchQueue. sync { pendingImageRequests. removeValue ( forKey: cacheKey) } ?? [ ]
78+ completions. forEach { $0 ( nil ) }
6279 return
6380 }
6481
6582 guard let data = data else {
6683 debugPrint ( " getImageByName: network returned no data for \( url. absoluteString) " )
67- completion ( nil )
84+ let completions = imageFetchQueue. sync { pendingImageRequests. removeValue ( forKey: cacheKey) } ?? [ ]
85+ completions. forEach { $0 ( nil ) }
6886 return
6987 }
7088
@@ -74,7 +92,8 @@ func fetchNetworkImageIfNeeded(_ url: URL, completion: @escaping (UIImage?) -> V
7492 } else {
7593 imageCache. setObject ( img!, forKey: url. absoluteString as NSString )
7694 }
77- completion ( img)
95+ let completions = imageFetchQueue. sync { pendingImageRequests. removeValue ( forKey: cacheKey) } ?? [ ]
96+ completions. forEach { $0 ( img) }
7897 }
7998 task. resume ( )
8099}
0 commit comments