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
0d5742e2
Commit
0d5742e2
authored
Aug 25, 2021
by
Demid Merzlyakov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IOS-176: feature availability control: move most part of the stuff to the new control.
parent
f916bb10
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
136 additions
and
34 deletions
+136
-34
1Weather/AppDelegate.swift
+42
-0
1Weather/Coordinators/AppCoordinator.swift
+5
-2
1Weather/Network/ConfigManager.swift
+40
-23
1Weather/Network/PushNotificationsManager.swift
+5
-1
1Weather/Network/ShortsManager.swift
+5
-1
1Weather/UI/View controllers/Shorts/ShortsViewController.swift
+5
-1
1Weather/ViewModels/MenuViewModel.swift
+5
-1
1Weather/ViewModels/TodayViewModel.swift
+5
-1
OneWeatherCore/OneWeatherCore.xcodeproj/project.pbxproj
+4
-0
OneWeatherCore/OneWeatherCore/Managers/FeatureAvailability/FeatureAvailabilityCheckers/DeviceTypeFeatureAvailabilityChecker.swift
+19
-0
OneWeatherCore/OneWeatherCore/Managers/FeatureAvailability/FeatureAvailabilityCheckers/PremiumInAppFeatureAvailabilityChecker.swift
+1
-4
No files found.
1Weather/AppDelegate.swift
View file @
0d5742e2
...
@@ -76,6 +76,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
...
@@ -76,6 +76,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
FirebaseApp
.
configure
()
FirebaseApp
.
configure
()
ConfigManager
.
shared
.
updateConfig
()
ConfigManager
.
shared
.
updateConfig
()
FeatureAvailabilityManager
.
shared
=
configureFeatureAvailabilityManager
(
with
:
LocationManager
.
shared
,
configManager
:
ConfigManager
.
shared
)
//App UI
//App UI
let
appCoordinator
=
AppCoordinator
(
window
:
self
.
window
!
,
launchOptions
:
launchOptions
)
let
appCoordinator
=
AppCoordinator
(
window
:
self
.
window
!
,
launchOptions
:
launchOptions
)
appCoordinator
.
start
()
appCoordinator
.
start
()
...
@@ -179,6 +181,46 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
...
@@ -179,6 +181,46 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}
}
}
}
}
}
private
func
configureFeatureAvailabilityManager
(
with
locationManager
:
LocationManager
,
configManager
:
ConfigManager
)
->
FeatureAvailabilityManager
{
let
usOnly
=
USOnlyFeatureAvailabilityChecker
{
[
weak
locationManager
]
in
return
locationManager
?
.
selectedLocation
}
let
premium
=
PremiumInAppFeatureAvailabilityChecker
()
let
proSubscription
=
ProSubscriptionAvailabilityChecker
()
let
isPhone
=
DeviceTypeFeatureAvailabilityChecker
(
deviceType
:
.
phone
)
var
availabilityCheckers
=
[
AppFeature
:
FeatureAvailabilityChecker
]()
for
feature
in
AppFeature
.
allCases
{
// To make sure all features are explicitly configured.
switch
feature
{
case
.
ads
:
availabilityCheckers
[
feature
]
=
!
premium
&&
!
proSubscription
case
.
minutelyForecast
:
availabilityCheckers
[
feature
]
=
proSubscription
case
.
shorts
:
availabilityCheckers
[
feature
]
=
usOnly
&&
isPhone
case
.
airQualityIndex
:
break
case
.
attPrompt
:
break
// config only
case
.
nwsAlertsViaMoEngage
:
break
// config only
case
.
onboarding
:
break
// config only
case
.
shortsLastNudge
:
break
// config only
}
}
let
manager
=
FeatureAvailabilityManager
(
configFetcher
:
{
[
weak
configManager
]
in
configManager
?
.
config
},
checkers
:
availabilityCheckers
)
return
manager
}
}
}
extension
AppDelegate
:
AppsFlyerLibDelegate
{
extension
AppDelegate
:
AppsFlyerLibDelegate
{
...
...
1Weather/Coordinators/AppCoordinator.swift
View file @
0d5742e2
...
@@ -26,6 +26,9 @@ class AppCoordinator: Coordinator {
...
@@ -26,6 +26,9 @@ class AppCoordinator: Coordinator {
var
parentCoordinator
:
Coordinator
?
var
parentCoordinator
:
Coordinator
?
var
childCoordinators
=
[
Coordinator
]()
var
childCoordinators
=
[
Coordinator
]()
private
var
featureAvailabilityManager
:
FeatureAvailabilityManager
{
FeatureAvailabilityManager
.
shared
}
init
(
window
:
UIWindow
,
launchOptions
:
[
UIApplication
.
LaunchOptionsKey
:
Any
]?)
{
init
(
window
:
UIWindow
,
launchOptions
:
[
UIApplication
.
LaunchOptionsKey
:
Any
]?)
{
self
.
window
=
window
self
.
window
=
window
...
@@ -109,7 +112,7 @@ class AppCoordinator: Coordinator {
...
@@ -109,7 +112,7 @@ class AppCoordinator: Coordinator {
DispatchQueue
.
main
.
async
{
DispatchQueue
.
main
.
async
{
self
.
logAppLaunchEvents
()
self
.
logAppLaunchEvents
()
if
ConfigManager
.
shared
.
config
.
showOnboarding
{
if
self
.
featureAvailabilityManager
.
isAvailable
(
feature
:
.
onboarding
)
{
if
Settings
.
shared
.
initialOnboardingShowed
{
if
Settings
.
shared
.
initialOnboardingShowed
{
self
.
finishInitialOnboarding
()
self
.
finishInitialOnboarding
()
}
}
...
@@ -158,7 +161,7 @@ class AppCoordinator: Coordinator {
...
@@ -158,7 +161,7 @@ class AppCoordinator: Coordinator {
firstOpenSource
=
.
url
firstOpenSource
=
.
url
}
}
let
flow
=
ConfigManager
.
shared
.
config
.
showOnboarding
?
"FTUX"
:
"default"
let
flow
=
featureAvailabilityManager
.
isAvailable
(
feature
:
.
onboarding
)
?
"FTUX"
:
"default"
analytics
(
log
:
.
ANALYTICS_FIRST_OPEN
,
analytics
(
log
:
.
ANALYTICS_FIRST_OPEN
,
params
:
[
.
ANALYTICS_KEY_FIRST_OPEN_SOURCE
:
firstOpenSource
.
rawValue
,
params
:
[
.
ANALYTICS_KEY_FIRST_OPEN_SOURCE
:
firstOpenSource
.
rawValue
,
.
ANALYTICS_KEY_FIRST_OPEN_FLOW
:
flow
])
.
ANALYTICS_KEY_FIRST_OPEN_FLOW
:
flow
])
...
...
1Weather/Network/ConfigManager.swift
View file @
0d5742e2
...
@@ -20,12 +20,8 @@ public class ConfigManager {
...
@@ -20,12 +20,8 @@ public class ConfigManager {
private
static
let
adConfigKey
=
"ads_config_ios"
private
static
let
adConfigKey
=
"ads_config_ios"
private
static
let
popularCitiesConfigKey
=
"search_screen_popular_cities"
private
static
let
popularCitiesConfigKey
=
"search_screen_popular_cities"
private
static
let
ccpaUpdateIntervalConfigKey
=
"ccpa_update_interval_ios"
private
static
let
ccpaUpdateIntervalConfigKey
=
"ccpa_update_interval_ios"
private
static
let
nwsAlertsViaMoEngageEnabledKey
=
"ios_nws_alerts_via_moengage_enabled"
private
static
let
showAttPromptKey
=
"ios_show_att_prompt"
private
static
let
shortsLeftBelowCountKey
=
"shorts_left_below_nudge_every_x_cards"
private
static
let
shortsLeftBelowCountKey
=
"shorts_left_below_nudge_every_x_cards"
private
static
let
shortsLastNudgeEnabledKey
=
"shorts_swipe_down_nudge_enabled"
private
static
let
shortsSwipeUpNudgeCountKey
=
"shorts_swipe_up_nudge_on_x_cards"
private
static
let
shortsSwipeUpNudgeCountKey
=
"shorts_swipe_up_nudge_on_x_cards"
private
static
let
showOnboardingKey
=
"ios_show_onboarding"
private
let
delegates
=
MulticastDelegate
<
ConfigManagerDelegate
>
()
private
let
delegates
=
MulticastDelegate
<
ConfigManagerDelegate
>
()
...
@@ -44,12 +40,15 @@ public class ConfigManager {
...
@@ -44,12 +40,15 @@ public class ConfigManager {
public
var
config
:
AppConfig
=
AppConfig
(
popularCities
:
nil
,
public
var
config
:
AppConfig
=
AppConfig
(
popularCities
:
nil
,
adConfig
:
AdConfig
(),
adConfig
:
AdConfig
(),
ccpaUpdateInterval
:
nil
,
ccpaUpdateInterval
:
nil
,
nwsAlertsViaMoEngageEnabled
:
true
,
showAttPrompt
:
false
,
shortsLeftBelowCountKey
:
0
,
shortsLeftBelowCountKey
:
0
,
shortsLastNudgeEnabledKey
:
false
,
shortsSwipeUpNudgeCountKey
:
0
,
shortsSwipeUpNudgeCountKey
:
0
,
showOnboarding
:
false
)
explicitFeatureAvailability
:
[
.
nwsAlertsViaMoEngage
:
true
,
.
attPrompt
:
false
,
.
shortsLastNudge
:
false
,
.
onboarding
:
false
]
)
public
func
updateConfig
()
{
public
func
updateConfig
()
{
log
.
info
(
"update config"
)
log
.
info
(
"update config"
)
...
@@ -87,11 +86,23 @@ public class ConfigManager {
...
@@ -87,11 +86,23 @@ public class ConfigManager {
delegates
.
remove
(
delegate
:
delegate
)
delegates
.
remove
(
delegate
:
delegate
)
}
}
private
func
parseFeatureAvailability
()
->
[
AppFeature
:
Bool
]
{
var
featureAvailability
=
[
AppFeature
:
Bool
]()
for
feature
in
AppFeature
.
allCases
{
if
let
configName
=
feature
.
configVariableName
{
let
configValue
=
remoteConfig
.
configValue
(
forKey
:
configName
)
featureAvailability
[
feature
]
=
configValue
.
boolValue
}
}
return
featureAvailability
}
private
func
parseConfigFromFirebase
(
source
:
String
)
{
private
func
parseConfigFromFirebase
(
source
:
String
)
{
log
.
info
(
"Got config from
\(
source
)
"
)
log
.
info
(
"Got config from
\(
source
)
"
)
var
configErrors
=
[
Error
]()
var
configErrors
=
[
Error
]()
let
decoder
=
JSONDecoder
()
let
decoder
=
JSONDecoder
()
var
adConfig
=
AdConfig
()
var
adConfig
=
AdConfig
()
do
{
do
{
let
adConfigData
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
adConfigKey
)
.
dataValue
let
adConfigData
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
adConfigKey
)
.
dataValue
...
@@ -123,34 +134,22 @@ public class ConfigManager {
...
@@ -123,34 +134,22 @@ public class ConfigManager {
if
ccpaUpdateIntervalConfigValue
.
source
==
RemoteConfigSource
.
remote
{
if
ccpaUpdateIntervalConfigValue
.
source
==
RemoteConfigSource
.
remote
{
ccpaUpdateInterval
=
ccpaUpdateIntervalConfigValue
.
numberValue
.
doubleValue
ccpaUpdateInterval
=
ccpaUpdateIntervalConfigValue
.
numberValue
.
doubleValue
}
}
let
nwsAlertsViaMoEngageEnabledValue
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
nwsAlertsViaMoEngageEnabledKey
)
let
nwsAlertsViaMoEngageEnabled
=
nwsAlertsViaMoEngageEnabledValue
.
boolValue
let
showAttPromptValue
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
showAttPromptKey
)
let
showAttPrompt
=
showAttPromptValue
.
boolValue
let
shortsLeftBelowCountValue
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
shortsLeftBelowCountKey
)
let
shortsLeftBelowCountValue
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
shortsLeftBelowCountKey
)
let
shortsLeftBelowCount
=
shortsLeftBelowCountValue
.
numberValue
.
intValue
let
shortsLeftBelowCount
=
shortsLeftBelowCountValue
.
numberValue
.
intValue
let
shortsLastNudgeEnabledValue
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
shortsLastNudgeEnabledKey
)
let
shortsLastNudgeEnabled
=
shortsLastNudgeEnabledValue
.
boolValue
let
shortsSwipeNudgeCountValue
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
shortsSwipeUpNudgeCountKey
)
let
shortsSwipeNudgeCountValue
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
shortsSwipeUpNudgeCountKey
)
let
shortsSwipeNudgeCount
=
shortsSwipeNudgeCountValue
.
numberValue
.
intValue
let
shortsSwipeNudgeCount
=
shortsSwipeNudgeCountValue
.
numberValue
.
intValue
let
showOnboardingValue
=
remoteConfig
.
configValue
(
forKey
:
ConfigManager
.
showOnboardingKey
)
let
featureAvailability
=
parseFeatureAvailability
()
let
showOnboarding
=
showOnboardingValue
.
boolValue
DispatchQueue
.
main
.
async
{
DispatchQueue
.
main
.
async
{
self
.
config
=
AppConfig
(
popularCities
:
popularCities
,
self
.
config
=
AppConfig
(
popularCities
:
popularCities
,
adConfig
:
adConfig
,
adConfig
:
adConfig
,
ccpaUpdateInterval
:
ccpaUpdateInterval
,
ccpaUpdateInterval
:
ccpaUpdateInterval
,
nwsAlertsViaMoEngageEnabled
:
nwsAlertsViaMoEngageEnabled
,
showAttPrompt
:
showAttPrompt
,
shortsLeftBelowCountKey
:
shortsLeftBelowCount
,
shortsLeftBelowCountKey
:
shortsLeftBelowCount
,
shortsLastNudgeEnabledKey
:
shortsLastNudgeEnabled
,
shortsSwipeUpNudgeCountKey
:
shortsSwipeNudgeCount
,
shortsSwipeUpNudgeCountKey
:
shortsSwipeNudgeCount
,
showOnboarding
:
showOnboarding
)
explicitFeatureAvailability
:
featureAvailability
)
self
.
notifyAboutConfigUpdate
()
self
.
notifyAboutConfigUpdate
()
DispatchQueue
.
global
()
.
async
{
DispatchQueue
.
global
()
.
async
{
let
encoder
=
JSONEncoder
()
let
encoder
=
JSONEncoder
()
...
@@ -171,3 +170,21 @@ public class ConfigManager {
...
@@ -171,3 +170,21 @@ public class ConfigManager {
}
}
}
}
}
}
fileprivate
extension
AppFeature
{
var
configVariableName
:
String
?
{
switch
self
{
case
.
nwsAlertsViaMoEngage
:
return
"ios_nws_alerts_via_moengage_enabled"
case
.
attPrompt
:
return
"ios_show_att_prompt"
case
.
shortsLastNudge
:
return
"shorts_swipe_down_nudge_enabled"
case
.
onboarding
:
return
"ios_show_onboarding"
case
.
ads
,
.
airQualityIndex
,
.
minutelyForecast
,
.
shorts
:
return
nil
// don't use 'default', so that we didn't add new features here in the future.
}
}
}
1Weather/Network/PushNotificationsManager.swift
View file @
0d5742e2
...
@@ -56,8 +56,12 @@ public class PushNotificationsManager: NSObject, PushNotificationsManagerProtoco
...
@@ -56,8 +56,12 @@ public class PushNotificationsManager: NSObject, PushNotificationsManagerProtoco
internal
var
lastSetFIPSList
:
String
?
=
""
internal
var
lastSetFIPSList
:
String
?
=
""
internal
var
lastSetFIPSCode
:
String
?
=
""
internal
var
lastSetFIPSCode
:
String
?
=
""
private
var
featureAvailabilityManager
:
FeatureAvailabilityManager
{
FeatureAvailabilityManager
.
shared
}
private
func
updateNwsSubscriptions
(
with
fipsList
:
String
?,
currentFipsCode
:
String
?)
{
private
func
updateNwsSubscriptions
(
with
fipsList
:
String
?,
currentFipsCode
:
String
?)
{
if
configManager
.
config
.
nwsAlertsViaMoEngageEnabled
{
if
featureAvailabilityManager
.
isAvailable
(
feature
:
.
nwsAlertsViaMoEngage
)
{
if
fipsList
!=
lastSetFIPSList
{
if
fipsList
!=
lastSetFIPSList
{
log
.
info
(
"Set
\(
AnalyticsAttribute
.
fipsList
.
attributeName
)
to '
\(
fipsList
??
""
)
'"
)
log
.
info
(
"Set
\(
AnalyticsAttribute
.
fipsList
.
attributeName
)
to '
\(
fipsList
??
""
)
'"
)
lastSetFIPSList
=
fipsList
lastSetFIPSList
=
fipsList
...
...
1Weather/Network/ShortsManager.swift
View file @
0d5742e2
...
@@ -20,8 +20,12 @@ class ShortsManager {
...
@@ -20,8 +20,12 @@ class ShortsManager {
static
let
shared
=
ShortsManager
()
static
let
shared
=
ShortsManager
()
let
multicastDelegate
=
MulticastDelegate
<
ShortsManagerDelegate
>
()
let
multicastDelegate
=
MulticastDelegate
<
ShortsManagerDelegate
>
()
private(set)
var
shorts
=
[
ShortsItem
]()
private(set)
var
shorts
=
[
ShortsItem
]()
private
var
featureAvailabilityManager
:
FeatureAvailabilityManager
{
FeatureAvailabilityManager
.
shared
}
var
shortsAvailable
:
Bool
{
var
shortsAvailable
:
Bool
{
return
LocationManager
.
shared
.
selectedLocation
?
.
countryCode
==
"US"
&&
UIDevice
.
current
.
userInterfaceIdiom
==
.
phone
return
featureAvailabilityManager
.
isAvailable
(
feature
:
.
shorts
)
}
}
//Private
//Private
...
...
1Weather/UI/View controllers/Shorts/ShortsViewController.swift
View file @
0d5742e2
...
@@ -50,6 +50,10 @@ class ShortsViewController: UIViewController {
...
@@ -50,6 +50,10 @@ class ShortsViewController: UIViewController {
return
scheduler
return
scheduler
}()
}()
private
var
featureAvailabilityManager
:
FeatureAvailabilityManager
{
FeatureAvailabilityManager
.
shared
}
deinit
{
deinit
{
coordinator
.
viewControllerDidEnd
(
controller
:
self
)
coordinator
.
viewControllerDidEnd
(
controller
:
self
)
NotificationCenter
.
default
.
removeObserver
(
self
)
NotificationCenter
.
default
.
removeObserver
(
self
)
...
@@ -150,7 +154,7 @@ class ShortsViewController: UIViewController {
...
@@ -150,7 +154,7 @@ class ShortsViewController: UIViewController {
}
}
//Show the swipe helper view if needed
//Show the swipe helper view if needed
if
ConfigManager
.
shared
.
config
.
shortsLastNudgeEnabled
{
if
featureAvailabilityManager
.
isAvailable
(
feature
:
.
shortsLastNudge
)
{
//Check for the last row
//Check for the last row
if
rowIndex
==
viewModel
.
shorts
.
count
-
1
{
if
rowIndex
==
viewModel
.
shorts
.
count
-
1
{
swipeHelperView
.
configure
(
forState
:
.
downViewedAll
)
swipeHelperView
.
configure
(
forState
:
.
downViewedAll
)
...
...
1Weather/ViewModels/MenuViewModel.swift
View file @
0d5742e2
...
@@ -126,9 +126,13 @@ class MenuViewModel: NSObject, ViewModelProtocol {
...
@@ -126,9 +126,13 @@ class MenuViewModel: NSObject, ViewModelProtocol {
// MARK: - Help section
// MARK: - Help section
extension
MenuViewModel
{
extension
MenuViewModel
{
private
var
featureAvailabilityManager
:
FeatureAvailabilityManager
{
FeatureAvailabilityManager
.
shared
}
private
func
helpRequestBodyString
()
->
String
{
private
func
helpRequestBodyString
()
->
String
{
var
str
=
String
()
var
str
=
String
()
str
.
append
(
"Weather Alerts Enabled:
\(
ConfigManager
.
shared
.
config
.
nwsAlertsViaMoEngageEnabled
)\n
"
)
str
.
append
(
"Weather Alerts Enabled:
\(
featureAvailabilityManager
.
isAvailable
(
feature
:
.
nwsAlertsViaMoEngage
)
)\n
"
)
let
isRegistered
=
UIApplication
.
shared
.
isRegisteredForRemoteNotifications
let
isRegistered
=
UIApplication
.
shared
.
isRegisteredForRemoteNotifications
str
.
append
(
"Push Enabled:
\(
isRegistered
)\n
"
)
str
.
append
(
"Push Enabled:
\(
isRegistered
)\n
"
)
...
...
1Weather/ViewModels/TodayViewModel.swift
View file @
0d5742e2
...
@@ -35,6 +35,10 @@ class TodayViewModel: ViewModelProtocol {
...
@@ -35,6 +35,10 @@ class TodayViewModel: ViewModelProtocol {
shortsManager
.
shorts
shortsManager
.
shorts
}
}
private
var
featureAvailabilityManager
:
FeatureAvailabilityManager
{
FeatureAvailabilityManager
.
shared
}
public
lazy
var
todayCellFactory
:
TodayCellFactory
=
{
public
lazy
var
todayCellFactory
:
TodayCellFactory
=
{
let
factory
=
TodayCellFactory
(
viewModel
:
self
)
let
factory
=
TodayCellFactory
(
viewModel
:
self
)
factory
.
delegate
=
self
factory
.
delegate
=
self
...
@@ -127,7 +131,7 @@ class TodayViewModel: ViewModelProtocol {
...
@@ -127,7 +131,7 @@ class TodayViewModel: ViewModelProtocol {
// not calling onboardingFlowCompleted, because it will be called in the ATT prompt completion handler.
// not calling onboardingFlowCompleted, because it will be called in the ATT prompt completion handler.
return
return
}
}
if
self
.
configManager
.
config
.
showAttPrompt
if
self
.
featureAvailabilityManager
.
isAvailable
(
feature
:
.
attPrompt
)
&&
!
self
.
ccpaHelper
.
isNewUser
&&
!
self
.
ccpaHelper
.
isNewUser
&&
ATTrackingManager
.
trackingAuthorizationStatus
==
.
notDetermined
{
&&
ATTrackingManager
.
trackingAuthorizationStatus
==
.
notDetermined
{
...
...
OneWeatherCore/OneWeatherCore.xcodeproj/project.pbxproj
View file @
0d5742e2
...
@@ -88,6 +88,7 @@
...
@@ -88,6 +88,7 @@
CE72A76A26D676A000F13CF7
/* USOnlyFeatureAvailabilityChecker.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE72A76926D676A000F13CF7
/* USOnlyFeatureAvailabilityChecker.swift */
;
};
CE72A76A26D676A000F13CF7
/* USOnlyFeatureAvailabilityChecker.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE72A76926D676A000F13CF7
/* USOnlyFeatureAvailabilityChecker.swift */
;
};
CE72A76C26D6782F00F13CF7
/* PremiumInAppFeatureAvailabilityChecker.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE72A76B26D6782F00F13CF7
/* PremiumInAppFeatureAvailabilityChecker.swift */
;
};
CE72A76C26D6782F00F13CF7
/* PremiumInAppFeatureAvailabilityChecker.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE72A76B26D6782F00F13CF7
/* PremiumInAppFeatureAvailabilityChecker.swift */
;
};
CE72A76E26D680DF00F13CF7
/* ProSubscriptionAvailabilityChecker.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE72A76D26D680DF00F13CF7
/* ProSubscriptionAvailabilityChecker.swift */
;
};
CE72A76E26D680DF00F13CF7
/* ProSubscriptionAvailabilityChecker.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE72A76D26D680DF00F13CF7
/* ProSubscriptionAvailabilityChecker.swift */
;
};
CE72A77026D6917300F13CF7
/* DeviceTypeFeatureAvailabilityChecker.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CE72A76F26D6917300F13CF7
/* DeviceTypeFeatureAvailabilityChecker.swift */
;
};
CEFE851826948C15003C67D3
/* SmartTextProvider.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CEFE851726948C15003C67D3
/* SmartTextProvider.swift */
;
};
CEFE851826948C15003C67D3
/* SmartTextProvider.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CEFE851726948C15003C67D3
/* SmartTextProvider.swift */
;
};
CEFE851C2694986D003C67D3
/* SmartText.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CEFE851B2694986D003C67D3
/* SmartText.swift */
;
};
CEFE851C2694986D003C67D3
/* SmartText.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CEFE851B2694986D003C67D3
/* SmartText.swift */
;
};
CEFE85202694C4BC003C67D3
/* DefaultSmartText.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CEFE851F2694C4BC003C67D3
/* DefaultSmartText.swift */
;
};
CEFE85202694C4BC003C67D3
/* DefaultSmartText.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
CEFE851F2694C4BC003C67D3
/* DefaultSmartText.swift */
;
};
...
@@ -198,6 +199,7 @@
...
@@ -198,6 +199,7 @@
CE72A76926D676A000F13CF7
/* USOnlyFeatureAvailabilityChecker.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
USOnlyFeatureAvailabilityChecker.swift
;
sourceTree
=
"<group>"
;
};
CE72A76926D676A000F13CF7
/* USOnlyFeatureAvailabilityChecker.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
USOnlyFeatureAvailabilityChecker.swift
;
sourceTree
=
"<group>"
;
};
CE72A76B26D6782F00F13CF7
/* PremiumInAppFeatureAvailabilityChecker.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PremiumInAppFeatureAvailabilityChecker.swift
;
sourceTree
=
"<group>"
;
};
CE72A76B26D6782F00F13CF7
/* PremiumInAppFeatureAvailabilityChecker.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
PremiumInAppFeatureAvailabilityChecker.swift
;
sourceTree
=
"<group>"
;
};
CE72A76D26D680DF00F13CF7
/* ProSubscriptionAvailabilityChecker.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ProSubscriptionAvailabilityChecker.swift
;
sourceTree
=
"<group>"
;
};
CE72A76D26D680DF00F13CF7
/* ProSubscriptionAvailabilityChecker.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
ProSubscriptionAvailabilityChecker.swift
;
sourceTree
=
"<group>"
;
};
CE72A76F26D6917300F13CF7
/* DeviceTypeFeatureAvailabilityChecker.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
DeviceTypeFeatureAvailabilityChecker.swift
;
sourceTree
=
"<group>"
;
};
CEFE851726948C15003C67D3
/* SmartTextProvider.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SmartTextProvider.swift
;
sourceTree
=
"<group>"
;
};
CEFE851726948C15003C67D3
/* SmartTextProvider.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SmartTextProvider.swift
;
sourceTree
=
"<group>"
;
};
CEFE851B2694986D003C67D3
/* SmartText.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SmartText.swift
;
sourceTree
=
"<group>"
;
};
CEFE851B2694986D003C67D3
/* SmartText.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SmartText.swift
;
sourceTree
=
"<group>"
;
};
CEFE851D2694C477003C67D3
/* SmartTextMacro.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SmartTextMacro.swift
;
sourceTree
=
"<group>"
;
};
CEFE851D2694C477003C67D3
/* SmartTextMacro.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SmartTextMacro.swift
;
sourceTree
=
"<group>"
;
};
...
@@ -500,6 +502,7 @@
...
@@ -500,6 +502,7 @@
CE72A76926D676A000F13CF7
/* USOnlyFeatureAvailabilityChecker.swift */
,
CE72A76926D676A000F13CF7
/* USOnlyFeatureAvailabilityChecker.swift */
,
CE72A76B26D6782F00F13CF7
/* PremiumInAppFeatureAvailabilityChecker.swift */
,
CE72A76B26D6782F00F13CF7
/* PremiumInAppFeatureAvailabilityChecker.swift */
,
CE72A76D26D680DF00F13CF7
/* ProSubscriptionAvailabilityChecker.swift */
,
CE72A76D26D680DF00F13CF7
/* ProSubscriptionAvailabilityChecker.swift */
,
CE72A76F26D6917300F13CF7
/* DeviceTypeFeatureAvailabilityChecker.swift */
,
);
);
path
=
FeatureAvailabilityCheckers
;
path
=
FeatureAvailabilityCheckers
;
sourceTree
=
"<group>"
;
sourceTree
=
"<group>"
;
...
@@ -763,6 +766,7 @@
...
@@ -763,6 +766,7 @@
CDFE459426566D7B0021A29F
/* HealthSource.swift in Sources */
,
CDFE459426566D7B0021A29F
/* HealthSource.swift in Sources */
,
CD615F9A265526E700B717DB
/* CurrentWeather.swift in Sources */
,
CD615F9A265526E700B717DB
/* CurrentWeather.swift in Sources */
,
CD615F9B265526E700B717DB
/* DailyWeather.swift in Sources */
,
CD615F9B265526E700B717DB
/* DailyWeather.swift in Sources */
,
CE72A77026D6917300F13CF7
/* DeviceTypeFeatureAvailabilityChecker.swift in Sources */
,
CD615F9C265526E700B717DB
/* HourlyWeather.swift in Sources */
,
CD615F9C265526E700B717DB
/* HourlyWeather.swift in Sources */
,
CD615F9D265526E700B717DB
/* DayTimeWeather.swift in Sources */
,
CD615F9D265526E700B717DB
/* DayTimeWeather.swift in Sources */
,
CD615F9E265526E700B717DB
/* Health.swift in Sources */
,
CD615F9E265526E700B717DB
/* Health.swift in Sources */
,
...
...
OneWeatherCore/OneWeatherCore/Managers/FeatureAvailability/FeatureAvailabilityCheckers/DeviceTypeFeatureAvailabilityChecker.swift
0 → 100644
View file @
0d5742e2
//
// DeviceTypeFeatureAvailabilityChecker.swift
// OneWeatherCore
//
// Created by Demid Merzlyakov on 25.08.2021.
//
import
UIKit
public
struct
DeviceTypeFeatureAvailabilityChecker
:
FeatureAvailabilityChecker
{
let
deviceType
:
UIUserInterfaceIdiom
public
init
(
deviceType
:
UIUserInterfaceIdiom
)
{
self
.
deviceType
=
deviceType
}
public
var
isAvailable
:
Bool
{
UIDevice
.
current
.
userInterfaceIdiom
==
deviceType
}
}
OneWeatherCore/OneWeatherCore/Managers/FeatureAvailability/FeatureAvailabilityCheckers/PremiumInAppFeatureAvailabilityChecker.swift
View file @
0d5742e2
...
@@ -11,9 +11,6 @@ public struct PremiumInAppFeatureAvailabilityChecker: FeatureAvailabilityChecker
...
@@ -11,9 +11,6 @@ public struct PremiumInAppFeatureAvailabilityChecker: FeatureAvailabilityChecker
public
init
()
{}
public
init
()
{}
public
var
isAvailable
:
Bool
{
public
var
isAvailable
:
Bool
{
if
let
metricsLog
=
UserDefaults
.
standard
.
dictionary
(
forKey
:
kOLAppMetricsKey
)
{
isAppPro
()
return
metricsLog
[
kEventInAppPurchasedCompleted
]
!=
nil
}
return
false
}
}
}
}
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