Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Feature/4997 add datadonation to settings #1977

Merged
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
31da5f8
removed dummy test viewcontroller from TabBar
KaiTeuber Feb 11, 2021
cd12527
added missing strings to settingsa
KaiTeuber Feb 11, 2021
124e535
added another missing string for settings
KaiTeuber Feb 11, 2021
1abe75e
Merge branch 'feature/xxx-DataDonationSettingsText' into feature/4997…
KaiTeuber Feb 11, 2021
8233a75
added new section to app settings
KaiTeuber Feb 11, 2021
3f728f1
added show datadonation screen to settings
KaiTeuber Feb 11, 2021
d9e4f38
added a protocol for settings to use a different dataDonationViewModel
KaiTeuber Feb 11, 2021
4616bdb
added @published property to DataDonationViewModelProtocol
KaiTeuber Feb 11, 2021
a724014
Merge branch 'feature/4996-TSK-dataDonation' into feature/4997-AddDat…
KaiTeuber Feb 11, 2021
322ece6
moved files to cleanup, updated settings Icon
KaiTeuber Feb 11, 2021
c5f82b5
use SettingsDataDonationViewModel
KaiTeuber Feb 11, 2021
c51066e
added correct state of datadonation to the settings
KaiTeuber Feb 11, 2021
68d97ee
Merge branch 'feature/4996-TSK-dataDonation' into feature/4997-AddDat…
KaiTeuber Feb 12, 2021
88d2399
added a toggle cell
KaiTeuber Feb 12, 2021
fb153ee
updated logic when save will happen on datadonation settings
KaiTeuber Feb 12, 2021
4b1daf1
Merge branch 'feature/4996-TSK-dataDonation' into feature/4997-AddDat…
KaiTeuber Feb 12, 2021
697b8c2
a bit of refactoring SettingsDataDonationViewModel
KaiTeuber Feb 12, 2021
6c27df0
added closeOnSelection option to automatically close viewController
KaiTeuber Feb 12, 2021
8458b31
updated logic on datadonation toggle
KaiTeuber Feb 12, 2021
85a69f9
changed fallback string if no value was given
KaiTeuber Feb 12, 2021
d426b41
AppSettings data donation legal texts
tcfos Feb 12, 2021
e809c39
Merge branch 'feature/4997-AddDatadonationToSettings' of https://gith…
tcfos Feb 12, 2021
40753ef
fixed syntax error.
tcfos Feb 12, 2021
d455bc9
removed obsolete lines
tcfos Feb 12, 2021
dbaa052
review changes
pascal-brause Feb 12, 2021
14e87e5
Update src/xcode/ENA/ENA/Source/Scenes/Datadonation/District.swift
pascal-brause Feb 12, 2021
d975309
fixed syntax error
tcfos Feb 12, 2021
7fd0e8d
Merge branch 'feature/4997-AddDatadonationToSettings' of https://gith…
tcfos Feb 12, 2021
306df9a
Make sure every analytics data is removed when the user revokes his c…
pascal-brause Feb 12, 2021
ca30c3c
Merge branch 'feature/4997-AddDatadonationToSettings' of https://gith…
pascal-brause Feb 12, 2021
8f67276
addedd simpl unittest for model
KaiTeuber Feb 12, 2021
1c0ab51
unit test for DataDonationDetailsViewModel
tcfos Feb 12, 2021
4e372d9
Merge branch 'feature/4788-4789-4919-EPIC-PPA' into feature/4997-AddD…
pascal-brause Feb 12, 2021
2d0638b
unit test
tcfos Feb 12, 2021
bf54ce7
refactoring unit test
tcfos Feb 12, 2021
f6ea767
refactoring and enhancing unit tests
tcfos Feb 12, 2021
14dfde0
splitup tetst for BaseModel and DefaultModel
KaiTeuber Feb 12, 2021
2bb754e
fix mock store
pascal-brause Feb 12, 2021
1aec488
Merge branch 'feature/4997-AddDatadonationToSettings' of https://gith…
pascal-brause Feb 12, 2021
f41072a
added unittest for SettingsDataDonationViewModel
KaiTeuber Feb 12, 2021
c3799c6
reenabled Unittest
KaiTeuber Feb 12, 2021
6d6a820
code cleanups
KaiTeuber Feb 12, 2021
02382c9
Merge branch 'feature/4788-4789-4919-EPIC-PPA' into feature/4997-AddD…
KaiTeuber Feb 12, 2021
ed17349
fixed legal text formatting
tcfos Feb 12, 2021
5a6b892
typo fixed
tcfos Feb 12, 2021
363dc05
fix build
KaiTeuber Feb 12, 2021
4dc2580
Fixed broken layout constraints; adapted unit test accordingly
tcfos Feb 12, 2021
912252f
refactoring to get rid of the usesless bool
KaiTeuber Feb 12, 2021
09ff0fc
refactoring unit tests
tcfos Feb 12, 2021
d22eca4
Merge branch 'feature/4997-AddDatadonationToSettings' of https://gith…
tcfos Feb 12, 2021
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
100 changes: 82 additions & 18 deletions src/xcode/ENA/ENA.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "Icons_Settings_Datenspende.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,7 @@
"SurveyConsent_Details_Legal_Body1" = "Um die Echtheit Ihrer App zu bestätigen, erzeugt Ihr Smartphone eine eindeutige Kennung, die Informationen über die Version Ihres Smartphones und der App enthält. Das ist erforderlich, um zu verhindern, dass Nutzer mehrfach der Befragung teilnehmen und so die Ergebnisse der Befragung verfälschen. Die Kennung wird hier einmalig an Apple übermittelt. Dabei kann es auch zu einer Datenübermittlung in die USA kommen. Dort besteht kein dem europäischen Recht angemessenes Datenschutzniveau und Ihre europäischen Datenschutzrechte können eventuell nicht durchgesetzt werden. Insbesondere besteht die Möglichkeit, dass US-Sicherheitsbehörden, auch ohne einen konkreten Verdacht, auf die übermittelten Daten bei Apple zugreifen und diese auswerten, beispielsweise indem sie Daten mit anderen Informationen verknüpfen. Dies betrifft nur die an Apple übermittelte Kennung. Die weiteren Angaben über Ihre Teilnahme an der Befragung erhält Apple nicht.";

"SurveyConsent_Details_Legal_Body2" = "Wenn Sie mit der Drittlandsübermittlung nicht einverstanden sind, tippen Sie bitte nicht „Einverstanden“ an. Sie können die App weiterhin nutzen, eine Teilnahme an dieser Befragung ist dann jedoch nicht möglich.";

/* Data Donation App Settings*/

"ppa_settings_privacy_information_body" = "Indem Sie oben „Datenspende“ aktivieren, willigen Sie ein:\n\nDie App übermittelt täglich von ihr erfasste Angaben an das RKI. Die Daten betreffen angezeigte Risiko-Begegnungen und Warnungen, durch Sie abgerufene Testergebnisse, ob Sie andere Nutzer gewarnt haben sowie Angaben über das Betriebssystem Ihres Smartphones. Wenn Sie oben weitere Angaben gemacht haben (Region, Altersgruppe), werden auch diese an das RKI übermittelt.\n\nDas RKI wird diese Daten zu Statistiken zusammenfassen und auswerten, um die Wirksamkeit und Funktionsweise der App zu bewerten und Rückschlüsse auf das Pandemiegeschehen zu ziehen. Die dabei gefundenen Erkenntnisse helfen bei der Verbesserung der Funktionen und Nutzerfreundlichkeit der App sowie bei der Steuerung anderer Maßnahmen der Pandemiebekämpfung.\n\nBevor Ihre Daten ausgewertet werden, muss sichergestellt sein, dass jede an der Datenspende teilnehmende App nur einmal gezählt wird und die Statistiken nicht verfälscht werden. Hierfür muss die Echtheit Ihrer App geprüft werden. Dazu wird durch Ihr Smartphone eine eindeutige Kennung erzeugt und an Apple in die USA übermittelt, damit Apple die Echtheit Ihrer App gegenüber dem RKI bestätigen kann. Die Kennung enthält Informationen über die Version Ihres Smartphones und der App. Weitere Angaben aus der App erhält Apple hierbei nicht.\n\nSie können Ihr Einverständnis jederzeit zurücknehmen, indem Sie oben „Datenspende“ deaktivieren.";
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@

"DataDonation_Acknowledgement_Title" = "Your Consent";

"DataDonation_Acknowledgement_Content" = "By tapping on “Accept”, you consent to the following:\n\nThe app will transmit information it records to the RKI, on a daily basis. The data concerns possible exposures and warnings that have been displayed to you, test results you have retrieved, and whether you have warned other users, and information about your smartphone’s operating system. If you have provided further details above (region, age group), then the RKI will also receive this information.\n\nThe RKI will compile this data into statistics and analyze it to assess the effectiveness and functioning of the app, and draw conclusions regarding the pandemic. The resulting knowledge will help to improve the app’s features and make it more user-friendly, as well as to inform other pandemic response measures.\n\nBefore your data is analyzed, it is necessary to ensure that each app that shares data is only counted once, so as not to distort the statistics. This is why the authenticity of your app needs to be verified. For this purpose, a unique identifier is generated by your smartphone and transmitted to Apple in the U.S., so that Apple can confirm the authenticity of your app to the RKI. The identifier contains information about the version of your smartphone and the app. Apple does not receive any other information from the app during this process.\n\You can withdraw your consent at any time by disabling the data sharing feature in the app's settings.";
"DataDonation_Acknowledgement_Content" = "By tapping on “Accept”, you consent to the following:\n\nThe app will transmit information it records to the RKI, on a daily basis. The data concerns possible exposures and warnings that have been displayed to you, test results you have retrieved, and whether you have warned other users, and information about your smartphone’s operating system. If you have provided further details above (region, age group), then the RKI will also receive this information.\n\nThe RKI will compile this data into statistics and analyze it to assess the effectiveness and functioning of the app, and draw conclusions regarding the pandemic. The resulting knowledge will help to improve the app’s features and make it more user-friendly, as well as to inform other pandemic response measures.\n\nBefore your data is analyzed, it is necessary to ensure that each app that shares data is only counted once, so as not to distort the statistics. This is why the authenticity of your app needs to be verified. For this purpose, a unique identifier is generated by your smartphone and transmitted to Apple in the U.S., so that Apple can confirm the authenticity of your app to the RKI. The identifier contains information about the version of your smartphone and the app. Apple does not receive any other information from the app during this process.\n\nYou can withdraw your consent at any time by disabling the data sharing feature in the app's settings.";

"DataDonation_Acknowledgement_BulletPoint_1" = "Your consent is voluntary. If you do not give your consent, you will still be able to use the app.";

Expand Down Expand Up @@ -108,3 +108,7 @@
"SurveyConsent_Details_Legal_Body1" = "To confirm the authenticity of your app, your smartphone will generate a unique identifier that contains information about the version of your smartphone and the app. This is necessary to prevent users from participating in the survey more than once, as this could distort the results of the survey. Once generated, the identifier will be transmitted once to Apple. This may result in data being transferred to the U.S.. There, the level of data protection is not considered adequate under European law and it may not be possible to enforce your European data protection rights. In particular, there is a possibility that once the transmitted data reaches Apple, it may be accessed and analysed by U.S. security authorities, even if they have no specific grounds for suspicion, for example by linking the data with other information. This only concerns the identifier sent to Apple. Apple will not receive the other information about your participation in the survey.";

"SurveyConsent_Details_Legal_Body2" = "If you do not consent to this transfer of your data to a third country, please do not tap on “Accept”. You will still be able to use the app, but not participate in this survey.";

/* Data Donation App Settings*/

"ppa_settings_privacy_information_body" = "By enabling “Share Data” above, you consent to the following:\n\nThe app will transmit information it records to the RKI, on a daily basis. The data concerns possible exposures and warnings that have been displayed to you, test results you have retrieved, and whether you have warned other users, and information about your smartphone’s operating system. If you have provided further details above (region, age group), then the RKI will also receive this information.\n\nThe RKI will compile this data into statistics and analyze it to assess the effectiveness and functioning of the app, and draw conclusions regarding the pandemic. The resulting knowledge will help to improve the app’s features and make it more user-friendly, as well as to inform other pandemic response measures.\n\nBefore your data is analyzed, it is necessary to ensure that each app that shares data is only counted once, so as not to distort the statistics. This is why the authenticity of your app needs to be verified. For this purpose, a unique identifier is generated by your smartphone and transmitted to Apple in the U.S., so that Apple can confirm the authenticity of your app to the RKI. The identifier contains information about the version of your smartphone and the app. Apple does not receive any other information from the app during this process.\n\nYou can withdraw your consent at any time by disabling “Share Data” above.";
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,7 @@
"SurveyConsent_Details_Legal_Body1" = "Uygulamanızın orijinal olduğunu onaylamak adına akıllı telefonunuz, akıllı telefonunuzun sürümü ve Uygulamaya ilişkin veriler içeren benzersiz bir kimlik kodu oluşturur. Kullanıcıların ankete birden çok kez katılmasını ve böylece anket sonuçlarını tahrif etmesini önlemek için bu kodun oluşturulması gerekmektedir. Bu kimlik kodları, sadece bir kez Apple’a aktarılır. Bu süreçte verilerin ABD’ye aktarılması da söz konusu olabilir. Orada Avrupa hukukuna uygun kişisel verilerin koruma seviyesi bulunmamaktadır ve Avrupa’daki veri koruma haklarınız uygulanmayabilir. Bu bağlamda özellikle ABD güvenlik makamlarının, somut bir şüphe olmasa bile, Apple’a aktarılan bu verilere erişme ve örneğin verileri diğer bilgilerle ilişkilendirerek bunları değerlendirmeye alma olasılığı bulunmaktadır. Bu durum sadece Apple’a aktarılan kimlik kodları için söz konusudur. Apple ankete katılımız ile ilgili daha fazla bilgi almaz.";

"SurveyConsent_Details_Legal_Body2" = "Üçüncü ülkelere aktarımı kabul etmiyorsanız, lütfen “Kabul ediyorum” seçeneğine tıklamayın. Buna rağmen Uygulamayı kullanmaya devam edebilirsiniz, ancak ankete katılamazsınız.";

/* Data Donation App Settings*/

"ppa_settings_privacy_information_body" = "Yukarıdaki “Veri bağışı” seçeneğini etkinleştirerek, şunlara onay vermiş olursunuz:\n\nUygulama, topladığı bilgileri her gün RKI’ye aktarır. Bunlar, görüntülenen riskli karşılaşmalar ve uyarılar, size gönderilen test sonuçları, diğer kullanıcıları uyarıp uyarmadığınız ve akıllı telefonunuzun işletim sistemine ilişkin verilerdir. Ayrıca başka bilgiler de verdiyseniz (bölge, yaş grubu gibi), bunlar da RKI’ye aktarılır.\n\nRKI, Uygulamanın etki gücünü ve işlevselliğini değerlendirmek ve pandemi hakkında yeni çıkarımlar elde etmek için, bu verileri birleştirecek ve istatistikler olarak değerlendirecektir. Bu süreçte edinilen bulgular, Uygulamanın işlevlerini ve kullanım kolaylığını iyileştirmenin yanı sıra pandemiye karşı mücadele için diğer önlemlerin yönlendirilmesine yardımcı olmaktadır.\n\nVerilerinizin değerlendirilmesinden önce, veri bağışına katılan her Uygulamanın yalnızca bir kez sayıma alındığı ve istatistiklerin tahrif edilmediği kontrol edilir. Bu bağlamda Uygulamanızın orijinal olduğunun incelenmesi gerekmektedir. Bunun için, akıllı telefonunuz tarafından benzersiz bir kimlik kodu oluşturulur ve Apple’ın Uygulamanızın orijinal ürün olduğunu RKI’ye doğrulaması için ABD’deki Apple’a aktarılır. Bu kimlik kodu, akıllı telefonunuzun sürümü ve Uygulama hakkında veriler içerir. Apple <, Uygulamadan daha fazla bilgi almaz.\n\nYukarıdaki “Veri bağışı” seçeneğini devre dışı bırakarak, verdiğiniz rıza beyanını geri alabilirsiniz.";
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
////
//
// 🦠 Corona-Warn-App
//

Expand All @@ -9,27 +9,12 @@ class DataDonationViewController: DynamicTableViewController, DeltaOnboardingVie

// MARK: - Init
init(
store: Store,
presentSelectValueList: @escaping (SelectValueViewModel) -> Void,
viewModel: DataDonationViewModelProtocol,
didTapLegal: @escaping () -> Void
) {
self.presentSelectValueList = presentSelectValueList
self.viewModel = viewModel
self.didTapLegal = didTapLegal

guard let url = Bundle.main.url(forResource: "ppdd-ppa-administrative-unit-set-ua-approved", withExtension: "json") else {
preconditionFailure("missing json file")
}
let datadonationModel = DataDonationModel(
store: store,
jsonFileURL: url
)

self.viewModel = DataDonationViewModel(
store: store,
presentSelectValueList: presentSelectValueList,
datadonationModel: datadonationModel
)

super.init(nibName: nil, bundle: nil)
}

Expand All @@ -45,24 +30,11 @@ class DataDonationViewController: DynamicTableViewController, DeltaOnboardingVie

setupTableView()
}

override var navigationItem: UINavigationItem {
navigationFooterItem
}

private lazy var navigationFooterItem: ENANavigationFooterItem = {
let item = ENANavigationFooterItem()

item.primaryButtonTitle = AppStrings.DataDonation.Info.buttonOK
item.isPrimaryButtonEnabled = true

item.secondaryButtonTitle = AppStrings.DataDonation.Info.buttonNOK
item.secondaryButtonHasBackground = true
item.isSecondaryButtonHidden = false
item.isSecondaryButtonEnabled = true

return item
}()

// MARK: - Protocol ENANavigationControllerWithFooterChild

func navigationController(_ navigationController: ENANavigationControllerWithFooter, didTapPrimaryButton button: UIButton) {
Expand All @@ -78,23 +50,35 @@ class DataDonationViewController: DynamicTableViewController, DeltaOnboardingVie
// MARK: - Protocol DismissHandling

func wasAttemptedToBeDismissed() {

Log.debug("attemptedToBeDismissed")
}

// MARK: - Public

// MARK: - Internal

/// Is called when when the one of the ENANavigationControllerWithFooter buttons is tapped.
var finished: (() -> Void)?

// MARK: - Private
private let presentSelectValueList: (SelectValueViewModel) -> Void

private let didTapLegal: () -> Void

private let viewModel: DataDonationViewModel
private let viewModel: DataDonationViewModelProtocol
private var subscriptions: [AnyCancellable] = []

private lazy var navigationFooterItem: ENANavigationFooterItem = {
let item = ENANavigationFooterItem()

item.primaryButtonTitle = AppStrings.DataDonation.Info.buttonOK
item.isPrimaryButtonEnabled = true

item.secondaryButtonTitle = AppStrings.DataDonation.Info.buttonNOK
item.secondaryButtonHasBackground = true
item.isSecondaryButtonHidden = false
item.isSecondaryButtonEnabled = true

return item
}()

private func setupTableView() {
view.backgroundColor = .enaColor(for: .background)
tableView.separatorStyle = .none
Expand All @@ -111,7 +95,7 @@ class DataDonationViewController: DynamicTableViewController, DeltaOnboardingVie

dynamicTableViewModel = viewModel.dynamicTableViewModel

viewModel.$reloadTableView
viewModel.reloadTableViewPublisher
.receive(on: DispatchQueue.OCombine(.main))
.sink { [weak self] _ in
guard let self = self else { return }
Expand All @@ -123,7 +107,7 @@ class DataDonationViewController: DynamicTableViewController, DeltaOnboardingVie

// MARK: - Cell reuse identifiers.

extension DataDonationViewController {
internal extension DataDonationViewController {
enum CustomCellReuseIdentifiers: String, TableViewCellReuseIdentifiers {
case roundedCell
case legalExtended = "DynamicLegalExtendedCell"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//
// 🦠 Corona-Warn-App
//

import Foundation
import UIKit
import OpenCombine

/*** this protocol gets used to provide different view model classes for the dataDonationViewController */

protocol DataDonationViewModelProtocol {

/// use these 3 to definde @published in a prorocol
KaiTeuber marked this conversation as resolved.
Show resolved Hide resolved
var reloadTableView: Bool { get }
KaiTeuber marked this conversation as resolved.
Show resolved Hide resolved
var reloadTableViewPublished: OpenCombine.Published<Bool> { get }
KaiTeuber marked this conversation as resolved.
Show resolved Hide resolved
var reloadTableViewPublisher: OpenCombine.Published<Bool>.Publisher { get }

var friendlyFederalStateName: String { get }
var friendlyRegionName: String { get }
var friendlyAgeName: String { get }
var dynamicTableViewModel: DynamicTableViewModel { get }

func save(consentGiven: Bool)
}

class BaseDataDonationViewModel: DataDonationViewModelProtocol {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to replace this base implementation with a protocol extension.


// MARK: - Init

init(
store: Store,
presentSelectValueList: @escaping (SelectValueViewModel) -> Void,
datadonationModel: DataDonationModel
) {
self.presentSelectValueList = presentSelectValueList
self.reloadTableView = false
self.dataDonationModel = datadonationModel
}

// MARK: - Protocol DataDonationViewModelProtocol

let presentSelectValueList: (SelectValueViewModel) -> Void

@OpenCombine.Published var reloadTableView: Bool

var reloadTableViewPublished: OpenCombine.Published<Bool> { _reloadTableView }
var reloadTableViewPublisher: OpenCombine.Published<Bool>.Publisher { $reloadTableView }
var dataDonationModel: DataDonationModel
var subscriptions: [AnyCancellable] = []

var dynamicTableViewModel: DynamicTableViewModel {
fatalError("base implementation should never get called")
}

/// formatted name output
var friendlyFederalStateName: String {
return dataDonationModel.federalStateName ?? AppStrings.DataDonation.Info.noSelectionState
}

/// formatted region output
var friendlyRegionName: String {
return dataDonationModel.region ?? AppStrings.DataDonation.Info.noSelectionRegion
}

/// formatted age output
var friendlyAgeName: String {
return dataDonationModel.age ?? AppStrings.DataDonation.Info.noSelectionAgeGroup
}

/// will set consent given and save the model afterwards
func save(consentGiven: Bool) {
dataDonationModel.isConsentGiven = consentGiven
Log.debug("DataDonation consent value set to '\(consentGiven)'")
dataDonationModel.save()
}
}

internal extension DynamicCell {

/// A `legalExtendedDataDonation` to display legal text for Data Donation screen
/// - Parameters:
/// - title: The title/header for the legal foo.
/// - description: Optional description text.
/// - bulletPoints: A list of strings to be prefixed with bullet points.
/// - accessibilityIdentifier: Optional, but highly recommended, accessibility identifier.
/// - configure: Optional custom cell configuration
/// - Returns: A `DynamicCell` to display legal texts
static func legalExtendedDataDonation(
title: NSAttributedString,
description: NSAttributedString?,
bulletPoints: [NSAttributedString]? = nil,
accessibilityIdentifier: String? = nil,
configure: CellConfigurator? = nil
) -> Self {
.identifier(DataDonationViewController.CustomCellReuseIdentifiers.legalExtended) { viewController, cell, indexPath in
guard let cell = cell as? DynamicLegalExtendedCell else {
fatalError("could not initialize cell of type `DynamicLegalExtendedCell`")
}
cell.configure(title: title, description: description, bulletPoints: bulletPoints)
configure?(viewController, cell, indexPath)
}
}

}
Loading