[swift] Alamofire-SwiftyJSON을 사용하여 네트워크 요청에 캐시 로직 추가하기

많은 앱에서 네트워크 요청에 대한 캐싱 기능은 매우 중요합니다. 캐싱을 사용하면 동일한 데이터를 반복해서 가져올 필요 없이 이전에 요청한 결과를 재사용할 수 있습니다. 애플의 Foundation 프레임워크만을 사용해 구현하려면 몇 가지 복잡한 작업이 필요하지만, Alamofire-SwiftyJSON 라이브러리를 사용하면 간단하게 캐싱 기능을 구현할 수 있습니다.

1. Alamofire-SwiftyJSON 라이브러리 설치

먼저, Alamofire-SwiftyJSON 라이브러리를 설치해야 합니다. Cocoapods를 사용한다면 Podfile에 다음과 같은 코드를 추가합니다:

pod 'Alamofire-SwiftyJSON'

그리고 터미널에서 다음 명령을 실행하여 라이브러리를 설치합니다:

$ pod install

만약 Cocoapods를 사용하지 않는다면, 수동으로 AlamofireSwiftyJSON을 프로젝트에 추가해야 합니다.

2. 네트워크 요청에 캐싱 로직 추가하기

Alamofire-SwiftyJSON를 사용하여 네트워크 요청에 캐싱 기능을 추가하는 방법을 알아보겠습니다. 아래의 코드는 GET 요청에 대한 캐싱 기능을 구현한 예시입니다:

import Alamofire
import SwiftyJSON

let cacheTimeInterval: TimeInterval = 60 * 5 // 캐싱되는 데이터의 유효시간 (5분)

enum APIRouter: URLRequestConvertible {
    case fetchData

    var method: HTTPMethod {
        switch self {
        case .fetchData:
            return .get
        }
    }

    var path: String {
        switch self {
        case .fetchData:
            return "https://api.example.com/data"
        }
    }

    var parameters: Parameters? {
        switch self {
        case .fetchData:
            return nil
        }
    }

    func asURLRequest() throws -> URLRequest {
        let url = try path.asURL()

        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = method.rawValue

        return try URLEncoding.default.encode(urlRequest, with: parameters)
    }
}

class APIClient {
    static let shared = APIClient()

    var cachedData: JSON?

    private init() {}

    func fetchData(fromCache: Bool = false, completion: @escaping (JSON?, Error?) -> Void) {
        if let data = cachedData, fromCache { // 캐시에서 데이터를 가져옴
            completion(data, nil)
        } else {
            Alamofire.request(APIRouter.fetchData).responseJSON { response in
                switch response.result {
                case .success(let value):
                    let data = JSON(value)

                    // 캐시에 데이터를 저장
                    self.cachedData = data

                    completion(data, nil)
                case .failure(let error):
                    completion(nil, error)
                }
            }
        }
    }
}

위의 코드에서 APIClient 클래스는 싱글톤 인스턴스로 구현되어 있습니다. fetchData(fromCache:) 메서드는 fromCache 매개변수에 따라 캐시된 데이터를 반환하거나 네트워크 요청을 통해 데이터를 가져옵니다. 캐싱된 데이터는 cachedData에 저장되고, 캐시의 유효성은 cacheTimeInterval 상수로 설정한 유효시간으로 제어됩니다.

3. 사용 예시

위에서 정의한 APIClient 클래스를 사용하는 예시 코드입니다:

APIClient.shared.fetchData(fromCache: true) { data, error in
    if let error = error {
        print("네트워크 요청 실패: \(error.localizedDescription)")
    } else if let data = data {
        print("캐시된 데이터 사용: \(data)")

        // 데이터 사용 후, 새로운 데이터를 가져오기 위해서는 fromCache 매개변수를 false로 설정하여 서버에 요청합니다.
        APIClient.shared.fetchData(fromCache: false) { data, error in
            // ...
        }
    }
}

위의 예시 코드에서 fetchData(fromCache: true)를 호출하면 첫 번째로 캐시된 데이터를 사용합니다. 데이터 사용 후, fetchData(fromCache: false)를 호출하여 서버로부터 새로운 데이터를 가져오고 캐시를 갱신합니다.

결론

이렇게 Alamofire-SwiftyJSON을 사용하여 네트워크 요청에 캐시 로직을 추가하는 방법을 알아보았습니다. 캐싱을 통해 앱의 성능을 향상시키고 데이터 사용량을 줄일 수 있습니다. 이 예시를 참고하여 앱의 요구사항에 맞게 캐싱 기능을 구현해 보세요.

참고 자료