투케이2K

245. (ios/swift) NSCache 캐시 사용해 http 요청 이미지 표시 및 재요청 시 저장 된 캐시 사용 표시 수행 - URLSession 본문

IOS

245. (ios/swift) NSCache 캐시 사용해 http 요청 이미지 표시 및 재요청 시 저장 된 캐시 사용 표시 수행 - URLSession

투케이2K 2022. 11. 5. 13:34

[개발 환경 설정]

개발 툴 : XCODE

개발 언어 : SWIFT

 

[호출 : 소스 코드]

    // MARK: - [테스트 메인 함수 정의 실시]
    func testMain() {
        print("")
        print("====================================")
        print("[\(self.ACTIVITY_NAME) >> testMain() :: 테스트 함수 시작 실시]")
        print("====================================")
        print("")
        
        
        /*
         // -----------------------------
         [요약 설명]
         // -----------------------------
         1. 사전 info plist 설정 :
         
         App Transport Security Settings >> Allow Arbitrary Loads >> YES
         // -----------------------------
         */
        
        
        // [비동기 처리 수행]
        DispatchQueue.main.async {
            
            // [URL 지정 및 파라미터 값 지정 실시]
            var urlComponents = URLComponents(string: "https://i.pravatar.cc/150?")
            let paramQuery_1 = URLQueryItem(name: "img", value: "3")
            urlComponents?.queryItems?.append(paramQuery_1) // 파라미터 지정
            
            
            // [http 통신 타입 및 헤더 지정 실시]
            var requestURL = URLRequest(url: (urlComponents?.url)!)
            requestURL.httpMethod = "GET" // GET
            requestURL.addValue("application/x-www-form-urlencoded; charset=utf-8;", forHTTPHeaderField: "Content-Type")
            requestURL.addValue("no-cache", forHTTPHeaderField: "Cache-Control")

            
            
            //------------------------------
            // MARK: [이미지 캐시 여부 체크 실시]
            if let image = ImageCacheChecker.shared.getImage(requestURL.description) {
                print("")
                print("====================================")
                print("[A_Intro >> testMain :: http get 요청 실시]")
                print("로 직 : 이미지 캐시 사용 표시")
                print("requestURL : \(requestURL.description)")
                print("image : \(image)")
                print("====================================")
                print("")
                
                // [이미지 뷰에 지정]
                self.imageView.image = image
                return
            }
            else {
                print("")
                print("====================================")
                print("[A_Intro >> testMain :: http get 요청 실시]")
                print("로 직 : 이미지 캐시 없음")
                print("====================================")
                print("")
            }
            //------------------------------

            
            // [http 요쳥을 위한 URLSessionDataTask 생성]
            print("")
            print("====================================")
            print("[A_Intro >> testMain :: http get 요청 실시]")
            print("url : ", requestURL.description)
            print("header : ", requestURL.allHTTPHeaderFields?.description ?? "")
            print("====================================")
            print("")
            let dataTask = URLSession.shared.dataTask(with: requestURL) { (data, response, error) in

                // [error가 존재하면 종료]
                guard error == nil else {
                    print("")
                    print("====================================")
                    print("[A_Intro >> testMain :: http get 요청 실패]")
                    print("fail :: ", error?.localizedDescription ?? "")
                    print("====================================")
                    print("")
                    return
                }

                // [status 코드 체크 실시]
                let successsRange = 200..<300
                guard let statusCode = (response as? HTTPURLResponse)?.statusCode, successsRange.contains(statusCode)
                else {
                    print("")
                    print("====================================")
                    print("[A_Intro >> testMain :: http get 요청 에러]")
                    print("error :: ", (response as? HTTPURLResponse)?.statusCode ?? 0)
                    print("msg :: ", (response as? HTTPURLResponse)?.description ?? "")
                    print("====================================")
                    print("")
                    return
                }

                // [response 데이터 획득]
                let resultCode = (response as? HTTPURLResponse)?.statusCode ?? 0
                let resultData = data! // 데이터 길이
                let resultMimeType = response?.mimeType // 응답 데이터 타입 확인
                
                
                // [응답 데이터 타입이 이미지 파일 인지 확인 실시]
                if ((resultMimeType?.lowercased().contains("image")) != nil) {
                    print("")
                    print("====================================")
                    print("[A_Intro >> testMain :: http get 요청 성공]")
                    print("resultCode :: ", resultCode)
                    print("resultData :: ", resultData)
                    print("resultMimeType :: ", resultMimeType ?? "")
                    print("====================================")
                    print("")
                    
                    
                    DispatchQueue.main.async {
                        
                        // [응답 데이터를 이미지로 받음]
                        let image = UIImage(data: data!)
                        
                        // [이미지 뷰에 표시 수행 실시]
                        self.imageView.image = image
                        
                        // MARK: [이미지 캐시 저장]
                        ImageCacheChecker.shared.setImage(requestURL.description, image: image!)
                    }
                }
                else {
                    print("")
                    print("====================================")
                    print("[A_Intro >> testMain :: http get 요청 에러]")
                    print("resultCode :: ", resultCode)
                    print("error :: ", "파일 형식이 이미지 파일이 아닙니다")
                    print("mimeType :: ", resultMimeType ?? "")
                    print("====================================")
                    print("")
                }
            }

            // network 통신 실행
            dataTask.resume()

        }
    }
 

[캐시 정의 클래스 : 소스 코드]

import Foundation
import UIKit

class ImageCacheChecker {
    
    
    /*
     -------------------------------
     MARK: [클래스 설명]
     -------------------------------
     1. 이미지 캐시 체크 여부 수행 클래스
     -------------------------------
     2. 호출 방법 :
     
     if let image = ImageCacheChecker.shared.getImage(requestURL.description) {
         print("")
         print("====================================")
         print("[A_Intro >> testMain :: http get 요청 실시]")
         print("로 직 : 이미지 캐시 사용 표시")
         print("requestURL : \(requestURL.description)")
         print("image : \(image)")
         print("====================================")
         print("")
         
         // [이미지 뷰에 지정]
         self.imageView.image = image
         return
     }
     
     ------------------
     
     // [응답 데이터를 이미지로 받음]
     let image = UIImage(data: data!)
     
     // [이미지 뷰에 표시 수행 실시]
     self.imageView.image = image
     
     // MARK: [이미지 캐시 저장]
     ImageCacheChecker.shared.setImage(requestURL.description, image: image!)
     
     -------------------------------
     */
    
    
    // MARK: [전역 변수 선언]
    static let shared = ImageCacheChecker() // [싱글톤]
    private init() {}
    private let cache = NSCache<NSString, UIImage>()
    
    
    // MARK: [set 메소드]
    func setImage(_ urlStr: String, image: UIImage) {
        self.cache.setObject(image, forKey: urlStr as NSString)
    }
    
    
    // MARK: [get 메소드]
    func getImage(_ urlStr: String) -> UIImage? {
        self.cache.object(forKey: urlStr as NSString)
    }
    
    
} // [클래스 종료]
 

[결과 출력]


 

반응형
Comments