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
cfd25127
Commit
cfd25127
authored
Sep 16, 2021
by
Dmitry Stepanets
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- Added in-app checked
- Updated UI
parent
f1cc460a
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
429 additions
and
46 deletions
+429
-46
1Weather/AppDelegate.swift
+2
-1
1Weather/InApps/Configuration.storekit
+15
-1
1Weather/InApps/StoreManager.swift
+50
-5
1Weather/Resources/Assets.xcassets/menu/menu_restore.imageset/Contents.json
+16
-0
1Weather/Resources/Assets.xcassets/menu/menu_restore.imageset/menu_restore.pdf
+283
-0
1Weather/Resources/en.lproj/Localizable.strings
+1
-0
1Weather/UI/View controllers/Menu/Cells/MenuCellFactory.swift
+20
-7
1Weather/UI/View controllers/Menu/Header/MenuHeaderView.swift
+32
-29
1Weather/UI/View controllers/Menu/MenuViewController.swift
+4
-0
1Weather/UI/View controllers/Subscriptions/SubscriptionOverviewViewController.swift
+1
-1
1Weather/ViewModels/MenuViewModel.swift
+4
-0
1Weather/ViewModels/SubscriptionViewModel.swift
+1
-2
No files found.
1Weather/AppDelegate.swift
View file @
cfd25127
...
@@ -164,7 +164,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
...
@@ -164,7 +164,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func
applicationDidBecomeActive
(
_
application
:
UIApplication
)
{
func
applicationDidBecomeActive
(
_
application
:
UIApplication
)
{
LocationManager
.
shared
.
updateEverythingIfNeeded
()
LocationManager
.
shared
.
updateEverythingIfNeeded
()
storeManager
.
verifySubscriptions
()
storeManager
.
verifyPurchases
()
if
#available(iOS 14, *)
{
if
#available(iOS 14, *)
{
WidgetManager
.
shared
.
refreshAnalytics
()
WidgetManager
.
shared
.
refreshAnalytics
()
...
...
1Weather/InApps/Configuration.storekit
View file @
cfd25127
...
@@ -4,7 +4,21 @@
...
@@ -4,7 +4,21 @@
],
],
"products" : [
"products" : [
{
"displayPrice" : "1.99",
"familyShareable" : false,
"internalID" : "22A7BDE0",
"localizations" : [
{
"description" : "",
"displayName" : "Upgrade to 1Weather Pro",
"locale" : "en_US"
}
],
"productID" : "com.onelouder.oneweather.inapp1",
"referenceName" : "1Weather Pro ",
"type" : "NonConsumable"
}
],
],
"settings" : {
"settings" : {
"_timeRate" : 6
"_timeRate" : 6
...
...
1Weather/InApps/StoreManager.swift
View file @
cfd25127
...
@@ -91,7 +91,7 @@ public class StoreManager {
...
@@ -91,7 +91,7 @@ public class StoreManager {
self
.
checkSubscriptionExpirationLocally
()
self
.
checkSubscriptionExpirationLocally
()
self
.
completeTransactions
()
self
.
completeTransactions
()
self
.
updateProductInfo
()
self
.
updateProductInfo
()
self
.
verify
Subscription
s
()
self
.
verify
Purchase
s
()
#warning("Not implemented!")
#warning("Not implemented!")
//TODO: implement
//TODO: implement
...
@@ -187,9 +187,44 @@ public class StoreManager {
...
@@ -187,9 +187,44 @@ public class StoreManager {
}
}
}
}
public
func
verifySubscriptions
()
{
public
func
purchaseInApp
()
{
let
log
=
self
.
log
let
log
=
self
.
log
log
.
info
(
"Verify subscriptions..."
)
log
.
info
(
"Purchase In-app start"
)
SwiftyStoreKit
.
purchaseProduct
(
kInAppOneWeatherProId
,
atomically
:
true
)
{
result
in
switch
result
{
case
.
success
(
let
product
):
if
product
.
needsFinishTransaction
{
SwiftyStoreKit
.
finishTransaction
(
product
.
transaction
)
}
log
.
info
(
"In app bought"
)
self
.
removeAdsPurchased
=
true
case
.
error
(
error
:
let
error
):
log
.
error
(
"Purchase in-app: error for
\(
kInAppOneWeatherProId
)
:
\(
error
)
"
)
}
}
}
public
func
restoreInApp
()
{
SwiftyStoreKit
.
restorePurchases
(
atomically
:
true
)
{[
weak
self
]
results
in
if
results
.
restoreFailedPurchases
.
count
>
0
{
self
?
.
log
.
error
(
"Restore Failed:
\(
results
.
restoreFailedPurchases
)
"
)
}
else
if
results
.
restoredPurchases
.
count
>
0
{
let
ids
=
results
.
restoredPurchases
.
compactMap
{
$0
.
productId
}
if
(
ids
.
contains
{
$0
==
kInAppOneWeatherProId
})
{
self
?
.
log
.
info
(
"Restore Success:
\(
results
.
restoredPurchases
)
"
)
self
?
.
removeAdsPurchased
=
true
}
}
else
{
self
?
.
log
.
info
(
"Nothing to Restore"
)
}
}
}
public
func
verifyPurchases
()
{
let
log
=
self
.
log
log
.
info
(
"Verify purchases..."
)
let
service
:
AppleReceiptValidator
.
VerifyReceiptURLType
let
service
:
AppleReceiptValidator
.
VerifyReceiptURLType
#if DEBUG
#if DEBUG
service
=
.
sandbox
service
=
.
sandbox
...
@@ -201,6 +236,16 @@ public class StoreManager {
...
@@ -201,6 +236,16 @@ public class StoreManager {
SwiftyStoreKit
.
verifyReceipt
(
using
:
appleValidator
)
{
result
in
SwiftyStoreKit
.
verifyReceipt
(
using
:
appleValidator
)
{
result
in
switch
result
{
switch
result
{
case
.
success
(
let
receipt
):
case
.
success
(
let
receipt
):
//In-app
let
purchaseInAppResult
=
SwiftyStoreKit
.
verifyPurchase
(
productId
:
kInAppOneWeatherProId
,
inReceipt
:
receipt
)
switch
purchaseInAppResult
{
case
.
purchased
:
self
.
removeAdsPurchased
=
true
case
.
notPurchased
:
self
.
removeAdsPurchased
=
false
}
//Subscriptions
let
purchaseResult
=
SwiftyStoreKit
.
verifySubscriptions
(
ofType
:
.
autoRenewable
,
productIds
:
self
.
allSubscriptionIds
,
inReceipt
:
receipt
)
let
purchaseResult
=
SwiftyStoreKit
.
verifySubscriptions
(
ofType
:
.
autoRenewable
,
productIds
:
self
.
allSubscriptionIds
,
inReceipt
:
receipt
)
switch
purchaseResult
{
switch
purchaseResult
{
case
.
purchased
(
let
expiryDate
,
let
items
):
case
.
purchased
(
let
expiryDate
,
let
items
):
...
@@ -223,11 +268,11 @@ public class StoreManager {
...
@@ -223,11 +268,11 @@ public class StoreManager {
log
.
error
(
"Receipt verification failed:
\(
error
)
"
)
log
.
error
(
"Receipt verification failed:
\(
error
)
"
)
self
.
hasSubscription
=
false
self
.
hasSubscription
=
false
self
.
everHadSubscription
=
false
self
.
everHadSubscription
=
false
self
.
removeAdsPurchased
=
false
self
.
subscriptionExpirationDate
=
nil
self
.
subscriptionExpirationDate
=
nil
}
}
}
}
}
}
//MARK: - Observers management
//MARK: - Observers management
public
func
add
(
observer
:
StoreManagerObserver
)
{
public
func
add
(
observer
:
StoreManagerObserver
)
{
...
@@ -264,6 +309,6 @@ public class StoreManager {
...
@@ -264,6 +309,6 @@ public class StoreManager {
extension
StoreManager
:
ConfigManagerDelegate
{
extension
StoreManager
:
ConfigManagerDelegate
{
public
func
dataUpdated
(
by
configManager
:
ConfigManager
)
{
public
func
dataUpdated
(
by
configManager
:
ConfigManager
)
{
self
.
updateProductInfo
()
self
.
updateProductInfo
()
self
.
verify
Subscription
s
()
self
.
verify
Purchase
s
()
}
}
}
}
1Weather/Resources/Assets.xcassets/menu/menu_restore.imageset/Contents.json
0 → 100644
View file @
cfd25127
{
"images"
:
[
{
"filename"
:
"menu_restore.pdf"
,
"idiom"
:
"universal"
}
],
"info"
:
{
"author"
:
"xcode"
,
"version"
:
1
},
"properties"
:
{
"preserves-vector-representation"
:
true
,
"template-rendering-intent"
:
"template"
}
}
1Weather/Resources/Assets.xcassets/menu/menu_restore.imageset/menu_restore.pdf
0 → 100644
View file @
cfd25127
No preview for this file type
1Weather/Resources/en.lproj/Localizable.strings
View file @
cfd25127
...
@@ -202,6 +202,7 @@
...
@@ -202,6 +202,7 @@
"menu.upgradeNow" = "Upgrade now";
"menu.upgradeNow" = "Upgrade now";
"menu.settings" = "Settings";
"menu.settings" = "Settings";
"menu.subscriptionOverview" = "Premium";
"menu.subscriptionOverview" = "Premium";
"menu.restorePurchases" = "Restore purchases";
"menu.about" = "About us";
"menu.about" = "About us";
"menu.ad" = "Ad choices";
"menu.ad" = "Ad choices";
"menu.rateUs" = "Rate us";
"menu.rateUs" = "Rate us";
...
...
1Weather/UI/View controllers/Menu/Cells/MenuCellFactory.swift
View file @
cfd25127
...
@@ -10,6 +10,7 @@ import UIKit
...
@@ -10,6 +10,7 @@ import UIKit
public
enum
MenuRow
{
public
enum
MenuRow
{
case
settings
case
settings
case
subscriptionOverview
case
subscriptionOverview
case
restorePurchases
case
about
case
about
case
ad
case
ad
case
rateUs
case
rateUs
...
@@ -38,6 +39,8 @@ public enum MenuRow {
...
@@ -38,6 +39,8 @@ public enum MenuRow {
return
UIImage
(
named
:
"menu_device_id"
)
return
UIImage
(
named
:
"menu_device_id"
)
case
.
subscriptionOverview
:
case
.
subscriptionOverview
:
return
UIImage
(
named
:
"menu_crown"
)
return
UIImage
(
named
:
"menu_crown"
)
case
.
restorePurchases
:
return
UIImage
(
named
:
"menu_restore"
)
}
}
}
}
...
@@ -61,22 +64,26 @@ public enum MenuRow {
...
@@ -61,22 +64,26 @@ public enum MenuRow {
return
"menu.deviceId"
.
localized
()
return
"menu.deviceId"
.
localized
()
case
.
subscriptionOverview
:
case
.
subscriptionOverview
:
return
"menu.subscriptionOverview"
.
localized
()
return
"menu.subscriptionOverview"
.
localized
()
case
.
restorePurchases
:
return
"menu.restorePurchases"
.
localized
()
}
}
}
}
var
roundedCorners
:
CACornerMask
{
var
roundedCorners
:
CACornerMask
{
switch
self
{
switch
self
{
case
.
settings
:
case
.
settings
:
if
StoreManager
.
shared
.
hasSubscription
{
if
!
StoreManager
.
shared
.
hasSubscription
&&
StoreManager
.
shared
.
removeAdsPurchased
{
return
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
]
return
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
,
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
]
}
}
else
{
else
{
return
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
,
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
]
return
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
]
}
}
case
.
about
:
case
.
restorePurchases
:
return
[
.
layerMinXM
inYCorner
,
.
layerMaxXMin
YCorner
]
return
[
.
layerMinXM
axYCorner
,
.
layerMaxXMax
YCorner
]
case
.
subscriptionOverview
:
case
.
subscriptionOverview
:
return
[
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
]
return
[
.
layerMinXMaxYCorner
,
.
layerMaxXMaxYCorner
]
case
.
about
:
return
[
.
layerMinXMinYCorner
,
.
layerMaxXMinYCorner
]
case
.
ad
:
case
.
ad
:
return
[]
return
[]
case
.
rateUs
:
case
.
rateUs
:
...
@@ -131,8 +138,14 @@ class MenuCellFactory<T>: CellFactory {
...
@@ -131,8 +138,14 @@ class MenuCellFactory<T>: CellFactory {
rows
:
[
.
settings
,
.
subscriptionOverview
])
rows
:
[
.
settings
,
.
subscriptionOverview
])
}
}
else
{
else
{
infoSectionItem
=
SectionItem
(
type
:
.
info
,
if
StoreManager
.
shared
.
removeAdsPurchased
{
rows
:
[
.
settings
])
infoSectionItem
=
SectionItem
(
type
:
.
info
,
rows
:
[
.
settings
])
}
else
{
infoSectionItem
=
SectionItem
(
type
:
.
info
,
rows
:
[
.
settings
,
.
restorePurchases
])
}
}
}
let
settingsSectionItem
=
SectionItem
(
type
:
.
settings
,
let
settingsSectionItem
=
SectionItem
(
type
:
.
settings
,
...
...
1Weather/UI/View controllers/Menu/Header/MenuHeaderView.swift
View file @
cfd25127
...
@@ -23,6 +23,7 @@ class MenuHeaderView: UIView {
...
@@ -23,6 +23,7 @@ class MenuHeaderView: UIView {
prepareView
()
prepareView
()
preparePremium
()
preparePremium
()
updateUI
()
updateUI
()
reload
()
}
}
required
init
?(
coder
:
NSCoder
)
{
required
init
?(
coder
:
NSCoder
)
{
...
@@ -34,6 +35,37 @@ class MenuHeaderView: UIView {
...
@@ -34,6 +35,37 @@ class MenuHeaderView: UIView {
updateUI
()
updateUI
()
}
}
public
func
reload
()
{
if
StoreManager
.
shared
.
removeAdsPurchased
{
premiumHeadingLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
16
)
premiumHeadingLabel
.
text
=
"menu.upgradeTo"
.
localized
()
let
descParagpraphStyle
=
NSMutableParagraphStyle
()
descParagpraphStyle
.
minimumLineHeight
=
20
let
descriptionAttrString
=
NSAttributedString
(
string
:
"menu.premiumMembership"
.
localized
(),
attributes
:
[
.
foregroundColor
:
UIColor
.
white
,
.
paragraphStyle
:
descParagpraphStyle
,
.
font
:
AppFont
.
SFPro
.
bold
(
size
:
24
)])
premiumDescriptionLabel
.
attributedText
=
descriptionAttrString
buyButton
.
setTitle
(
"menu.upgradeNow"
.
localized
(),
for
:
.
normal
)
}
else
{
premiumHeadingLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
23
)
premiumHeadingLabel
.
text
=
"menu.goPremium"
.
localized
()
let
descParagpraphStyle
=
NSMutableParagraphStyle
()
descParagpraphStyle
.
minimumLineHeight
=
20
let
descriptionAttrString
=
NSAttributedString
(
string
:
"menu.premium.desc"
.
localized
(),
attributes
:
[
.
foregroundColor
:
UIColor
.
white
,
.
paragraphStyle
:
descParagpraphStyle
,
.
font
:
AppFont
.
SFPro
.
regular
(
size
:
14
)])
premiumDescriptionLabel
.
attributedText
=
descriptionAttrString
buyButton
.
setTitle
(
"menu.buyNow"
.
localized
(),
for
:
.
normal
)
}
}
//Prvaite
//Prvaite
private
func
updateUI
()
{
private
func
updateUI
()
{
backgroundColor
=
ThemeManager
.
currentTheme
.
baseBackgroundColor
backgroundColor
=
ThemeManager
.
currentTheme
.
baseBackgroundColor
...
@@ -80,35 +112,6 @@ private extension MenuHeaderView {
...
@@ -80,35 +112,6 @@ private extension MenuHeaderView {
buyButton
.
addTarget
(
self
,
action
:
#selector(
handleBuyButton
)
,
for
:
.
touchUpInside
)
buyButton
.
addTarget
(
self
,
action
:
#selector(
handleBuyButton
)
,
for
:
.
touchUpInside
)
premiumContainer
.
addSubview
(
buyButton
)
premiumContainer
.
addSubview
(
buyButton
)
if
StoreManager
.
shared
.
removeAdsPurchased
{
premiumHeadingLabel
.
font
=
AppFont
.
SFPro
.
regular
(
size
:
16
)
premiumHeadingLabel
.
text
=
"menu.upgradeTo"
.
localized
()
let
descParagpraphStyle
=
NSMutableParagraphStyle
()
descParagpraphStyle
.
minimumLineHeight
=
20
let
descriptionAttrString
=
NSAttributedString
(
string
:
"menu.premiumMembership"
.
localized
(),
attributes
:
[
.
foregroundColor
:
UIColor
.
white
,
.
paragraphStyle
:
descParagpraphStyle
,
.
font
:
AppFont
.
SFPro
.
bold
(
size
:
24
)])
premiumDescriptionLabel
.
attributedText
=
descriptionAttrString
buyButton
.
setTitle
(
"menu.upgradeNow"
.
localized
(),
for
:
.
normal
)
}
else
{
premiumHeadingLabel
.
font
=
AppFont
.
SFPro
.
bold
(
size
:
23
)
premiumHeadingLabel
.
text
=
"menu.goPremium"
.
localized
()
let
descParagpraphStyle
=
NSMutableParagraphStyle
()
descParagpraphStyle
.
minimumLineHeight
=
20
let
descriptionAttrString
=
NSAttributedString
(
string
:
"menu.premium.desc"
.
localized
(),
attributes
:
[
.
foregroundColor
:
UIColor
.
white
,
.
paragraphStyle
:
descParagpraphStyle
,
.
font
:
AppFont
.
SFPro
.
regular
(
size
:
14
)])
premiumDescriptionLabel
.
attributedText
=
descriptionAttrString
buyButton
.
setTitle
(
"menu.buyNow"
.
localized
(),
for
:
.
normal
)
}
//Constraints
//Constraints
premiumContainer
.
snp
.
makeConstraints
{
(
make
)
in
premiumContainer
.
snp
.
makeConstraints
{
(
make
)
in
make
.
top
.
equalTo
(
30
)
make
.
top
.
equalTo
(
30
)
...
...
1Weather/UI/View controllers/Menu/MenuViewController.swift
View file @
cfd25127
...
@@ -63,6 +63,7 @@ class MenuViewController: UIViewController {
...
@@ -63,6 +63,7 @@ class MenuViewController: UIViewController {
super
.
viewWillAppear
(
animated
)
super
.
viewWillAppear
(
animated
)
menuCellFactory
.
reload
()
menuCellFactory
.
reload
()
menuHeaderView
.
reload
()
tableView
.
reloadData
()
tableView
.
reloadData
()
}
}
...
@@ -157,6 +158,8 @@ extension MenuViewController: UITableViewDelegate {
...
@@ -157,6 +158,8 @@ extension MenuViewController: UITableViewDelegate {
viewModel
.
showDeviceId
()
viewModel
.
showDeviceId
()
case
.
subscriptionOverview
:
case
.
subscriptionOverview
:
coordinator
.
openSubscriptionOverview
()
coordinator
.
openSubscriptionOverview
()
case
.
restorePurchases
:
viewModel
.
restorePurchases
()
default
:
default
:
break
break
}
}
...
@@ -168,6 +171,7 @@ extension MenuViewController: StoreManagerObserver {
...
@@ -168,6 +171,7 @@ extension MenuViewController: StoreManagerObserver {
func
storeManagerUpdatedStatus
(
_
storeManager
:
StoreManager
)
{
func
storeManagerUpdatedStatus
(
_
storeManager
:
StoreManager
)
{
onMain
{
onMain
{
self
.
menuCellFactory
.
reload
()
self
.
menuCellFactory
.
reload
()
self
.
menuHeaderView
.
reload
()
self
.
tableView
.
reloadData
()
self
.
tableView
.
reloadData
()
}
}
}
}
...
...
1Weather/UI/View controllers/Subscriptions/SubscriptionOverviewViewController.swift
View file @
cfd25127
...
@@ -33,7 +33,7 @@ class SubscriptionOverviewViewController: UIViewController {
...
@@ -33,7 +33,7 @@ class SubscriptionOverviewViewController: UIViewController {
prepareScrollView
()
prepareScrollView
()
//Verify new subscription
//Verify new subscription
StoreManager
.
shared
.
verify
Subscription
s
()
StoreManager
.
shared
.
verify
Purchase
s
()
}
}
}
}
...
...
1Weather/ViewModels/MenuViewModel.swift
View file @
cfd25127
...
@@ -69,6 +69,10 @@ class MenuViewModel: NSObject, ViewModelProtocol {
...
@@ -69,6 +69,10 @@ class MenuViewModel: NSObject, ViewModelProtocol {
}
}
}
}
public
func
restorePurchases
()
{
storeManager
.
restoreInApp
()
}
public
func
viewAboutUs
()
{
public
func
viewAboutUs
()
{
self
.
delegate
?
.
presentWebView
(
url
:
ONE_WEATHER_ABOUT_US_URL
)
self
.
delegate
?
.
presentWebView
(
url
:
ONE_WEATHER_ABOUT_US_URL
)
analytics
(
log
:
.
ANALYTICS_VIEW_ABOUT
)
analytics
(
log
:
.
ANALYTICS_VIEW_ABOUT
)
...
...
1Weather/ViewModels/SubscriptionViewModel.swift
View file @
cfd25127
...
@@ -22,8 +22,7 @@ class SubscriptionViewModel: ViewModelProtocol {
...
@@ -22,8 +22,7 @@ class SubscriptionViewModel: ViewModelProtocol {
}
}
public
var
isProUser
:
Bool
{
public
var
isProUser
:
Bool
{
return
true
storeManager
.
removeAdsPurchased
// storeManager.removeAdsPurchased
}
}
public
func
purchase
(
subscription
:
SKProduct
)
{
public
func
purchase
(
subscription
:
SKProduct
)
{
...
...
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