Commit 13c10ce9 by Demid Merzlyakov

Ads integrated on the Today screen.

parent 225696ee
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
CD80917B2578E4A8003541A4 /* UIViewController+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD80917A2578E4A8003541A4 /* UIViewController+Alert.swift */; }; CD80917B2578E4A8003541A4 /* UIViewController+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD80917A2578E4A8003541A4 /* UIViewController+Alert.swift */; };
CD822FF525D6817000A05501 /* TodayForecastCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD822FF425D6817000A05501 /* TodayForecastCell.swift */; }; CD822FF525D6817000A05501 /* TodayForecastCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD822FF425D6817000A05501 /* TodayForecastCell.swift */; };
CD822FFA25D6890900A05501 /* OneWeatherColorsAsset.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD822FF925D6890900A05501 /* OneWeatherColorsAsset.xcassets */; }; CD822FFA25D6890900A05501 /* OneWeatherColorsAsset.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD822FF925D6890900A05501 /* OneWeatherColorsAsset.xcassets */; };
CD822FFE25D6976F00A05501 /* TodayAdCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD822FFD25D6976F00A05501 /* TodayAdCell.swift */; }; CD822FFE25D6976F00A05501 /* AdCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD822FFD25D6976F00A05501 /* AdCell.swift */; };
CD82300325D69DE400A05501 /* TodayConditionsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD82300225D69DE400A05501 /* TodayConditionsCell.swift */; }; CD82300325D69DE400A05501 /* TodayConditionsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD82300225D69DE400A05501 /* TodayConditionsCell.swift */; };
CD82300725D6A73F00A05501 /* TodayConditionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD82300625D6A73E00A05501 /* TodayConditionButton.swift */; }; CD82300725D6A73F00A05501 /* TodayConditionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD82300625D6A73E00A05501 /* TodayConditionButton.swift */; };
CD82300A25D6B2AF00A05501 /* AppTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD82300925D6B2AF00A05501 /* AppTabBarController.swift */; }; CD82300A25D6B2AF00A05501 /* AppTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD82300925D6B2AF00A05501 /* AppTabBarController.swift */; };
...@@ -299,7 +299,7 @@ ...@@ -299,7 +299,7 @@
CD80917A2578E4A8003541A4 /* UIViewController+Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Alert.swift"; sourceTree = "<group>"; }; CD80917A2578E4A8003541A4 /* UIViewController+Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Alert.swift"; sourceTree = "<group>"; };
CD822FF425D6817000A05501 /* TodayForecastCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayForecastCell.swift; sourceTree = "<group>"; }; CD822FF425D6817000A05501 /* TodayForecastCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayForecastCell.swift; sourceTree = "<group>"; };
CD822FF925D6890900A05501 /* OneWeatherColorsAsset.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = OneWeatherColorsAsset.xcassets; sourceTree = "<group>"; }; CD822FF925D6890900A05501 /* OneWeatherColorsAsset.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = OneWeatherColorsAsset.xcassets; sourceTree = "<group>"; };
CD822FFD25D6976F00A05501 /* TodayAdCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayAdCell.swift; sourceTree = "<group>"; }; CD822FFD25D6976F00A05501 /* AdCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdCell.swift; sourceTree = "<group>"; };
CD82300225D69DE400A05501 /* TodayConditionsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayConditionsCell.swift; sourceTree = "<group>"; }; CD82300225D69DE400A05501 /* TodayConditionsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayConditionsCell.swift; sourceTree = "<group>"; };
CD82300625D6A73E00A05501 /* TodayConditionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayConditionButton.swift; sourceTree = "<group>"; }; CD82300625D6A73E00A05501 /* TodayConditionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayConditionButton.swift; sourceTree = "<group>"; };
CD82300925D6B2AF00A05501 /* AppTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTabBarController.swift; sourceTree = "<group>"; }; CD82300925D6B2AF00A05501 /* AppTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTabBarController.swift; sourceTree = "<group>"; };
...@@ -730,7 +730,7 @@ ...@@ -730,7 +730,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
CDA5542725EF734200A2E08C /* TodayCellFactory.swift */, CDA5542725EF734200A2E08C /* TodayCellFactory.swift */,
CD822FFD25D6976F00A05501 /* TodayAdCell.swift */, CD822FFD25D6976F00A05501 /* AdCell.swift */,
CD822FF425D6817000A05501 /* TodayForecastCell.swift */, CD822FF425D6817000A05501 /* TodayForecastCell.swift */,
CD15DB4125DA806C00024727 /* TodayForecastTimePeriodCell.swift */, CD15DB4125DA806C00024727 /* TodayForecastTimePeriodCell.swift */,
CD82300125D69DB900A05501 /* TodayConditions */, CD82300125D69DB900A05501 /* TodayConditions */,
...@@ -1529,7 +1529,7 @@ ...@@ -1529,7 +1529,7 @@
CDF4808F261727E00076E9F5 /* CLAuthorizationStatus+Localized.swift in Sources */, CDF4808F261727E00076E9F5 /* CLAuthorizationStatus+Localized.swift in Sources */,
CE13B81D262480B3007CBD4D /* BRMoPubAdView.m in Sources */, CE13B81D262480B3007CBD4D /* BRMoPubAdView.m in Sources */,
CD37D3DE260C9E37002669D6 /* MenuCell.swift in Sources */, CD37D3DE260C9E37002669D6 /* MenuCell.swift in Sources */,
CD822FFE25D6976F00A05501 /* TodayAdCell.swift in Sources */, CD822FFE25D6976F00A05501 /* AdCell.swift in Sources */,
CEF959A626035A2600975FAA /* DeviceLocationMonitor.swift in Sources */, CEF959A626035A2600975FAA /* DeviceLocationMonitor.swift in Sources */,
CD32CDFF260B2E5400235081 /* ForecastDescriptionView.swift in Sources */, CD32CDFF260B2E5400235081 /* ForecastDescriptionView.swift in Sources */,
CEC5275D25E8E50B00DA58A5 /* WdtDailySummary.swift in Sources */, CEC5275D25E8E50B00DA58A5 /* WdtDailySummary.swift in Sources */,
......
...@@ -21,7 +21,11 @@ class AdLogger: NSObject { ...@@ -21,7 +21,11 @@ class AdLogger: NSObject {
case error case error
} }
#if DEBUG
static var debugMode: Bool = true
#else
static var debugMode: Bool = false static var debugMode: Bool = false
#endif
static func setDebugMode(_ on: Bool) { static func setDebugMode(_ on: Bool) {
debugMode = on debugMode = on
......
...@@ -9,7 +9,7 @@ import Foundation ...@@ -9,7 +9,7 @@ import Foundation
public class Analytics { public class Analytics {
private let services: [AnalyticsService] private let services: [AnalyticsService]
private let log = Logger(componentName: "Analytics") private let log = Logger(componentName: "Analytics")
public init(services: [AnalyticsService]) { public init(services: [AnalyticsService]) {
self.services = services self.services = services
...@@ -30,15 +30,14 @@ public class Analytics { ...@@ -30,15 +30,14 @@ public class Analytics {
} }
let loggedToString = loggedTo.joined(separator: ", ") let loggedToString = loggedTo.joined(separator: ", ")
if let params = params { if let params = params {
if let prettyPrintableParams = params as? [AnalyticsParameter: Any] { var readableParams = [String: Any](minimumCapacity: params.count)
log.info("Event \(event.rawValue) params: \(prettyPrintableParams) sent to \(loggedToString))") for (key, value) in params {
} readableParams[key.rawValue] = value
else {
log.info("Event \(event.rawValue) params: \(params) sent to \(loggedToString))")
} }
log.info("Event \(event.rawValue) params: \(readableParams) sent to \(loggedToString)")
} }
else { else {
log.info("Event \(event.rawValue) sent to \(loggedToString))") log.info("Event \(event.rawValue) sent to \(loggedToString)")
} }
} }
} }
...@@ -7,10 +7,18 @@ ...@@ -7,10 +7,18 @@
import UIKit import UIKit
class TodayAdCell: UITableViewCell { class AdCell: UITableViewCell {
//Private //Private
private let container = UIView() private let container = UIView()
private let label = UILabel() private let label = UILabel()
public var adView: AdView? = nil {
didSet {
guard adView != oldValue else {
return
}
prepareAd()
}
}
private let gradientView = GradientView(startColor: UIColor.white.withAlphaComponent(0), private let gradientView = GradientView(startColor: UIColor.white.withAlphaComponent(0),
endColor: UIColor(hex: 0xdaddec), endColor: UIColor(hex: 0xdaddec),
opacity: 0.5) opacity: 0.5)
...@@ -52,10 +60,9 @@ class TodayAdCell: UITableViewCell { ...@@ -52,10 +60,9 @@ class TodayAdCell: UITableViewCell {
} }
//MARK:- Prepare //MARK:- Prepare
private extension TodayAdCell { private extension AdCell {
func prepareCellStyle() { func prepareCellStyle() {
selectionStyle = .none selectionStyle = .none
} }
func prepareContainer() { func prepareContainer() {
...@@ -71,6 +78,10 @@ private extension TodayAdCell { ...@@ -71,6 +78,10 @@ private extension TodayAdCell {
} }
func prepareAd() { func prepareAd() {
for subview in container.subviews {
subview.removeFromSuperview()
}
label.text = "Advertisment" label.text = "Advertisment"
label.font = AppFont.SFPro.regular(size: 14) label.font = AppFont.SFPro.regular(size: 14)
container.addSubview(label) container.addSubview(label)
...@@ -78,6 +89,13 @@ private extension TodayAdCell { ...@@ -78,6 +89,13 @@ private extension TodayAdCell {
label.snp.makeConstraints { (make) in label.snp.makeConstraints { (make) in
make.center.equalToSuperview() make.center.equalToSuperview()
} }
if let adView = adView {
container.addSubview(adView)
adView.snp.makeConstraints { (make) in
make.center.equalToSuperview()
make.size.equalToSuperview()
}
}
} }
func prepareGradient() { func prepareGradient() {
......
...@@ -40,12 +40,8 @@ class TodayCellFactory: CellFactoryProtocol { ...@@ -40,12 +40,8 @@ class TodayCellFactory: CellFactoryProtocol {
private var todaySection = TodaySection(rows: [.alert, .forecast, .ad, private var todaySection = TodaySection(rows: [.alert, .forecast, .ad,
.conditions, .forecastPeriod, .precipitation, .conditions, .forecastPeriod, .precipitation,
.airQuality, .dayTime, .sun, .moon]) .airQuality, .dayTime, .sun, .moon])
private let health = Health(lastUpdateTime: Date(),
airQuality: .init(index: 140, advice: "Slightly elevated pollution, but general public likely not affected"), private var adViewCache = [IndexPath: AdView]()
pollutants: ["pm25" : .init(name: "PM 2.5", value: 48),
"pm10" : .init(name: "PM 10", value: 42),
"no2" : .init(name: "NO2", value: 74),
"so2" : .init(name: "SO2", value: 135)])
//Public //Public
init(viewModel: TodayViewModel) { init(viewModel: TodayViewModel) {
...@@ -63,7 +59,7 @@ class TodayCellFactory: CellFactoryProtocol { ...@@ -63,7 +59,7 @@ class TodayCellFactory: CellFactoryProtocol {
public func registerCells(on tableView:UITableView) { public func registerCells(on tableView:UITableView) {
registerCell(type: TodayAlertCell.self, tableView: tableView) registerCell(type: TodayAlertCell.self, tableView: tableView)
registerCell(type: TodayForecastCell.self, tableView: tableView) registerCell(type: TodayForecastCell.self, tableView: tableView)
registerCell(type: TodayAdCell.self, tableView: tableView) registerCell(type: AdCell.self, tableView: tableView)
registerCell(type: TodayConditionsCell.self, tableView: tableView) registerCell(type: TodayConditionsCell.self, tableView: tableView)
registerCell(type: TodayForecastTimePeriodCell.self, tableView: tableView) registerCell(type: TodayForecastTimePeriodCell.self, tableView: tableView)
registerCell(type: PrecipitationCell.self, tableView: tableView) registerCell(type: PrecipitationCell.self, tableView: tableView)
...@@ -73,6 +69,17 @@ class TodayCellFactory: CellFactoryProtocol { ...@@ -73,6 +69,17 @@ class TodayCellFactory: CellFactoryProtocol {
registerCell(type: MoonPhaseCell.self, tableView: tableView) registerCell(type: MoonPhaseCell.self, tableView: tableView)
} }
private func adView(for indexPath: IndexPath) -> AdView {
if let adView = adViewCache[indexPath] {
return adView
}
let adView = adViewCache[indexPath] ?? AdView()
adView.loggingAlias = "📍 Today Banner"
adView.set(placementName: placementNameTodayBanner, adType: .banner)
adViewCache[indexPath] = adView
return adView
}
public func cellFromTableView(tableView:UITableView, indexPath:IndexPath) -> UITableViewCell { public func cellFromTableView(tableView:UITableView, indexPath:IndexPath) -> UITableViewCell {
let cellType = todaySection.rows[indexPath.row] let cellType = todaySection.rows[indexPath.row]
guard let loc = self.todayViewModel.location else { guard let loc = self.todayViewModel.location else {
...@@ -87,7 +94,8 @@ class TodayCellFactory: CellFactoryProtocol { ...@@ -87,7 +94,8 @@ class TodayCellFactory: CellFactoryProtocol {
cell.configure(with: loc) cell.configure(with: loc)
return cell return cell
case .ad: case .ad:
let cell = dequeueReusableCell(type: TodayAdCell.self, tableView: tableView, indexPath: indexPath) let cell = dequeueReusableCell(type: AdCell.self, tableView: tableView, indexPath: indexPath)
cell.adView = adView(for: indexPath)
return cell return cell
case .conditions: case .conditions:
let cell = dequeueReusableCell(type: TodayConditionsCell.self, tableView: tableView, indexPath: indexPath) let cell = dequeueReusableCell(type: TodayConditionsCell.self, tableView: tableView, indexPath: indexPath)
...@@ -136,12 +144,23 @@ class TodayCellFactory: CellFactoryProtocol { ...@@ -136,12 +144,23 @@ class TodayCellFactory: CellFactoryProtocol {
cellsToUpdate = [.condition, .timePeriod, .precipitation, .dayTime] cellsToUpdate = [.condition, .timePeriod, .precipitation, .dayTime]
} }
public func willDisplay(cell:UITableViewCell) { public func willDisplay(cell: UITableViewCell) {
switch cell { switch cell {
case let sunCell as SunPhaseCell: case let sunCell as SunPhaseCell:
sunCell.updateSunPosition() sunCell.updateSunPosition()
case let moonCell as MoonPhaseCell: case let moonCell as MoonPhaseCell:
moonCell.updateMoonPosition() moonCell.updateMoonPosition()
case let adCell as AdCell:
adCell.adView?.start()
default:
break
}
}
public func didHide(cell: UITableViewCell) {
switch cell {
case let adCell as AdCell:
adCell.adView?.stop()
default: default:
break break
} }
......
...@@ -131,6 +131,10 @@ extension TodayViewController: UITableViewDelegate { ...@@ -131,6 +131,10 @@ extension TodayViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
todayCellFactory.willDisplay(cell: cell) todayCellFactory.willDisplay(cell: cell)
} }
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
todayCellFactory.didHide(cell: cell)
}
} }
//MARK:- ViewModel Delegate //MARK:- ViewModel Delegate
......
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