Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion DP3TApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,10 @@
DCE1398E26382B5E0093D8F6 /* CreatedEventsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCE1398C26382B5E0093D8F6 /* CreatedEventsManager.swift */; };
DCE32DF52637D05F00168693 /* QRCodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCE32DF42637D05F00168693 /* QRCodeTests.swift */; };
DF3BA22324520EE3009086E7 /* NSDebugDatabaseUploadHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF3BA22224520EE3009086E7 /* NSDebugDatabaseUploadHelper.swift */; };
F20EEE3627DF889D004DADA2 /* NSDeactivatedInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F223579F27D60473001EFCD6 /* NSDeactivatedInfoViewController.swift */; };
F20EEE3727DF88A1004DADA2 /* NSDeactivatedInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F223579D27D5F7BC001EFCD6 /* NSDeactivatedInfoView.swift */; };
F223579E27D5F7BC001EFCD6 /* NSDeactivatedInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F223579D27D5F7BC001EFCD6 /* NSDeactivatedInfoView.swift */; };
F22357A027D60473001EFCD6 /* NSDeactivatedInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F223579F27D60473001EFCD6 /* NSDeactivatedInfoViewController.swift */; };
F806D33C24F91C7800672DFC /* LocalPushProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F806D33B24F91C7800672DFC /* LocalPushProtocol.swift */; };
F806D33D24F91C7800672DFC /* LocalPushProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F806D33B24F91C7800672DFC /* LocalPushProtocol.swift */; };
F806D33F24F91D5B00672DFC /* TracingManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F806D33E24F91D5B00672DFC /* TracingManagerTests.swift */; };
Expand Down Expand Up @@ -1007,6 +1011,8 @@
DCE1398C26382B5E0093D8F6 /* CreatedEventsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatedEventsManager.swift; sourceTree = "<group>"; };
DCE32DF42637D05F00168693 /* QRCodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeTests.swift; sourceTree = "<group>"; };
DF3BA22224520EE3009086E7 /* NSDebugDatabaseUploadHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSDebugDatabaseUploadHelper.swift; sourceTree = "<group>"; };
F223579D27D5F7BC001EFCD6 /* NSDeactivatedInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSDeactivatedInfoView.swift; sourceTree = "<group>"; };
F223579F27D60473001EFCD6 /* NSDeactivatedInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSDeactivatedInfoViewController.swift; sourceTree = "<group>"; };
F806D33B24F91C7800672DFC /* LocalPushProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalPushProtocol.swift; sourceTree = "<group>"; };
F806D33E24F91D5B00672DFC /* TracingManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TracingManagerTests.swift; sourceTree = "<group>"; };
F806D34024F91DB900672DFC /* MockIdentifierProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockIdentifierProvider.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1927,6 +1933,7 @@
DC286A27242CE1D2001D5344 /* Screens */ = {
isa = PBXGroup;
children = (
F223579C27D5F780001EFCD6 /* Deactivated */,
6EB9887727158EFD00DFFA17 /* Vaccination */,
F87E96AE2639966400755AF1 /* Info */,
F8D581242589701C00307C2B /* Unsupported */,
Expand Down Expand Up @@ -2056,6 +2063,15 @@
path = Views;
sourceTree = "<group>";
};
F223579C27D5F780001EFCD6 /* Deactivated */ = {
isa = PBXGroup;
children = (
F223579D27D5F7BC001EFCD6 /* NSDeactivatedInfoView.swift */,
F223579F27D60473001EFCD6 /* NSDeactivatedInfoViewController.swift */,
);
path = Deactivated;
sourceTree = "<group>";
};
F80465142525F58900311802 /* Tutorials */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2761,6 +2777,7 @@
246FD176249B568F00FD36F8 /* Environment+AppStore.swift in Sources */,
242D220B245C4BD8005DAEA8 /* NSCovidCodeInfoViewController.swift in Sources */,
6EF28D9226393878001C1565 /* QRCodePDFGenerator.swift in Sources */,
F20EEE3727DF88A1004DADA2 /* NSDeactivatedInfoView.swift in Sources */,
F87C3713258C2613008DCC81 /* NSRadioButtonGroup.swift in Sources */,
242D220C245C4BD8005DAEA8 /* RandomGenerators.swift in Sources */,
6EF28D052637053C001C1565 /* NSQRScanningView.swift in Sources */,
Expand Down Expand Up @@ -2822,6 +2839,7 @@
242D2223245C4BD8005DAEA8 /* ConfigResponseBody.swift in Sources */,
F86A6A772637F226003CAC1B /* CheckInExposure.swift in Sources */,
F8A6BE2B24CAC2C700DE6B44 /* NSInfoBoxVisibilityManager.swift in Sources */,
F20EEE3627DF889D004DADA2 /* NSDeactivatedInfoViewController.swift in Sources */,
242D2224245C4BD8005DAEA8 /* NSLayoutConstants.swift in Sources */,
2411CA9D245F1085002FB5A9 /* Environment+PublicKeys.swift in Sources */,
F83ECEE72577EEF300DB18CB /* NSTracingReminderViewController.swift in Sources */,
Expand Down Expand Up @@ -3124,6 +3142,7 @@
6E1771562440B5140008D73D /* NSCodeInputControl.swift in Sources */,
F851223D250A2676009BE733 /* NSChartLineView.swift in Sources */,
DC01360925DFE5D6001A33F4 /* StatisticInfoPopupType.swift in Sources */,
F22357A027D60473001EFCD6 /* NSDeactivatedInfoViewController.swift in Sources */,
242D21D1245C3853005DAEA8 /* Logger.swift in Sources */,
6EFB09792445B2CA0097BD3D /* NSInfoBoxView.swift in Sources */,
6EF4D24824582BBB005E2A9C /* NSExternalLinkButton.swift in Sources */,
Expand Down Expand Up @@ -3167,6 +3186,7 @@
6E3F65F72449B61A00980A4E /* NSDebugscreenViewController.swift in Sources */,
F80E40632508F83100876906 /* NSStatisticsHeaderView.swift in Sources */,
DC1617A32638717800B56ADA /* NSCheckInCurrentStateModuleView.swift in Sources */,
F223579E27D5F7BC001EFCD6 /* NSDeactivatedInfoView.swift in Sources */,
DCA3FFBC2451621D0003F5AD /* NSSplashViewController.swift in Sources */,
DC16178F2638717800B56ADA /* NSDiaryEntryContentView.swift in Sources */,
F80E40662508FE1600876906 /* NSStatsticsModuleHeader.swift in Sources */,
Expand Down Expand Up @@ -4711,7 +4731,7 @@
repositoryURL = "https://github.com/DP-3T/dp3t-sdk-ios.git";
requirement = {
kind = exactVersion;
version = 2.4.0;
version = 2.5.1;
};
};
F870A5B52492C6D500C34FFA /* XCRemoteSwiftPackageReference "SQLite" */ = {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions DP3TApp/Logic/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

window?.makeKeyAndVisible()

let deactivated = UserStorage.shared.appDeactivated

guard !deactivated else { return }

if UserStorage.shared.appClipCheckinUrl() != nil {
let checkinOnboardingVC = NSCheckinOnboardingViewController()
checkinOnboardingVC.modalPresentationStyle = .fullScreen
Expand All @@ -140,6 +144,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

// Nothing to do here if device is not supported
guard TracingManager.shared.isSupported else {
startForceUpdateCheck()
return
}

Expand Down
4 changes: 3 additions & 1 deletion DP3TApp/Logic/CheckIn/ProblematicEventsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ class ProblematicEventsManager {
syncNeeded = false
}

if syncNeeded {
let deactivated = (ConfigManager.currentConfig?.deactivate ?? false)

if syncNeeded, !deactivated {
sync { _, _ in }
}
}
Expand Down
20 changes: 20 additions & 0 deletions DP3TApp/Logic/Config/ConfigLoadOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,26 @@ class ConfigLoadOperation: Operation {

ConfigLoadOperation.presentedConfigForVersion = ConfigManager.appVersion
}
} else if let c = config, c.deactivate {
DispatchQueue.main.sync {
let vc = NSNavigationController(rootViewController: NSDeactivatedInfoViewController())

guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
appDelegate.window?.rootViewController? = vc
}

if TracingManager.shared.isActivated {
TracingManager.shared.endTracing()
}

TracingManager.shared.setBackgroundRefreshEnabled(false)
UBPushManager.shared.setActive(false)
CheckInManager.shared.cleanUpOldData(maxDaysToKeep: 0)

if !UserStorage.shared.appDeactivated {
UserStorage.shared.appDeactivated = true
}

} else {
self.cancel()
}
Expand Down
54 changes: 52 additions & 2 deletions DP3TApp/Logic/Config/ConfigManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ConfigManager: NSObject {
static let configBackgroundValidityInterval: TimeInterval = 60 * 60 * 6 // 6h

static var allowTracing: Bool {
return true
return !(ConfigManager.currentConfig?.deactivate ?? false)
}

// MARK: - Version Numbers
Expand Down Expand Up @@ -81,6 +81,9 @@ class ConfigManager: NSObject {
}

static func shouldLoadConfig(backgroundTask: Bool, url: String?, lastConfigUrl: String?, lastConfigLoad: Date?) -> Bool {
if ConfigManager.currentConfig?.deactivate ?? false {
return true
}
// if the config url was changed (by OS version or app version changing) load config in anycase
if url != lastConfigUrl {
return true
Expand Down Expand Up @@ -110,7 +113,8 @@ class ConfigManager: NSObject {
}

public func loadConfig(backgroundTask: Bool, completion: @escaping (ConfigResponseBody?) -> Void) {
let request = Endpoint.config(appversion: ConfigManager.appVersion, osversion: ConfigManager.osVersion, buildnr: ConfigManager.buildNumber).request()
var request = Endpoint.config(appversion: ConfigManager.appVersion, osversion: ConfigManager.osVersion, buildnr: ConfigManager.buildNumber).request()
request.cachePolicy = .reloadIgnoringLocalCacheData

guard Self.shouldLoadConfig(backgroundTask: backgroundTask,
url: request.url?.absoluteString,
Expand Down Expand Up @@ -160,7 +164,11 @@ class ConfigManager: NSObject {
loadConfig(backgroundTask: false) { config in
// self must be strong
if let config = config {
self.presentDeactivationIfNeeded(config: config, window: window)
self.presentAlertIfNeeded(config: config, window: window)
} else {
//still show deactivationScreen if no internet
self.presentDeactivationIfNeeded(config: ConfigManager.currentConfig)
}
}
}
Expand Down Expand Up @@ -210,6 +218,48 @@ class ConfigManager: NSObject {
}
}
}

public func presentDeactivationIfNeeded(config: ConfigResponseBody?, window: UIWindow? = nil) {
guard let config = config else { return }

if config.deactivate {
let vc = NSNavigationController(rootViewController: NSDeactivatedInfoViewController())

if let window = window {
if (window.rootViewController as? NSNavigationController)?.visibleViewController as? NSDeactivatedInfoViewController == nil {
window.rootViewController = vc
}
} else {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
if (appDelegate.window?.rootViewController as? NSNavigationController)?.visibleViewController as? NSDeactivatedInfoViewController == nil {
appDelegate.window?.rootViewController? = vc
}
}

if TracingManager.shared.isActivated {
TracingManager.shared.endTracing()
}

TracingManager.shared.setBackgroundRefreshEnabled(false)
UBPushManager.shared.setActive(false)
CheckInManager.shared.cleanUpOldData(maxDaysToKeep: 0)
if !UserStorage.shared.appDeactivated {
UserStorage.shared.appDeactivated = true
}
} else if !config.deactivate, UserStorage.shared.appDeactivated {
if TracingManager.shared.isAuthorized {
TracingManager.shared.startTracing()
}
TracingManager.shared.setBackgroundRefreshEnabled(true)
UserStorage.shared.appDeactivated = false

if !UserStorage.shared.hasCompletedOnboarding {
let onboardingViewController = NSOnboardingViewController()
onboardingViewController.modalPresentationStyle = .fullScreen
window?.rootViewController?.present(onboardingViewController, animated: false)
}
}
}
}

private extension UIViewController {
Expand Down
5 changes: 4 additions & 1 deletion DP3TApp/Logic/Config/ConfigResponseBody.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ class ConfigResponseBody: UBCodable {
public var showVaccinationInfo = false
public let vaccinationBookingInfo: LocalizedValue<VaccinationBookingInfo>

public let deactivate: Bool
public let deactivationMessage: LocalizedValue<InfoBox>?

class InfoBox: UBCodable {
let title, msg: String
let title, msg: String?
let url: URL?
let urlTitle: String?
let infoId: String?
Expand Down
22 changes: 14 additions & 8 deletions DP3TApp/Logic/Tracing/TracingManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class TracingManager: NSObject {
}

func requestTracingPermission(completion: @escaping (Error?) -> Void) {
guard #available(iOS 12.5, *) else { return }
guard #available(iOS 12.5, *), isSupported else { return }

DP3TTracing.startTracing { result in
switch result {
Expand All @@ -122,7 +122,7 @@ class TracingManager: NSObject {
}

func startTracing(callback: ((TracingEnableResult) -> Void)? = nil) {
guard #available(iOS 12.5, *) else { return }
guard #available(iOS 12.5, *), isSupported else { return }
if UserStorage.shared.hasCompletedOnboarding, ConfigManager.allowTracing {
DP3TTracing.startTracing(completionHandler: { result in
switch result {
Expand Down Expand Up @@ -151,13 +151,13 @@ class TracingManager: NSObject {
}

func endTracing() {
guard #available(iOS 12.5, *) else { return }
guard #available(iOS 12.5, *), isSupported else { return }
DP3TTracing.stopTracing()
localPush.removeSyncWarningTriggers()
}

func resetSDK() {
guard #available(iOS 12.5, *) else { return }
guard #available(iOS 12.5, *), isSupported else { return }
// completely reset SDK
DP3TTracing.reset()

Expand All @@ -168,7 +168,7 @@ class TracingManager: NSObject {
}

func deletePositiveTest() {
guard #available(iOS 12.5, *) else { return }
guard #available(iOS 12.5, *), isSupported else { return }
UIStateManager.shared.blockUpdate {
// reset end isolation question date and onset date
ReportingManager.shared.endIsolationQuestionDate = nil
Expand All @@ -193,7 +193,7 @@ class TracingManager: NSObject {
}

func deleteReports() {
guard #available(iOS 12.5, *) else { return }
guard #available(iOS 12.5, *), isSupported else { return }
// delete all visible messages
DP3TTracing.resetExposureDays()

Expand All @@ -206,7 +206,7 @@ class TracingManager: NSObject {
}

func userHasCompletedOnboarding() {
guard #available(iOS 12.5, *) else { return }
guard #available(iOS 12.5, *), isSupported else { return }
if ConfigManager.allowTracing, UserStorage.shared.tracingSettingEnabled {
DP3TTracing.startTracing { result in
switch result {
Expand Down Expand Up @@ -250,6 +250,12 @@ class TracingManager: NSObject {
completion?()
}
}

func setBackgroundRefreshEnabled(_ enabled: Bool) {
guard #available(iOS 12.5, *), isSupported else { return }

DP3TTracing.setBackgroundTasksEnabled(enabled)
}
}

extension TracingManager: DP3TTracingDelegate {
Expand All @@ -271,7 +277,7 @@ extension TracingManager: DP3TTracingDelegate {
isAuthorized = (state.trackingState != .inactive(error: .authorizationUnknown) &&
state.trackingState != .inactive(error: .permissionError))

let needsPush = !isAuthorized && CrowdNotifier.hasCheckins()
let needsPush = !isAuthorized && CrowdNotifier.hasCheckins() && !UserStorage.shared.appDeactivated
UBPushManager.shared.setActive(needsPush)

// update tracing error states if needed
Expand Down
4 changes: 2 additions & 2 deletions DP3TApp/Logic/Tracing/UIState/UIStateLogic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ class UIStateLogic {
private func setInfoBoxState(_ newState: inout UIStateModel) {
if let infoBox = ConfigManager.currentConfig?.infoBox?.value,
infoBox.infoId == nil || !NSInfoBoxVisibilityManager.shared.dismissedInfoBoxIds.contains(infoBox.infoId!) {
newState.homescreen.infoBox = UIStateModel.Homescreen.InfoBox(title: infoBox.title,
text: infoBox.msg,
newState.homescreen.infoBox = UIStateModel.Homescreen.InfoBox(title: infoBox.title ?? "",
text: infoBox.msg ?? "",
link: infoBox.urlTitle,
url: infoBox.url,
isDismissible: infoBox.isDismissible,
Expand Down
3 changes: 3 additions & 0 deletions DP3TApp/Logic/User/UserStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class UserStorage {
@UBOptionalUserDefault(key: "lastTracingDisabledDate")
var lastTracingDisabledDate: Date?

@UBUserDefault(key: "appDeactivated", defaultValue: false)
var appDeactivated: Bool

// method to get AppClip url in Main App
public func appClipCheckinUrl() -> String? {
let bi = (Bundle.main.bundleIdentifier ?? "")
Expand Down
Loading