[swift] SwiftyUserDefaults를 사용하여 캐시 데이터 만료 설정 관리하기

캐시 데이터는 애플리케이션에서 빠른 데이터 액세스를 위해 사용되는 중요한 요소입니다. 그러나 캐시 데이터가 오래되면 업데이트되지 않은 정보를 제공할 수 있기 때문에 만료 관리가 필요합니다. 이번 글에서는 Swift에서 SwiftyUserDefaults 라이브러리를 사용하여 캐시 데이터의 만료 설정을 관리하는 방법에 대해 알아보겠습니다.

SwiftyUserDefaults란?

SwiftyUserDefaults는 개발자가 UserDefaults를 사용할 때 편리한 기능을 제공하는 Swift 라이브러리입니다. UserDefaults를 사용하는데 일반적으로 반복되는 코드를 줄여주고, 타입 안전성을 제공하여 개발자의 생산성을 향상시켜줍니다.

만료 설정을 위한 SwiftyUserDefaults 확장

SwiftyUserDefaults를 사용하여 캐시 데이터의 만료를 설정하려면 다음과 같이 확장을 만들어야 합니다.

import SwiftyUserDefaults

extension DefaultsKeys {
    static let cacheExpirationDate = DefaultsKey<Date?>("cacheExpirationDate")
}

extension DefaultsAdapter: ExpiringCacheProtocol {
    var expirationDate: Date? {
        get { Defaults[.cacheExpirationDate] }
        set { Defaults[.cacheExpirationDate] = newValue }
    }
    
    func isCacheExpired() -> Bool {
        guard let expirationDate = expirationDate else { return true }
        return Date() > expirationDate
    }
}

protocol ExpiringCacheProtocol {
    var expirationDate: Date? { get set }
    func isCacheExpired() -> Bool
}

위의 코드에서는 DefaultsKeys를 확장하여 cacheExpirationDate라는 새로운 키타입을 정의합니다. 이 키타입은 캐시 데이터의 만료 날짜를 저장하는 데 사용됩니다. DefaultsAdapterExpiringCacheProtocol을 준수하도록 확장됩니다. 이 프로토콜은 캐시 데이터의 만료 날짜를 검사하는 기능을 제공합니다.

캐시 데이터 저장 및 만료 관리

이제 ExpiringCacheProtocol을 준수하는 객체를 사용하여 캐시 데이터 저장 및 만료 관리를 할 수 있습니다. 예를 들어, CacheManager라는 클래스를 만들어 다음과 같이 사용할 수 있습니다.

struct CacheManager<T: Codable> {
    private let adapter: DefaultsAdapter
    
    init(adapter: DefaultsAdapter) {
        self.adapter = adapter
    }
    
    func setCache(data: T, expirationDate: Date) {
        adapter.expirationDate = expirationDate
        let encoder = JSONEncoder()
        if let encodedData = try? encoder.encode(data) {
            Defaults[.cacheData] = encodedData
        }
    }
    
    func getCache() -> T? {
        if adapter.isCacheExpired() {
            return nil
        }
        
        if let encodedData = Defaults[.cacheData] {
            let decoder = JSONDecoder()
            if let decodedData = try? decoder.decode(T.self, from: encodedData) {
                return decodedData
            }
        }
        return nil
    }
}

CacheManagerExpiringCacheProtocol을 준수하는 DefaultsAdapter 객체를 인자로 받아 초기화됩니다. setCache 메서드는 데이터와 만료 날짜를 받아 캐시를 저장합니다. getCache 메서드는 캐시 데이터를 가져오고 만료 여부를 확인합니다.

사용 예시

struct User: Codable {
    let name: String
    let age: Int
}

let cacheManager = CacheManager<User>(adapter: DefaultsAdapter())
let user = User(name: "John", age: 30)
let expirationDate = Date().addingTimeInterval(300) // 5분 후 만료

cacheManager.setCache(data: user, expirationDate: expirationDate)

let cachedUser = cacheManager.getCache()

위의 예시에서는 User 구조체를 만들어 캐시 데이터로 저장하고, 5분 후에 만료되도록 설정하고 있습니다. cachedUser를 가져올 때 getCache 메서드는 만료 여부를 확인하여 만료되지 않은 경우에만 데이터를 반환합니다.

결론

SwiftyUserDefaults를 사용하여 캐시 데이터의 만료 설정을 관리하는 방법에 대해 알아보았습니다. 이를 통해 애플리케이션에서 캐싱 기능을 효과적으로 활용하여 데이터 액세스 성능을 향상시킬 수 있습니다.