Commit fda52da8 by Demid Merzlyakov

IOS-73: hide adviews when there are no ads.

parent dc0d546b
......@@ -10,13 +10,22 @@ import Foundation
import GoogleMobileAds
import UIKit
@objc
public protocol AdViewDelegate: AnyObject {
func succeeded(adView: AdView)
func failed(adView: AdView)
func succeeded(adView: AdView, hadAdBefore: Bool)
func failed(adView: AdView, hadAdBefore: Bool)
func closeButtonTapped(adView: AdView)
/// Return the view controller, that will present the interstitial.
func adTopViewController() -> UIViewController
func adTopViewController() -> UIViewController?
}
// MARK: - Default methods implementation
extension AdViewDelegate {
func closeButtonTapped(adView: AdView) {
// do nothing
}
func adTopViewController() -> UIViewController? {
return nil
}
}
@objcMembers
......@@ -324,22 +333,25 @@ extension AdView {
extension AdView: NativeBannerContainerViewDelegate {
func adLoader(_ adLoader: GADAdLoader, didReceived bannerView: GAMBannerView) {
log.info("ad request succeeded")
let hadAdBefore = adReady
adReady = true
analytics(log: .ANALYTICS_AD_RECEIVED, params: self.analyticsParams)
self.delegate?.succeeded(adView: self)
self.delegate?.succeeded(adView: self, hadAdBefore: hadAdBefore)
}
func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) {
log.info("ad request succeeded")
let hadAdBefore = adReady
adReady = true
analytics(log: .ANALYTICS_AD_RECEIVED, params: self.analyticsParams)
self.delegate?.succeeded(adView: self)
self.delegate?.succeeded(adView: self, hadAdBefore: hadAdBefore)
}
public func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: Error) {
log.error("ad request failed")
let hadAdBefore = adReady
adReady = false
self.delegate?.failed(adView: self)
self.delegate?.failed(adView: self, hadAdBefore: hadAdBefore)
}
}
......
......@@ -7,7 +7,19 @@
import UIKit
extension CellFactoryProtocol {
public protocol CellFactory {
var numberOfSections:Int { get }
func numberOfRows(inSection section:Int) -> Int
func registerCells(on tableView:UITableView)
func cellFromTableView(tableView:UITableView, indexPath:IndexPath) -> UITableViewCell
}
public protocol CellFactoryDelegate {
func cellFactoryCellsChanged(_ factory: CellFactory)
}
// MARK: - Default methods implementation
extension CellFactory {
func dequeueReusableCell<T: ReusableCellProtocol>(type:T.Type, tableView:UITableView, indexPath: IndexPath) -> T {
let cell = tableView.dequeueReusableCell(withIdentifier: T.kIdentifier, for: indexPath) as! T
return cell
......@@ -17,10 +29,3 @@ extension CellFactoryProtocol {
tableView.register(type, forCellReuseIdentifier: T.kIdentifier)
}
}
public protocol CellFactoryProtocol {
var numberOfSections:Int { get }
func numberOfRows(inSection section:Int) -> Int
func registerCells(on tableView:UITableView)
func cellFromTableView(tableView:UITableView, indexPath:IndexPath) -> UITableViewCell
}
......@@ -64,10 +64,12 @@ class BannerAdCell: UITableViewCell, AdCell {
private extension BannerAdCell {
func prepareCellStyle() {
selectionStyle = .none
clipsToBounds = true
}
func prepareContainer() {
container.layer.cornerRadius = 6
container.clipsToBounds = true
contentView.addSubview(container)
container.snp.makeConstraints { (make) in
......
......@@ -26,7 +26,7 @@ class MRECAdCell: UITableViewCell, AdCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
prepareCellStyle()
prepareCell()
prepareContainer()
prepareAd()
prepareGradient()
......@@ -58,8 +58,9 @@ class MRECAdCell: UITableViewCell, AdCell {
//MARK:- Prepare
private extension MRECAdCell {
func prepareCellStyle() {
func prepareCell() {
selectionStyle = .none
clipsToBounds = true
}
func prepareContainer() {
......
......@@ -30,6 +30,7 @@ class ForecastViewController: UIViewController {
self.coordinator = coordinator
self.forecastCellFactory = ForecastCellFactory(viewModel: viewModel)
super.init(nibName: nil, bundle: nil)
self.forecastCellFactory.delegate = self
}
required init?(coder: NSCoder) {
......@@ -159,7 +160,6 @@ private extension ForecastViewController {
tableView.separatorStyle = .none
tableView.tableFooterView = UIView()
tableView.estimatedRowHeight = UITableView.automaticDimension
tableView.rowHeight = UITableView.automaticDimension
tableView.delegate = self
tableView.dataSource = self
view.addSubview(tableView)
......@@ -247,6 +247,10 @@ extension ForecastViewController: UITableViewDataSource {
return forecastCellFactory.cellFromTableView(tableView: tableView,
indexPath: indexPath)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
forecastCellFactory.height(for: indexPath)
}
}
//MARK:- ViewModel Delegate
......@@ -278,3 +282,9 @@ extension ForecastViewController: DaysControlViewDelegate {
viewModel.offsetHolder.update(offset: offset)
}
}
extension ForecastViewController: CellFactoryDelegate {
func cellFactoryCellsChanged(_ factory: CellFactory) {
self.tableView.reloadData()
}
}
......@@ -8,7 +8,7 @@
import UIKit
import OneWeatherCore
class LocationCellFactory: CellFactoryProtocol {
class LocationCellFactory: CellFactory {
//Private
private let locationsViewModel:LocationsViewModel
......
......@@ -91,7 +91,7 @@ private struct SectionItem {
let rows:[MenuRow]
}
class MenuCellFactory<T>: CellFactoryProtocol {
class MenuCellFactory<T>: CellFactory {
//Private
private let menuViewModel:MenuViewModel
private let sections:[SectionItem] = [SectionItem(type: .info, rows: [.settings]),
......
......@@ -72,8 +72,13 @@ fileprivate struct ExtendedInfoSection: NWSAlertTableViewSection {
let rows: [NWSAlertCellType] = [.extendedInfoBlock]
}
class NWSAlertCellFactory: CellFactoryProtocol {
var alert: NWSAlert {
class NWSAlertCellFactory: CellFactory {
fileprivate var sections: [NWSAlertTableViewSection]
private var adViewCache = [IndexPath: AdView]()
public var delegate: CellFactoryDelegate?
public var alert: NWSAlert {
didSet {
for i in 0..<sections.count {
sections[i].update(with: alert)
......@@ -81,19 +86,28 @@ class NWSAlertCellFactory: CellFactoryProtocol {
}
}
init(alert: NWSAlert) {
public init(alert: NWSAlert) {
self.alert = alert
self.sections = [HeaderSection(alert: alert), ExtendedInfoSection(alert: alert)]
}
fileprivate var sections: [NWSAlertTableViewSection]
private var adViewCache = [IndexPath: AdView]()
public func height(for indexPath: IndexPath) -> CGFloat {
let cellType = cellType(at: indexPath)
switch cellType {
case .adBanner: fallthrough
case .adMREC:
let adView = adView(for: indexPath)
return adView.adReady ? UITableView.automaticDimension : 0
default:
return UITableView.automaticDimension
}
}
var numberOfSections: Int {
public var numberOfSections: Int {
return sections.count
}
func numberOfRows(inSection section: Int) -> Int {
public func numberOfRows(inSection section: Int) -> Int {
sections[section].numberOfRows
}
......@@ -102,6 +116,7 @@ class NWSAlertCellFactory: CellFactoryProtocol {
return adView
}
let adView = adViewCache[indexPath] ?? AdView()
adView.delegate = self
adView.loggingAlias = "⚠️ Alert Banner"
adView.set(placementName: placementNameNWSAlertBanner, adType: .banner)
adViewCache[indexPath] = adView
......@@ -116,9 +131,14 @@ class NWSAlertCellFactory: CellFactoryProtocol {
registerCell(type: MRECAdCell.self, tableView: tableView)
}
func cellFromTableView(tableView: UITableView, indexPath: IndexPath) -> UITableViewCell {
private func cellType(at indexPath: IndexPath) -> NWSAlertCellType {
let section = sections[indexPath.section]
let type = section.type(forRow: indexPath.row)
return type
}
public func cellFromTableView(tableView: UITableView, indexPath: IndexPath) -> UITableViewCell {
let type = cellType(at: indexPath)
switch type {
case .header:
let alertCell = dequeueReusableCell(type: NWSAlertCell.self, tableView: tableView, indexPath: indexPath)
......@@ -165,3 +185,22 @@ class NWSAlertCellFactory: CellFactoryProtocol {
}
}
}
// MARK: - AdViewDelegate
extension NWSAlertCellFactory: AdViewDelegate {
func succeeded(adView: AdView, hadAdBefore: Bool) {
onMain {
if hadAdBefore != adView.adReady {
self.delegate?.cellFactoryCellsChanged(self)
}
}
}
func failed(adView: AdView, hadAdBefore: Bool) {
onMain {
if hadAdBefore != adView.adReady {
self.delegate?.cellFactoryCellsChanged(self)
}
}
}
}
......@@ -109,7 +109,7 @@ extension NWSAlertViewController: UITableViewDelegate, UITableViewDataSource {
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
UITableView.automaticDimension
return viewModel.cellFactory.height(for: indexPath)
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
......
......@@ -18,7 +18,7 @@ private struct LayerSection {
let rowsCount:Int
}
class RadarLayersCellFactory: CellFactoryProtocol {
class RadarLayersCellFactory: CellFactory {
//Private
private let radarViewModel:RadarViewModel
private let sections:[LayerSection]
......
......@@ -84,7 +84,7 @@ private struct SettingsDataSource {
let rows:[SettingsRow]
}
class SettingsCellFactory: CellFactoryProtocol {
class SettingsCellFactory: CellFactory {
//Private
private let viewModel: SettingsViewModel
private let sections: [SettingsDataSource] = {
......
......@@ -9,7 +9,7 @@ import UIKit
import Localize_Swift
import OneWeatherCore
class SettingsDetailsCellFactory: CellFactoryProtocol {
class SettingsDetailsCellFactory: CellFactory {
//Private
private let viewModel:SettingsDetailsViewModel
......
......@@ -50,7 +50,7 @@ private struct TodaySection {
}
}
class TodayCellFactory: CellFactoryProtocol {
class TodayCellFactory: CellFactory {
//Private
private var cellsToUpdate:CellsToUpdate = [.condition, .timePeriod, .precipitation, .dayTime]
private let todayViewModel:TodayViewModel
......@@ -62,6 +62,7 @@ class TodayCellFactory: CellFactoryProtocol {
private var adViewCache = [IndexPath: AdView]()
//Public
public var delegate: CellFactoryDelegate?
init(viewModel: TodayViewModel) {
self.todayViewModel = viewModel
}
......@@ -93,6 +94,7 @@ class TodayCellFactory: CellFactoryProtocol {
return adView
}
let adView = AdView()
adView.delegate = self
adView.loggingAlias = "📍 Today Banner"
var adType = AdType.banner
if cellType(at: indexPath) == .adMREC {
......@@ -172,6 +174,18 @@ class TodayCellFactory: CellFactoryProtocol {
}
}
public func height(for indexPath: IndexPath) -> CGFloat {
let cellType = cellType(at: indexPath)
switch cellType {
case .adBanner: fallthrough
case .adMREC:
let adView = adView(for: indexPath)
return adView.adReady ? UITableView.automaticDimension : 0
default:
return UITableView.automaticDimension
}
}
public func setNeedsUpdate() {
cellsToUpdate = [.condition, .timePeriod, .precipitation, .dayTime]
setupHiddenRows()
......@@ -223,3 +237,22 @@ class TodayCellFactory: CellFactoryProtocol {
todaySection.hiddenRows = rowsToHide
}
}
// MARK: - AdViewDelegate
extension TodayCellFactory: AdViewDelegate {
func succeeded(adView: AdView, hadAdBefore: Bool) {
onMain {
if hadAdBefore != adView.adReady {
self.delegate?.cellFactoryCellsChanged(self)
}
}
}
func failed(adView: AdView, hadAdBefore: Bool) {
onMain {
if hadAdBefore != adView.adReady {
self.delegate?.cellFactoryCellsChanged(self)
}
}
}
}
......@@ -106,7 +106,6 @@ private extension TodayViewController {
tableView.separatorStyle = .none
tableView.tableFooterView = UIView()
tableView.estimatedRowHeight = UITableView.automaticDimension
tableView.rowHeight = UITableView.automaticDimension
tableView.delegate = self
tableView.dataSource = self
view.addSubview(tableView)
......@@ -126,6 +125,10 @@ extension TodayViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return viewModel.todayCellFactory.cellFromTableView(tableView: tableView, indexPath: indexPath)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return viewModel.todayCellFactory.height(for: indexPath)
}
}
//MARK:- UITableView Delegate
......
......@@ -25,6 +25,7 @@ class NWSAlertViewModel: ViewModelProtocol {
cellFactory = NWSAlertCellFactory(alert: alert)
alertsManager.delegates.add(delegate: self)
NotificationCenter.default.addObserver(self, selector: #selector(handlePremiumStateChange), name: Notification.Name(rawValue: kEventInAppPurchasedCompleted), object: nil)
cellFactory.delegate = self
}
@objc
......@@ -35,6 +36,7 @@ class NWSAlertViewModel: ViewModelProtocol {
}
}
//MARK: - NWSAlertsManagerDelegate
extension NWSAlertViewModel: NWSAlertsManagerDelegate {
func alertsListDidChange(in alertsManager: NWSAlertsManager) {
// do nothing
......@@ -48,3 +50,10 @@ extension NWSAlertViewModel: NWSAlertsManagerDelegate {
}
}
}
extension NWSAlertViewModel: CellFactoryDelegate {
func cellFactoryCellsChanged(_ factory: CellFactory) {
delegate?.viewModelDidChange(model: self)
}
}
......@@ -23,7 +23,9 @@ class TodayViewModel: ViewModelProtocol {
private(set) var location:Location?
public lazy var todayCellFactory:TodayCellFactory = {
TodayCellFactory(viewModel: self)
let factory = TodayCellFactory(viewModel: self)
factory.delegate = self
return factory
}()
deinit {
......@@ -129,3 +131,10 @@ extension TodayViewModel: SettingsDelegate {
delegate?.viewModelDidChange(model: self)
}
}
// MARK: CellFactoryDelegate
extension TodayViewModel: CellFactoryDelegate {
func cellFactoryCellsChanged(_ factory: CellFactory) {
delegate?.viewModelDidChange(model: self)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment