Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
1
1weather
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dmitriy Stepanets
1weather
Commits
fda52da8
Commit
fda52da8
authored
Jun 10, 2021
by
Demid Merzlyakov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IOS-73: hide adviews when there are no ads.
parent
dc0d546b
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
315 additions
and
164 deletions
+315
-164
1Weather/Ads/AdView.swift
+19
-7
1Weather/Common/CellFactory.swift
+13
-8
1Weather/UI/SharedCells/AdCells/BannerAdCell.swift
+2
-0
1Weather/UI/SharedCells/AdCells/MRECAdCell.swift
+3
-2
1Weather/UI/View controllers/Forecast/Cells/ForecastCellFactory.swift
+157
-129
1Weather/UI/View controllers/Forecast/ForecastViewController.swift
+11
-1
1Weather/UI/View controllers/Locations/Cells/LocationCellFactory.swift
+1
-1
1Weather/UI/View controllers/Menu/Cells/MenuCellFactory.swift
+1
-1
1Weather/UI/View controllers/NWSAlert/Cells/NWSAlertCellFactory.swift
+47
-8
1Weather/UI/View controllers/NWSAlert/NWSAlertViewController.swift
+1
-1
1Weather/UI/View controllers/Radar/Cells/RadarLayersCellFactory.swift
+1
-1
1Weather/UI/View controllers/Settings/Cells/SettingsCellFactory.swift
+1
-1
1Weather/UI/View controllers/Settings/Cells/SettingsDetailsCellFactory.swift
+1
-1
1Weather/UI/View controllers/Today/Cells/TodayCellFactory.swift
+34
-1
1Weather/UI/View controllers/Today/TodayViewController.swift
+4
-1
1Weather/ViewModels/NWSAlertViewModel.swift
+9
-0
1Weather/ViewModels/TodayViewModel.swift
+10
-1
No files found.
1Weather/Ads/AdView.swift
View file @
fda52da8
...
...
@@ -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
)
}
}
...
...
1Weather/Common/CellFactory.swift
View file @
fda52da8
...
...
@@ -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
}
1Weather/UI/SharedCells/AdCells/BannerAdCell.swift
View file @
fda52da8
...
...
@@ -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
...
...
1Weather/UI/SharedCells/AdCells/MRECAdCell.swift
View file @
fda52da8
...
...
@@ -26,7 +26,7 @@ class MRECAdCell: UITableViewCell, AdCell {
override
init
(
style
:
UITableViewCell
.
CellStyle
,
reuseIdentifier
:
String
?)
{
super
.
init
(
style
:
style
,
reuseIdentifier
:
reuseIdentifier
)
prepareCell
Style
()
prepareCell
()
prepareContainer
()
prepareAd
()
prepareGradient
()
...
...
@@ -58,8 +58,9 @@ class MRECAdCell: UITableViewCell, AdCell {
//MARK:- Prepare
private
extension
MRECAdCell
{
func
prepareCell
Style
()
{
func
prepareCell
()
{
selectionStyle
=
.
none
clipsToBounds
=
true
}
func
prepareContainer
()
{
...
...
1Weather/UI/View controllers/Forecast/Cells/ForecastCellFactory.swift
View file @
fda52da8
...
...
@@ -6,49 +6,68 @@
//
import
UIKit
import
OneWeatherCore
private
enum
DailyForecastCellType
:
Int
,
CaseIterabl
e
{
case
forecast
=
0
case
forecast
Info
case
adBanner
private
enum
ForecastCellTyp
e
{
//Daily
case
forecast
Daily
case
forecastDailyInfo
case
sun
case
moon
case
adMREC
}
private
enum
HourlyForecastCellType
:
Int
,
CaseIterable
{
// Hourly
case
day
case
forecastHourly
case
adBanner
case
precipitation
case
wind
// Shared
case
adBanner
case
adMREC
}
private
struct
CellsToUpdate
:
OptionSet
{
let
rawValue
:
Int
static
let
dailyTimePeriod
=
CellsToUpdate
(
rawValue
:
1
<<
0
)
static
let
hourlyTimePeriod
=
CellsToUpdate
(
rawValue
:
1
<<
1
)
static
let
dailyForecastInfoCell
=
CellsToUpdate
(
rawValue
:
1
<<
2
)
static
let
precipitation
=
CellsToUpdate
(
rawValue
:
1
<<
4
)
static
let
wind
=
CellsToUpdate
(
rawValue
:
1
<<
5
)
private
struct
HourlySection
{
let
rows
:
[
ForecastCellType
]
=
{
let
showAds
=
!
isAppPro
()
&&
AdConfigManager
.
shared
.
adConfig
.
adsEnabled
if
showAds
{
return
[
.
day
,
.
forecastHourly
,
.
adBanner
,
.
precipitation
,
.
wind
,
.
adMREC
]
}
else
{
return
[
.
day
,
.
forecastHourly
,
.
precipitation
,
.
wind
]
}
}()
}
private
struct
DailySection
{
let
rows
:
[
ForecastCellType
]
=
{
let
showAds
=
!
isAppPro
()
&&
AdConfigManager
.
shared
.
adConfig
.
adsEnabled
if
showAds
{
return
[
.
forecastDaily
,
.
forecastDailyInfo
,
.
adBanner
,
.
sun
,
.
moon
,
.
adMREC
]
}
else
{
return
[
.
forecastDaily
,
.
forecastDailyInfo
,
.
sun
,
.
moon
]
}
}()
}
class
ForecastCellFactory
:
CellFactoryProtocol
{
class
ForecastCellFactory
:
CellFactory
{
//Private
private
var
cellsToUpdate
:
CellsToUpdate
=
[
.
dailyTimePeriod
,
.
hourlyTimePeriod
,
.
dailyForecastInfoCell
,
.
precipitation
,
.
wind
]
private
let
dailySection
=
DailySection
()
private
let
hourlySection
=
HourlySection
()
private
var
cellsToUpdate
:
Set
<
ForecastCellType
>
=
[
.
forecastDaily
,
.
forecastHourly
,
.
forecastDailyInfo
,
.
precipitation
,
.
wind
]
private
let
forecastViewModel
:
ForecastViewModel
private
var
adViewCache
=
[
TimePeriod
:
[
IndexPath
:
AdView
]]()
//Public
public
var
delegate
:
CellFactoryDelegate
?
public
var
timePeriod
=
TimePeriod
.
daily
public
var
numberOfSections
:
Int
{
return
1
}
public
func
numberOfRows
(
inSection
section
:
Int
)
->
Int
{
return
timePeriod
==
.
daily
?
DailyForecastCellType
.
allCases
.
count
:
HourlyForecastCellType
.
allCase
s
.
count
return
timePeriod
==
.
daily
?
dailySection
.
rows
.
count
:
hourlySection
.
row
s
.
count
}
public
init
(
viewModel
:
ForecastViewModel
)
{
...
...
@@ -69,93 +88,9 @@ class ForecastCellFactory: CellFactoryProtocol {
}
public
func
cellFromTableView
(
tableView
:
UITableView
,
indexPath
:
IndexPath
)
->
UITableViewCell
{
switch
timePeriod
{
case
.
daily
:
return
dailyCellFor
(
tableView
:
tableView
,
indexPath
:
indexPath
)
case
.
hourly
:
return
hourlyCellFor
(
tableView
:
tableView
,
indexPath
:
indexPath
)
}
}
public
func
setNeedsUpdate
()
{
self
.
cellsToUpdate
=
[
.
dailyTimePeriod
,
.
hourlyTimePeriod
,
.
dailyForecastInfoCell
,
.
precipitation
,
.
wind
]
}
public
func
selectedWeatherDidChange
()
{
self
.
cellsToUpdate
=
[
.
dailyForecastInfoCell
,
.
precipitation
,
.
wind
]
}
public
func
willDisplay
(
cell
:
UITableViewCell
)
{
switch
cell
{
case
let
sunCell
as
SunPhaseCell
:
sunCell
.
updateSunPosition
()
case
let
moonCell
as
MoonPhaseCell
:
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
:
break
}
}
private
func
adView
(
for
timePeriod
:
TimePeriod
,
indexPath
:
IndexPath
)
->
AdView
{
if
let
adView
=
adViewCache
[
self
.
timePeriod
]?[
indexPath
]
{
return
adView
}
let
adView
=
AdView
()
var
placementName
:
String
!
var
timePeriodString
:
String
!
var
adType
=
AdType
.
banner
var
adTypeString
=
"Banner"
var
adLoggingEmoji
=
"🔹"
switch
timePeriod
{
case
.
daily
:
timePeriodString
=
"D"
placementName
=
placementNameForecastDailyBanner
let
cellType
=
DailyForecastCellType
(
rawValue
:
indexPath
.
row
)
if
cellType
==
.
adMREC
{
placementName
=
placementNameForecastDailySquare
adType
=
.
square
adTypeString
=
"MREC"
adLoggingEmoji
=
"✅"
}
case
.
hourly
:
placementName
=
placementNameForecastHourlyBanner
timePeriodString
=
"H"
let
cellType
=
HourlyForecastCellType
(
rawValue
:
indexPath
.
row
)
if
cellType
==
.
adMREC
{
placementName
=
placementNameForecastHourlySquare
adType
=
.
square
adTypeString
=
"MREC"
adLoggingEmoji
=
"✅"
}
}
adView
.
set
(
placementName
:
placementName
,
adType
:
adType
)
adView
.
loggingAlias
=
"
\(
adLoggingEmoji
)
Forecast
\(
timePeriodString
!
)
\(
adTypeString
)
"
var
edited
=
adViewCache
[
timePeriod
]
??
[
IndexPath
:
AdView
]()
edited
[
indexPath
]
=
adView
adViewCache
[
timePeriod
]
=
edited
return
adView
}
//Private
private
func
dailyCellFor
(
tableView
:
UITableView
,
indexPath
:
IndexPath
)
->
UITableViewCell
{
guard
let
cellType
=
DailyForecastCellType
(
rawValue
:
indexPath
.
row
)
else
{
return
UITableViewCell
()
}
let
cellType
=
cellType
(
at
:
indexPath
)
switch
cellType
{
case
.
forecast
:
case
.
forecast
Daily
:
let
cell
=
dequeueReusableCell
(
type
:
ForecastDailyCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
cell
.
delegate
=
self
...
...
@@ -163,19 +98,19 @@ class ForecastCellFactory: CellFactoryProtocol {
cell
.
setOffset
(
offset
:
forecastViewModel
.
offsetHolder
.
currentOffset
,
selectedButton
:
forecastViewModel
.
selectedDailyWeatherIndex
)
if
cellsToUpdate
.
contains
(
.
dailyTimePeriod
)
{
if
cellsToUpdate
.
contains
(
.
forecastDaily
)
{
cell
.
configure
(
daily
:
daily
)
cellsToUpdate
.
remove
(
.
dailyTimePeriod
)
cellsToUpdate
.
remove
(
.
forecastDaily
)
}
}
return
cell
case
.
forecastInfo
:
case
.
forecast
Daily
Info
:
let
cell
=
dequeueReusableCell
(
type
:
ForecastInfoCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
if
let
daily
=
forecastViewModel
.
selectedDailyWeather
{
if
cellsToUpdate
.
contains
(
.
dailyForecastInfoCell
)
{
if
cellsToUpdate
.
contains
(
.
forecastDailyInfo
)
{
cell
.
configure
(
dailyWeather
:
daily
)
cellsToUpdate
.
remove
(
.
dailyForecastInfoCell
)
cellsToUpdate
.
remove
(
.
forecastDailyInfo
)
}
}
...
...
@@ -200,15 +135,6 @@ class ForecastCellFactory: CellFactoryProtocol {
let
cell
=
dequeueReusableCell
(
type
:
MRECAdCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
cell
.
adView
=
adView
(
for
:
timePeriod
,
indexPath
:
indexPath
)
return
cell
}
}
private
func
hourlyCellFor
(
tableView
:
UITableView
,
indexPath
:
IndexPath
)
->
UITableViewCell
{
guard
let
cellType
=
HourlyForecastCellType
(
rawValue
:
indexPath
.
row
)
else
{
return
UITableViewCell
()
}
switch
cellType
{
case
.
day
:
let
cell
=
dequeueReusableCell
(
type
:
ForecastDayCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
if
let
today
=
forecastViewModel
.
location
?
.
today
{
...
...
@@ -218,9 +144,9 @@ class ForecastCellFactory: CellFactoryProtocol {
case
.
forecastHourly
:
let
cell
=
dequeueReusableCell
(
type
:
ForecastHourlyCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
if
let
hourly
=
forecastViewModel
.
location
?
.
hourly
{
if
cellsToUpdate
.
contains
(
.
hourlyTimePeriod
)
{
if
cellsToUpdate
.
contains
(
.
forecastHourly
)
{
cell
.
configure
(
hourly
:
hourly
)
cellsToUpdate
.
remove
(
.
hourlyTimePeriod
)
cellsToUpdate
.
remove
(
.
forecastHourly
)
}
}
return
cell
...
...
@@ -242,18 +168,101 @@ class ForecastCellFactory: CellFactoryProtocol {
}
}
return
cell
case
.
adBanner
:
let
cell
=
dequeueReusableCell
(
type
:
BannerAdCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
cell
.
adView
=
adView
(
for
:
timePeriod
,
indexPath
:
indexPath
)
return
cell
}
}
private
func
cellType
(
at
indexPath
:
IndexPath
)
->
ForecastCellType
{
switch
timePeriod
{
case
.
daily
:
return
self
.
dailySection
.
rows
[
indexPath
.
row
]
case
.
hourly
:
return
self
.
hourlySection
.
rows
[
indexPath
.
row
]
}
}
public
func
height
(
for
indexPath
:
IndexPath
)
->
CGFloat
{
let
cellType
=
cellType
(
at
:
indexPath
)
switch
cellType
{
case
.
adBanner
:
fallthrough
case
.
adMREC
:
let
cell
=
dequeueReusableCell
(
type
:
MRECAdCell
.
self
,
tableView
:
tableView
,
indexPath
:
indexPath
)
cell
.
adView
=
adView
(
for
:
timePeriod
,
indexPath
:
indexPath
)
return
cell
let
adView
=
adView
(
for
:
timePeriod
,
indexPath
:
indexPath
)
return
adView
.
adReady
?
UITableView
.
automaticDimension
:
0
default
:
return
UITableView
.
automaticDimension
}
}
public
func
setNeedsUpdate
()
{
self
.
cellsToUpdate
=
[
.
forecastDaily
,
.
forecastHourly
,
.
forecastDailyInfo
,
.
precipitation
,
.
wind
]
}
public
func
selectedWeatherDidChange
()
{
self
.
cellsToUpdate
=
[
.
forecastDailyInfo
,
.
precipitation
,
.
wind
]
}
public
func
willDisplay
(
cell
:
UITableViewCell
)
{
switch
cell
{
case
let
sunCell
as
SunPhaseCell
:
sunCell
.
updateSunPosition
()
case
let
moonCell
as
MoonPhaseCell
:
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
:
break
}
}
private
func
adView
(
for
timePeriod
:
TimePeriod
,
indexPath
:
IndexPath
)
->
AdView
{
if
let
adView
=
adViewCache
[
self
.
timePeriod
]?[
indexPath
]
{
return
adView
}
let
adView
=
AdView
()
adView
.
delegate
=
self
var
placementName
:
String
!
var
timePeriodString
:
String
!
var
adType
=
AdType
.
banner
var
adTypeString
=
"Banner"
var
adLoggingEmoji
=
"🔹"
switch
timePeriod
{
case
.
daily
:
timePeriodString
=
"D"
placementName
=
placementNameForecastDailyBanner
let
cellType
=
cellType
(
at
:
indexPath
)
if
cellType
==
.
adMREC
{
placementName
=
placementNameForecastDailySquare
adType
=
.
square
adTypeString
=
"MREC"
adLoggingEmoji
=
"✅"
}
case
.
hourly
:
placementName
=
placementNameForecastHourlyBanner
timePeriodString
=
"H"
let
cellType
=
cellType
(
at
:
indexPath
)
if
cellType
==
.
adMREC
{
placementName
=
placementNameForecastHourlySquare
adType
=
.
square
adTypeString
=
"MREC"
adLoggingEmoji
=
"✅"
}
}
adView
.
set
(
placementName
:
placementName
,
adType
:
adType
)
adView
.
loggingAlias
=
"
\(
adLoggingEmoji
)
Forecast
\(
timePeriodString
!
)
\(
adTypeString
)
"
var
edited
=
adViewCache
[
timePeriod
]
??
[
IndexPath
:
AdView
]()
edited
[
indexPath
]
=
adView
adViewCache
[
timePeriod
]
=
edited
return
adView
}
}
//MARK:- ForecastTimePeriodCell Delegate
...
...
@@ -266,3 +275,22 @@ extension ForecastCellFactory: ForecastDailyCellDelegate {
forecastViewModel
.
offsetHolder
.
update
(
offset
:
offset
)
}
}
// MARK: - AdViewDelegate
extension
ForecastCellFactory
:
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
)
}
}
}
}
1Weather/UI/View controllers/Forecast/ForecastViewController.swift
View file @
fda52da8
...
...
@@ -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
()
}
}
1Weather/UI/View controllers/Locations/Cells/LocationCellFactory.swift
View file @
fda52da8
...
...
@@ -8,7 +8,7 @@
import
UIKit
import
OneWeatherCore
class
LocationCellFactory
:
CellFactory
Protocol
{
class
LocationCellFactory
:
CellFactory
{
//Private
private
let
locationsViewModel
:
LocationsViewModel
...
...
1Weather/UI/View controllers/Menu/Cells/MenuCellFactory.swift
View file @
fda52da8
...
...
@@ -91,7 +91,7 @@ private struct SectionItem {
let
rows
:[
MenuRow
]
}
class
MenuCellFactory
<
T
>
:
CellFactory
Protocol
{
class
MenuCellFactory
<
T
>
:
CellFactory
{
//Private
private
let
menuViewModel
:
MenuViewModel
private
let
sections
:[
SectionItem
]
=
[
SectionItem
(
type
:
.
info
,
rows
:
[
.
settings
]),
...
...
1Weather/UI/View controllers/NWSAlert/Cells/NWSAlertCellFactory.swift
View file @
fda52da8
...
...
@@ -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
)
}
}
}
}
1Weather/UI/View controllers/NWSAlert/NWSAlertViewController.swift
View file @
fda52da8
...
...
@@ -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
{
...
...
1Weather/UI/View controllers/Radar/Cells/RadarLayersCellFactory.swift
View file @
fda52da8
...
...
@@ -18,7 +18,7 @@ private struct LayerSection {
let
rowsCount
:
Int
}
class
RadarLayersCellFactory
:
CellFactory
Protocol
{
class
RadarLayersCellFactory
:
CellFactory
{
//Private
private
let
radarViewModel
:
RadarViewModel
private
let
sections
:[
LayerSection
]
...
...
1Weather/UI/View controllers/Settings/Cells/SettingsCellFactory.swift
View file @
fda52da8
...
...
@@ -84,7 +84,7 @@ private struct SettingsDataSource {
let
rows
:[
SettingsRow
]
}
class
SettingsCellFactory
:
CellFactory
Protocol
{
class
SettingsCellFactory
:
CellFactory
{
//Private
private
let
viewModel
:
SettingsViewModel
private
let
sections
:
[
SettingsDataSource
]
=
{
...
...
1Weather/UI/View controllers/Settings/Cells/SettingsDetailsCellFactory.swift
View file @
fda52da8
...
...
@@ -9,7 +9,7 @@ import UIKit
import
Localize_Swift
import
OneWeatherCore
class
SettingsDetailsCellFactory
:
CellFactory
Protocol
{
class
SettingsDetailsCellFactory
:
CellFactory
{
//Private
private
let
viewModel
:
SettingsDetailsViewModel
...
...
1Weather/UI/View controllers/Today/Cells/TodayCellFactory.swift
View file @
fda52da8
...
...
@@ -50,7 +50,7 @@ private struct TodaySection {
}
}
class
TodayCellFactory
:
CellFactory
Protocol
{
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
)
}
}
}
}
1Weather/UI/View controllers/Today/TodayViewController.swift
View file @
fda52da8
...
...
@@ -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
...
...
1Weather/ViewModels/NWSAlertViewModel.swift
View file @
fda52da8
...
...
@@ -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
)
}
}
1Weather/ViewModels/TodayViewModel.swift
View file @
fda52da8
...
...
@@ -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
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment