Skip to content

Commit 88559ed

Browse files
committed
- iOS 14 support with improve consent gathering
- Use pull to refresh and auto load instead of the reload button
1 parent 96e5494 commit 88559ed

File tree

10 files changed

+239
-125
lines changed

10 files changed

+239
-125
lines changed

Podfile.lock

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,38 @@
11
PODS:
2-
- Google-Mobile-Ads-SDK (7.60.0):
2+
- Google-Mobile-Ads-SDK (7.66.0):
33
- GoogleAppMeasurement (~> 6.0)
4-
- GoogleAppMeasurement (6.5.1):
5-
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
6-
- GoogleUtilities/MethodSwizzler (~> 6.0)
7-
- GoogleUtilities/Network (~> 6.0)
8-
- "GoogleUtilities/NSData+zlib (~> 6.0)"
9-
- nanopb (~> 1.30905.0)
10-
- GoogleUtilities/AppDelegateSwizzler (6.6.0):
4+
- GoogleUserMessagingPlatform (~> 1.1)
5+
- GoogleAppMeasurement (6.8.3):
6+
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
7+
- GoogleUtilities/MethodSwizzler (~> 6.7)
8+
- GoogleUtilities/Network (~> 6.7)
9+
- "GoogleUtilities/NSData+zlib (~> 6.7)"
10+
- nanopb (~> 1.30906.0)
11+
- GoogleUserMessagingPlatform (1.2.0)
12+
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
1113
- GoogleUtilities/Environment
1214
- GoogleUtilities/Logger
1315
- GoogleUtilities/Network
14-
- GoogleUtilities/Environment (6.6.0):
16+
- GoogleUtilities/Environment (6.7.2):
1517
- PromisesObjC (~> 1.2)
16-
- GoogleUtilities/Logger (6.6.0):
18+
- GoogleUtilities/Logger (6.7.2):
1719
- GoogleUtilities/Environment
18-
- GoogleUtilities/MethodSwizzler (6.6.0):
20+
- GoogleUtilities/MethodSwizzler (6.7.2):
1921
- GoogleUtilities/Logger
20-
- GoogleUtilities/Network (6.6.0):
22+
- GoogleUtilities/Network (6.7.2):
2123
- GoogleUtilities/Logger
2224
- "GoogleUtilities/NSData+zlib"
2325
- GoogleUtilities/Reachability
24-
- "GoogleUtilities/NSData+zlib (6.6.0)"
25-
- GoogleUtilities/Reachability (6.6.0):
26+
- "GoogleUtilities/NSData+zlib (6.7.2)"
27+
- GoogleUtilities/Reachability (6.7.2):
2628
- GoogleUtilities/Logger
27-
- nanopb (1.30905.0):
28-
- nanopb/decode (= 1.30905.0)
29-
- nanopb/encode (= 1.30905.0)
30-
- nanopb/decode (1.30905.0)
31-
- nanopb/encode (1.30905.0)
29+
- nanopb (1.30906.0):
30+
- nanopb/decode (= 1.30906.0)
31+
- nanopb/encode (= 1.30906.0)
32+
- nanopb/decode (1.30906.0)
33+
- nanopb/encode (1.30906.0)
3234
- PersonalizedAdConsent (1.0.5)
33-
- PromisesObjC (1.2.8)
35+
- PromisesObjC (1.2.10)
3436

3537
DEPENDENCIES:
3638
- Google-Mobile-Ads-SDK
@@ -40,18 +42,20 @@ SPEC REPOS:
4042
trunk:
4143
- Google-Mobile-Ads-SDK
4244
- GoogleAppMeasurement
45+
- GoogleUserMessagingPlatform
4346
- GoogleUtilities
4447
- nanopb
4548
- PersonalizedAdConsent
4649
- PromisesObjC
4750

4851
SPEC CHECKSUMS:
49-
Google-Mobile-Ads-SDK: d70efb31e7ea19fe99d466dc5d4788966b6914f8
50-
GoogleAppMeasurement: 137afe68bfa406c3f4221b9395253d9e5d4654cf
51-
GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1
52-
nanopb: c43f40fadfe79e8b8db116583945847910cbabc9
52+
Google-Mobile-Ads-SDK: 7d7074359c040f5add4e0963bf860e14690060d0
53+
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
54+
GoogleUserMessagingPlatform: c85530d930ba509583aa5a6d50a10aca22cf8502
55+
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
56+
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
5357
PersonalizedAdConsent: dbecabb3467df967c16d9cebc2ef4a8890e4bbd8
54-
PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6
58+
PromisesObjC: b14b1c6b68e306650688599de8a45e49fae81151
5559

5660
PODFILE CHECKSUM: 0a3ad6eec838428d85e01e854381b78b9d11267d
5761

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pod install
1919

2020
in a terminal in the project directory to download linked frameworks and use `Workout.xcworkspace` to open the project.
2121

22-
The frameworks `MBLibrary` and `MBHealth` referenced by this project are available [here](https://github.com/piscoTech/MBLibrary), version currently in use is [1.8](https://github.com/piscoTech/MBLibrary/releases/tag/v1.8(20)).
22+
The frameworks `MBLibrary` and `MBHealth` referenced by this project are available [here](https://github.com/piscoTech/MBLibrary), version currently in use is [1.9](https://github.com/piscoTech/MBLibrary/releases/tag/v1.9(21)).
2323

2424
## Customization
2525
General behaviour of the app can be configured at compile time as specified in the [wiki](https://github.com/piscoTech/Workout/wiki#compile-time-setup).

Workout Core/Model/AdsManager.swift

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Foundation
1010
import MBLibrary
1111
import GoogleMobileAds
1212
import PersonalizedAdConsent
13+
import AppTrackingTransparency
1314

1415
public protocol RemoveAdsDelegate: AnyObject {
1516

@@ -43,6 +44,9 @@ public class AdsManager: NSObject, GADBannerViewDelegate {
4344
private static let defaultAdRetryDelay: TimeInterval = 5.0
4445
private static let maxAdRetryDelay: TimeInterval = 5 * 60.0
4546
private var adRetryDelay: TimeInterval = 5.0
47+
/// Whether the user allowed tracking and use of the IDFA.
48+
private var limitTracking = false
49+
/// Whether the user as opted in for personalized ads.
4650
private var allowsPersonalizedAds = true
4751

4852
private let iapManager: InAppPurchaseManager
@@ -69,6 +73,7 @@ public class AdsManager: NSObject, GADBannerViewDelegate {
6973
}
7074

7175
public private(set) var adView: GADBannerView?
76+
private var adEngineStrted = false
7277

7378
private override init() {
7479
fatalError("Use the public initializer")
@@ -90,29 +95,41 @@ public class AdsManager: NSObject, GADBannerViewDelegate {
9095
guard areAdsEnabled else {
9196
return
9297
}
93-
94-
PACConsentInformation.sharedInstance.requestConsentInfoUpdate(forPublisherIdentifiers: [Self.adsPublisherID]) { err in
95-
if err != nil {
96-
DispatchQueue.main.asyncAfter(delay: self.adRetryDelay, closure: self.initialize)
97-
self.adRetryDelay = min(Self.maxAdRetryDelay, self.adRetryDelay * 2)
98-
} else {
99-
self.adRetryDelay = Self.defaultAdRetryDelay
100-
if PACConsentInformation.sharedInstance.isRequestLocationInEEAOrUnknown {
101-
let consent = PACConsentInformation.sharedInstance.consentStatus
102-
if consent == .unknown {
103-
DispatchQueue.main.async {
104-
self.collectAdsConsent(manual: false)
98+
99+
let euConsent = {
100+
PACConsentInformation.sharedInstance.requestConsentInfoUpdate(forPublisherIdentifiers: [Self.adsPublisherID]) { err in
101+
if err != nil {
102+
DispatchQueue.main.asyncAfter(delay: self.adRetryDelay, closure: self.initialize)
103+
self.adRetryDelay = min(Self.maxAdRetryDelay, self.adRetryDelay * 2)
104+
} else {
105+
self.adRetryDelay = Self.defaultAdRetryDelay
106+
if PACConsentInformation.sharedInstance.isRequestLocationInEEAOrUnknown {
107+
let consent = PACConsentInformation.sharedInstance.consentStatus
108+
if consent == .unknown {
109+
DispatchQueue.main.async {
110+
self.collectAdsConsent(manual: false)
111+
}
112+
} else {
113+
self.allowsPersonalizedAds = consent == .personalized
114+
self.loadAds()
105115
}
106116
} else {
107-
self.allowsPersonalizedAds = consent == .personalized
117+
self.allowsPersonalizedAds = true
108118
self.loadAds()
109119
}
110-
} else {
111-
self.allowsPersonalizedAds = true
112-
self.loadAds()
113120
}
114121
}
115122
}
123+
124+
if #available(iOS 14, *) {
125+
ATTrackingManager.requestTrackingAuthorization { auth in
126+
self.limitTracking = auth != .authorized
127+
128+
DispatchQueue.main.async(execute: euConsent)
129+
}
130+
} else {
131+
euConsent()
132+
}
116133
}
117134

118135
// MARK: - Customization
@@ -207,7 +224,7 @@ public class AdsManager: NSObject, GADBannerViewDelegate {
207224

208225
private func getAdRequest() -> GADRequest {
209226
let req = GADRequest()
210-
if !allowsPersonalizedAds {
227+
if limitTracking || !allowsPersonalizedAds {
211228
let extras = GADExtras()
212229
extras.additionalParameters = ["npa": "1"]
213230
req.register(extras)
@@ -222,7 +239,7 @@ public class AdsManager: NSObject, GADBannerViewDelegate {
222239
adView.rootViewController = delegate?.defaultPresenter
223240
adView.delegate = self
224241
adView.adUnitID = Self.adsUnitID
225-
242+
226243
self.adView = adView
227244
}
228245
adView?.load(getAdRequest())

Workout.xcodeproj/project.pbxproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@
632632
isa = PBXProject;
633633
attributes = {
634634
LastSwiftUpdateCheck = 1110;
635-
LastUpgradeCheck = 1100;
635+
LastUpgradeCheck = 1200;
636636
ORGANIZATIONNAME = "Marco Boschi";
637637
TargetAttributes = {
638638
7A650AFC22C1300100059687 = {
@@ -984,6 +984,7 @@
984984
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
985985
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
986986
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
987+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
987988
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
988989
CLANG_WARN_STRICT_PROTOTYPES = YES;
989990
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -1048,6 +1049,7 @@
10481049
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
10491050
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
10501051
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
1052+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
10511053
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
10521054
CLANG_WARN_STRICT_PROTOTYPES = YES;
10531055
CLANG_WARN_SUSPICIOUS_MOVE = YES;

Workout.xcodeproj/xcshareddata/xcschemes/Workout Core.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1100"
3+
LastUpgradeVersion = "1200"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

Workout.xcodeproj/xcshareddata/xcschemes/Workout.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1100"
3+
LastUpgradeVersion = "1200"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

Workout.xcodeproj/xcshareddata/xcschemes/WorkoutHelper.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "1110"
3+
LastUpgradeVersion = "1200"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

Workout/Controller/ListTVC.swift

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class ListTableViewController: UITableViewController, WorkoutListDelegate, Worko
2020
private let list = WorkoutList(healthData: healthData, preferences: preferences)
2121
private var exporter: WorkoutBulkExporter?
2222

23-
private var standardRightBtns: [UIBarButtonItem]!
23+
private var standardRightBtn: UIBarButtonItem!
2424
private var standardLeftBtn: UIBarButtonItem!
2525
@IBOutlet private weak var enterExportModeBtn: UIBarButtonItem!
2626

@@ -37,6 +37,7 @@ class ListTableViewController: UITableViewController, WorkoutListDelegate, Worko
3737
@IBOutlet private weak var filterLbl: UILabel!
3838

3939
private var loaded = false
40+
private var refresher = UIRefreshControl()
4041

4142
override func viewDidLoad() {
4243
super.viewDidLoad()
@@ -48,7 +49,7 @@ class ListTableViewController: UITableViewController, WorkoutListDelegate, Worko
4849
navigationItem.titleView = titleView
4950
navBar?.enhancedDelegate = self
5051

51-
standardRightBtns = navigationItem.rightBarButtonItems
52+
standardRightBtn = navigationItem.rightBarButtonItem
5253
standardLeftBtn = navigationItem.leftBarButtonItem
5354
if #available(iOS 13, *) {
5455
// This can be done in storyboard
@@ -59,6 +60,10 @@ class ListTableViewController: UITableViewController, WorkoutListDelegate, Worko
5960
exportCommitBtn = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(doExport(_:)))
6061
exportRightBtns = [exportCommitBtn, exportToggleBtn]
6162
exportLeftBtn = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelExport(_:)))
63+
64+
// Refresh Control
65+
tableView.refreshControl = self.refresher
66+
refresher.addTarget(self, action: #selector(refresh(_:)), for: .valueChanged)
6267

6368
// Ads
6469
navigationController?.isToolbarHidden = true
@@ -71,7 +76,7 @@ class ListTableViewController: UITableViewController, WorkoutListDelegate, Worko
7176
preferences.add(delegate: self)
7277
list.delegate = self
7378
updateFilterLabel()
74-
refresh()
79+
refresh(self)
7580

7681
DispatchQueue.main.async {
7782
self.checkRequestReview()
@@ -91,7 +96,7 @@ class ListTableViewController: UITableViewController, WorkoutListDelegate, Worko
9196
loaded = true
9297
healthData.authorizeHealthKitAccess {
9398
DispatchQueue.main.async {
94-
self.refresh()
99+
self.refresh(self)
95100
}
96101
}
97102
}
@@ -121,8 +126,9 @@ class ListTableViewController: UITableViewController, WorkoutListDelegate, Worko
121126

122127
private weak var loadMoreCell: LoadMoreCell?
123128

124-
@IBAction func refresh() {
129+
@objc private func refresh(_ sender: Any) {
125130
list.reload()
131+
refresher.endRefreshing()
126132
}
127133

128134
func preferredSystemOfUnitsChanged() {
@@ -219,6 +225,13 @@ class ListTableViewController: UITableViewController, WorkoutListDelegate, Worko
219225
tableView.deselectRow(at: indexPath, animated: true)
220226
}
221227

228+
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
229+
// A second section is shown only iff additional workout can be loaded (or are being loaded)
230+
if tableView.numberOfSections == 2, !list.isLoading, indexPath.section == 0 && indexPath.row == tableView.numberOfRows(inSection: 0) - 1 {
231+
list.loadMore()
232+
}
233+
}
234+
222235
// MARK: - List Displaying
223236

224237
private let allFiltersStr = NSLocalizedString("WRKT_FILTER_ALL", comment: "All")
@@ -312,7 +325,7 @@ class ListTableViewController: UITableViewController, WorkoutListDelegate, Worko
312325
listChanged()
313326

314327
navigationItem.leftBarButtonItem = standardLeftBtn
315-
navigationItem.rightBarButtonItems = standardRightBtns
328+
navigationItem.rightBarButtonItem = standardRightBtn
316329
}
317330

318331
private func updateExportToggleAll() {

Workout/Info.plist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
44
<dict>
5+
<key>GADDelayAppMeasurementInit</key>
6+
<true/>
7+
<key>NSUserTrackingUsageDescription</key>
8+
<string>This identifier will be used to deliver personalized ads to you. You can purchase the ads free version from settings at any time.</string>
59
<key>CFBundleDevelopmentRegion</key>
610
<string>$(DEVELOPMENT_LANGUAGE)</string>
711
<key>CFBundleExecutable</key>

0 commit comments

Comments
 (0)