Welcome to mirror list, hosted at ThFree Co, Russian Federation.

BannersCache.swift « Ads « Core « Maps « iphone - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: de12ca0fec490f72a2100ebb3d7ac98ca27bc7c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import Crashlytics
import MyTrackerSDK

@objc (MWMBannersCache)
final class BannersCache: NSObject {
  static let cache = BannersCache()
  private override init() {}

  private enum LoadState {
    case notLoaded(BannerType)
    case loaded(BannerType)
    case error
  }

  typealias Completion = (MWMBanner, Bool) -> Void

  private var cache: [BannerType : Banner] = [:]
  private var requests: [BannerType : Banner] = [:]
  private var completion: Completion?
  private var loadStates: [LoadState]!
  private var cacheOnly = false

  private func onCompletion(isAsync: Bool) {
    guard let completion = completion else { return }
    var banner: Banner?
    statesLoop: for loadState in loadStates {
      switch loadState {
      case .notLoaded(let type):
        banner = cache[type]
        break statesLoop
      case .loaded(let type):
        banner = cache[type]
        break statesLoop
      case .error: continue
      }
    }
    if let banner = banner {
      Statistics.logEvent(kStatPlacePageBannerShow, withParameters: banner.statisticsDescription)
      MRMyTracker.trackEvent(withName: kStatPlacePageBannerShow)
      completion(banner, isAsync)
      banner.isBannerOnScreen = true
      self.completion = nil
    }
  }

  func get(coreBanners: [CoreBanner], cacheOnly: Bool, loadNew: Bool = true, completion: @escaping Completion) {
    self.completion = completion
    self.cacheOnly = cacheOnly
    loadStates = coreBanners.map { coreBanner in
      let bannerType = BannerType(type: coreBanner.mwmType, id: coreBanner.bannerID)
      if let banner = cache[bannerType], (!banner.isPossibleToReload || banner.isNeedToRetain) {
        return .loaded(bannerType)
      } else {
        if loadNew {
          get(bannerType: bannerType)
        }
        return .notLoaded(bannerType)
      }
    }

    onCompletion(isAsync: false)
  }

  private func get(bannerType: BannerType) {
    guard requests[bannerType] == nil else { return }

    let banner = bannerType.banner!
    requests[bannerType] = banner
    banner.reload(success: { [unowned self] banner in
      self.setLoaded(banner: banner)
    }, failure: { [unowned self] bannerType, event, errorDetails, error in
      var statParams = errorDetails
      statParams[kStatErrorMessage] = (error as NSError).userInfo.reduce("") { $0 + "\($1.key) : \($1.value)\n" }
      Statistics.logEvent(event, withParameters: statParams)
      Crashlytics.sharedInstance().recordError(error)
      MRMyTracker.trackEvent(withName: event)
      self.setError(bannerType: bannerType)
    }, click: { banner in
      Statistics.logEvent(kStatPlacePageBannerClick, withParameters: banner.statisticsDescription)
      MRMyTracker.trackEvent(withName: kStatPlacePageBannerClick)
    })
  }

  private func notLoadedIndex(bannerType: BannerType) -> Array<LoadState>.Index? {
    return loadStates.index(where: {
      if case .notLoaded(let type) = $0, type == bannerType {
        return true
      }
      return false
    })
  }

  private func setLoaded(banner: Banner) {
    let bannerType = banner.type
    if let notLoadedIndex = notLoadedIndex(bannerType: bannerType) {
      loadStates[notLoadedIndex] = .loaded(bannerType)
    }
    cache[bannerType] = banner
    requests[bannerType] = nil
    if !cacheOnly {
      onCompletion(isAsync: true)
    }
  }

  private func setError(bannerType: BannerType) {
    if let notLoadedIndex = notLoadedIndex(bannerType: bannerType) {
      loadStates[notLoadedIndex] = .error
    }
    requests[bannerType] = nil
    onCompletion(isAsync: true)
  }

  func bannerIsOutOfScreen(coreBanner: MWMBanner) {
    bannerIsOutOfScreen(bannerType: BannerType(type: coreBanner.mwmType, id: coreBanner.bannerID))
  }

  func bannerIsOutOfScreen(bannerType: BannerType) {
    completion = nil
    if let cached = cache[bannerType], cached.isBannerOnScreen {
      cached.isBannerOnScreen = false
    }
  }
}