뉴스 애플리케이션을 사용하여 API 기사를 Realm에 캐시하여 유효 기간 내에 표시

회사에서 제작한 뉴스 애플리케이션NewsDigest에서 보도의 캐시를 수정했다.
좋은 캐시 방법을 알았기 때문에 그 방법의 Tips입니다.

캐시의 목적

  • API를 함부로 두드리지 않음
  • 빠른 기사 보기
  • 현금의 구조


    캐시가 있으면 캐시된 글을 표시할 수 있고, 캐시가 없거나 캐시가 만료되면 API를 누르면 글을 요청할 수 있습니다.

    WHEN
    DO
    캐시가 없는 경우
    API 두드리기
    유효 기간 내 캐시
    캐시 사용
    이런 규칙.

    이루어지다


    컨디션

  • Swift3
  • RealmSwift
  • 개체 정의


    여기서 Article Enity 및 Feed 객체는 다음과 같은 느낌으로 정의됩니다.

    ArticleEntity

    
    import RealmSwift
    import Unbox
    
    final class ArticleEntity: Object, Unboxable {
    
        dynamic var title: String = ""
        dynamic var url: String = ""
    
        required convenience init(unboxer: Unboxer) throws {
            self.init()
    
            self.title = try unboxer.unbox(key: "title")
            self.url = try unboxer.unbox(key: "url")
        }
    }
    
    

    Feed

    import RealmSwift
    import Unbox
    
    final class Feed: Object, Unboxable {
    
        /// ID
        dynamic var tabId: Int = 0
        /// 直近の記事
        var recentArticles: List<ArticleEntity> = List()
        // データの有効期限
        dynamic var expiredDate: String = ""
    
        override class func primaryKey() -> String? {
            return "tabId"
        }
    }
    
    
    API를 통해 접수된 JSON 형식의 기사를 언박스에서 괜찮다고 느낀 것을 아티컬에니티에 넣은 뒤 해당 기사 블록의 Arry를 피드에 넣고 태블릿(엔터테인먼트, 정치 등 라벨의 판별 id)을 키로 리얼m에 저장한다.
    column
    컨텐트
    예제
    key
    태그 번호
    103
    object
    문장집
    Feed
    Feed도 유효기간이 있습니다. 뷰에 글을 표시할 때 그것을 보고 캐시를 사용할지 여부를 판단합니다.

    Realm에 Feed 객체 쓰기

    import RealmSwift
    
        /// Realmに記事をキャッシュする
        func wirteToRealm(_ tabId: TabId, articles: [ArticleEntity]){
    
            let feed = Feed()
            feed.tabId = tabId.rawValue
            feed.recentArticles = List(articles)
            feed.expiredDate = Date(timeInterval: 60 * 30, since: Date()).toString() // 30分が期限
    
            do {
                let realm = try Realm()
    
                try realm.write {
                     // 追記: コメントでご指摘いただきました。deleteしなくても上書きされます                
                     // if let cache = realm.object(ofType: Feed.self, forPrimaryKey: tabId.rawValue) {
                     //   realm.delete(cache)
                     // }
                    realm.add(feed, update: true)
                }
            } catch let e {
    
            }
        }
    
    여기에 보관된 물건을 리얼엠 브라우저에서 펼친 경우는 다음과 같다.

    기분 좋네.
    PrimaryKey의tabId와articleEnity20건,유효기간String.

    유효 기간 내 캐시가 있는 경우 캐시를 사용하고 없으면 API를 두드립니다.


    네.마지막으로 하고 싶은 게 이거야.
    /// 有効期限が切れていないキャッシュがあればそちらを使い、なければAPIを叩く
        func fetch(_ tabId: TabId) -> Single<[ArticleEntity]> {
    
            do {
                let realm = try Realm()
    
                // キャッシュがあり、有効期限が現在時刻より未来だったらキャッシュを使う
                if let cache = realm.object(ofType: Feed.self, forPrimaryKey: tabId.rawValue),
                    cache.expiredDate > now { // <- 日付の比較はよしなに
    
                    let entities = Array(cache.recentArticles)
                    return Single<[ArticleEntity]>.just(entities)
                }
            } catch {
                logger?.error(error.localizedDescription)
            }
    
            // キャッシュがなければAPIを叩いたものを使う
            return fetchLatest(tabId)
        }
    
    이렇게 하면 30분 이내에 리얼m 캐시된 글이 표시되기 때문에 통신이 발생하지 않고 빠르게 글을 표시할 수 있다.(실제 NewsDigest의 유효기간은 조정 중)
    업데이트할 때 API로 바로 전화하시면 됩니다.

    총결산


    그러므로
    "캐시가 있으면 캐시된 글로 표시하고 캐시가 없거나 캐시가 만료되면 API 요청 글을 두드리기"를 실현했다.
    누구한테 도움이 됐으면 좋겠어요.

    통지하다


    빠른 성장!No.1 뉴스 벤처기업은 뉴스의 미래를 창조할 응용 엔지니어를 모집하고 있다
    https://www.wantedly.com/projects/78838

    좋은 웹페이지 즐겨찾기