---
# System prepended metadata

title: '✏️ 13주차 \[8기\] B반 스터디'
tags: [toyo]

---

# ✏️ 13주차 \[8기\] B반 스터디

## 🗓2023-04-08

**참여자** : 리지, vetto, 송준

**진행자** : vetto

  
## \[금주의 실험🔥\] Cache

* 각 UI요소들의 역할은 아래와 같습니다.
* ImageView(2개): 받아온 이미지를 표시합니다.
* 이미지 받아오기(2개): URLSession을 통해 이미지 URL로부터 이미지를 받아와 ImageView에 표시합니다. 만약 캐시된 데이터가 있다면 캐시된 데이터를 활용합니다.
* 캐시 데이터가 없을 경우: 이미지를 요청한 후, “새로운 이미지를 받아왔습니다" 출력
* 캐시 데이터가 있을 경우: 캐시된 데이터를 활용한 후, “캐시된 데이터가 있습니다.” 출력
* 이미지 초기화: ImageView의 image를 nil로 만들어줍니다.
* 캐시 비우기: 저장된 캐시를 모두 제거합니다.
* 각 UI요소들이 의도대로 동작하도록 Cache를 이용하여 구현합니다. 
* 디스크에 저장하는 시도는 하지 않아도 됩니다.

### NSCache
```swift
struct NetworkManager {
    func loadImage(from imageURL: String, completion: @escaping ((Result<UIImage, NetworkError>) -> Void)) {
        guard let url = URL(string: imageURL) else { return }
        let urlRequest = URLRequest(url: url)
        
        let task = URLSession.shared.dataTask(with: urlRequest) { data, _, error in
            if error != nil {
                completion(.failure(.unknown))
                return
            }
            
            if let data = data {
                guard let result = UIImage(data: data) else {
                    completion(.failure(.decode))
                    return
                }
                completion(.success(result))
            }
        }
        task.resume()
    }
```

```swift
//ViewController에서 확인하는 코드
    private func fetchImage(from imageURL: String, imageView: UIImageView) {
        if let cachedImage = ImageCacheManager.shared.cachedImage(urlString: imageURL) {
            DispatchQueue.main.async {
                print("캐시된 데이터가 있습니다.")
                imageView.image = cachedImage
            }
            return
        }
        
        networkManager.loadImage(from: imageURL) { result in
            switch result {
            case .failure(let error):
                print(error.description)
            case .success(let image):
                ImageCacheManager.shared.setObject(image: image, urlString: imageURL)
                DispatchQueue.main.async {
                    imageView.image = image
                    print("새로운 이미지를 받아왔습니다.")
                }
            }
        }
    }
```



### URLCache
```swift
struct NetworkManager {
    
    func loadURLCachedImage(from imageURL: URLRequest, completion: @escaping ((Result<(Data), NetworkError>) -> Void)) {
        
        // MARK: task 생성
        let task = URLSession.shared.dataTask(with: imageURL) { data, response, error in
            // MARK: task resume이 되면서 실행
            if error != nil {
                completion(.failure(.unknown))
                return
            }
            
            guard response is HTTPURLResponse else {
                completion(.failure(.response))
                return
            }
            
            if let data = data,
               let response = response {
                let cachedResponse = CachedURLResponse(response: response, data: data)
                URLCache.shared.storeCachedResponse(cachedResponse, for: imageURL)
                print("새로 저장")
                completion(.success(data))
            }
        }
        
        // MARK: task 생성 후 실행되는 코드
        URLCache.shared.getCachedResponse(for: task) { cachedResponse in
            if let cachedResponse = cachedResponse {
                print("캐시된 데이터가 있습니다.")
                completion(.success(cachedResponse.data))
            } else {
                task.resume()
            }
        }
    }
}
```
```swift
// ViewController에서 실행하는 코드
    private func downloadImage(from imageURL: String, imageView: UIImageView) {
        guard let url = URL(string: imageURL) else { return }
        let request = URLRequest(url: url)
        
        networkManager.loadURLCachedImage(from: request) { result in
            switch result {
            case .failure(let error):
                print(error.description)
            case .success(let data):
                
                DispatchQueue.main.async {
                    let cachedImage = UIImage(data: data)
                    imageView.image = cachedImage
                }
                return
            }
        }
    }
```

###### tags: `toyo`