COVIDSafe code from version 1.2

This commit is contained in:
covidsafe-support 2020-05-15 00:47:40 -07:00
parent 3640e52eb2
commit cae9823e44
97 changed files with 1001 additions and 465 deletions

View file

@ -1308,7 +1308,7 @@
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = 45792XH5L8; DEVELOPMENT_TEAM = 45792XH5L8;
INFOPLIST_FILE = CovidSafe/Info.plist; INFOPLIST_FILE = CovidSafe/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -1316,7 +1316,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1; MARKETING_VERSION = 1.2;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
PRODUCT_NAME = COVIDSafe; PRODUCT_NAME = COVIDSafe;
@ -1391,7 +1391,7 @@
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = 45792XH5L8; DEVELOPMENT_TEAM = 45792XH5L8;
INFOPLIST_FILE = CovidSafe/Info.plist; INFOPLIST_FILE = CovidSafe/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -1399,7 +1399,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1; MARKETING_VERSION = 1.2;
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
PRODUCT_NAME = COVIDSafe; PRODUCT_NAME = COVIDSafe;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -1419,7 +1419,7 @@
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = 45792XH5L8; DEVELOPMENT_TEAM = 45792XH5L8;
INFOPLIST_FILE = CovidSafe/Info.plist; INFOPLIST_FILE = CovidSafe/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -1427,7 +1427,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1; MARKETING_VERSION = 1.2;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG"; OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
@ -1448,7 +1448,7 @@
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = 45792XH5L8; DEVELOPMENT_TEAM = 45792XH5L8;
INFOPLIST_FILE = CovidSafe/Info.plist; INFOPLIST_FILE = CovidSafe/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -1456,7 +1456,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1; MARKETING_VERSION = 1.2;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG"; OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
@ -1477,7 +1477,7 @@
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = 45792XH5L8; DEVELOPMENT_TEAM = 45792XH5L8;
INFOPLIST_FILE = CovidSafe/Info.plist; INFOPLIST_FILE = CovidSafe/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -1485,7 +1485,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1; MARKETING_VERSION = 1.2;
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG"; OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
PRODUCT_NAME = "COVIDSafe-staging"; PRODUCT_NAME = "COVIDSafe-staging";
@ -1506,7 +1506,7 @@
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = 45792XH5L8; DEVELOPMENT_TEAM = 45792XH5L8;
INFOPLIST_FILE = CovidSafe/Info.plist; INFOPLIST_FILE = CovidSafe/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -1514,7 +1514,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1; MARKETING_VERSION = 1.2;
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG"; OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
PRODUCT_NAME = "COVIDSafe-staging"; PRODUCT_NAME = "COVIDSafe-staging";
@ -1651,7 +1651,7 @@
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = 45792XH5L8; DEVELOPMENT_TEAM = 45792XH5L8;
INFOPLIST_FILE = CovidSafe/Info.plist; INFOPLIST_FILE = CovidSafe/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -1659,7 +1659,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1; MARKETING_VERSION = 1.2;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
PRODUCT_NAME = COVIDSafe; PRODUCT_NAME = COVIDSafe;
@ -1679,7 +1679,7 @@
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 18;
DEVELOPMENT_TEAM = 45792XH5L8; DEVELOPMENT_TEAM = 45792XH5L8;
INFOPLIST_FILE = CovidSafe/Info.plist; INFOPLIST_FILE = CovidSafe/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
@ -1687,7 +1687,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.1; MARKETING_VERSION = 1.2;
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
PRODUCT_NAME = COVIDSafe; PRODUCT_NAME = COVIDSafe;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -170,15 +170,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
DLog("applicationDidEnterBackground") DLog("applicationDidEnterBackground")
Encounter.timestamp(for: .appEnteredBackground) Encounter.timestamp(for: .appEnteredBackground)
let magicNumber = Int.random(in: 0 ... PushNotificationConstants.dailyRemPushNotifContents.count - 1)
self.dismissBlackscreen() self.dismissBlackscreen()
stopAccelerometerUpdates() stopAccelerometerUpdates()
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests()
triggerCalendarLocalPushNotifications(pnContent: PushNotificationConstants.dailyRemPushNotifContents[magicNumber], identifier: "appBackgroundNotifId")
} }
func applicationWillEnterForeground(_ application: UIApplication) { func applicationWillEnterForeground(_ application: UIApplication) {

View file

@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "bell 1.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,122 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 3.333496 10.000000 cm
0.000000 0.000000 0.000000 scn
8.417218 24.916286 m
10.605143 27.104212 13.572605 28.333374 16.666798 28.333374 c
19.760990 28.333374 22.728455 27.104212 24.916378 24.916286 c
27.104303 22.728361 28.333466 19.760899 28.333466 16.666706 c
28.333466 11.078941 29.528578 7.608990 30.629957 5.589794 c
31.182949 4.575975 31.721422 3.910900 32.095470 3.516073 c
32.282928 3.318199 32.430233 3.187002 32.518929 3.113091 c
32.563297 3.076117 32.593056 3.053432 32.605888 3.043879 c
32.607887 3.042391 32.609474 3.041222 32.610645 3.040365 c
33.208122 2.629946 33.472523 1.879206 33.261951 1.183733 c
33.049122 0.480803 32.401245 0.000040 31.666798 0.000040 c
1.666796 0.000040 l
0.932351 0.000040 0.284474 0.480803 0.071643 1.183733 c
-0.138928 1.879204 0.125471 2.629940 0.722946 3.040361 c
0.724115 3.041216 0.725706 3.042387 0.727709 3.043879 c
0.740541 3.053432 0.770297 3.076117 0.814666 3.113091 c
0.903360 3.187002 1.050666 3.318199 1.238125 3.516073 c
1.612173 3.910900 2.150646 4.575975 2.703637 5.589794 c
3.805017 7.608990 5.000130 11.078941 5.000130 16.666706 c
5.000130 19.760899 6.229293 22.728363 8.417218 24.916286 c
h
0.739792 3.051785 m
0.739924 3.051872 0.740055 3.051962 0.740186 3.052048 c
0.740179 3.052044 0.740172 3.052038 0.740165 3.052034 c
0.739792 3.051785 l
h
5.249002 3.333372 m
28.084591 3.333372 l
27.957779 3.541170 27.830471 3.761097 27.703640 3.993620 c
26.305019 6.557756 25.000132 10.587805 25.000132 16.666706 c
25.000132 18.876844 24.122158 20.996460 22.559357 22.559263 c
20.996553 24.122066 18.876934 25.000040 16.666798 25.000040 c
14.456660 25.000040 12.337044 24.122066 10.774240 22.559263 c
9.211437 20.996460 8.333464 18.876844 8.333464 16.666706 c
8.333464 10.587805 7.028576 6.557756 5.629956 3.993620 c
5.503126 3.761097 5.375815 3.541170 5.249002 3.333372 c
h
f*
n
Q
q
1.000000 0.000000 -0.000000 1.000000 15.449707 1.435913 cm
0.000000 0.000000 0.000000 scn
0.830655 5.005682 m
1.626866 5.467550 2.646740 5.196512 3.108608 4.400301 c
3.255117 4.147735 3.465406 3.938091 3.718419 3.792359 c
3.971431 3.646627 4.258289 3.569921 4.550273 3.569921 c
4.842258 3.569921 5.129116 3.646627 5.382128 3.792359 c
5.635140 3.938091 5.845430 4.147735 5.991939 4.400301 c
6.453807 5.196512 7.473681 5.467550 8.269892 5.005682 c
9.066103 4.543814 9.337140 3.523939 8.875272 2.727728 c
8.435747 1.970035 7.804881 1.341100 7.045839 0.903903 c
6.286797 0.466704 5.426219 0.236588 4.550273 0.236588 c
3.674328 0.236588 2.813751 0.466704 2.054708 0.903903 c
1.295666 1.341100 0.664800 1.970035 0.225275 2.727728 c
-0.236593 3.523939 0.034445 4.543814 0.830655 5.005682 c
h
f*
n
Q
endstream
endobj
3 0 obj
2693
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 40.000000 40.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Type /Catalog
/Pages 5 0 R
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000002783 00000 n
0000002806 00000 n
0000002979 00000 n
0000003053 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
3112
%%EOF

View file

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "chev-down.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,70 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
-1.000000 0.000000 -0.000000 -1.000000 12.000001 8.000000 cm
0.313726 0.317647 0.317647 scn
6.000000 8.000000 m
12.000001 0.000001 l
0.000000 0.000001 l
6.000000 8.000000 l
h
f
n
Q
endstream
endobj
3 0 obj
211
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 12.000000 8.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Type /Catalog
/Pages 5 0 R
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000000301 00000 n
0000000323 00000 n
0000000495 00000 n
0000000569 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
628
%%EOF

View file

@ -1,7 +1,7 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "consentDeselected.pdf", "filename" : "Rectangle 29.png",
"idiom" : "universal" "idiom" : "universal"
} }
], ],

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

View file

@ -1,127 +0,0 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
0.000000 20.000000 m
0.000000 22.209139 1.790861 24.000000 4.000000 24.000000 c
20.000000 24.000000 l
22.209139 24.000000 24.000000 22.209139 24.000000 20.000000 c
24.000000 4.000000 l
24.000000 1.790861 22.209139 0.000000 20.000000 0.000000 c
4.000000 0.000000 l
1.790861 0.000000 0.000000 1.790861 0.000000 4.000000 c
0.000000 20.000000 l
h
W*
n
q
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
0.000000 0.000000 0.000000 scn
4.000000 22.000000 m
20.000000 22.000000 l
20.000000 26.000000 l
4.000000 26.000000 l
4.000000 22.000000 l
h
22.000000 20.000000 m
22.000000 4.000000 l
26.000000 4.000000 l
26.000000 20.000000 l
22.000000 20.000000 l
h
20.000000 2.000000 m
4.000000 2.000000 l
4.000000 -2.000000 l
20.000000 -2.000000 l
20.000000 2.000000 l
h
2.000000 4.000000 m
2.000000 20.000000 l
-2.000000 20.000000 l
-2.000000 4.000000 l
2.000000 4.000000 l
h
4.000000 2.000000 m
2.895431 2.000000 2.000000 2.895432 2.000000 4.000000 c
-2.000000 4.000000 l
-2.000000 0.686291 0.686292 -2.000000 4.000000 -2.000000 c
4.000000 2.000000 l
h
22.000000 4.000000 m
22.000000 2.895432 21.104568 2.000000 20.000000 2.000000 c
20.000000 -2.000000 l
23.313709 -2.000000 26.000000 0.686293 26.000000 4.000000 c
22.000000 4.000000 l
h
20.000000 22.000000 m
21.104568 22.000000 22.000000 21.104568 22.000000 20.000000 c
26.000000 20.000000 l
26.000000 23.313709 23.313707 26.000000 20.000000 26.000000 c
20.000000 22.000000 l
h
4.000000 26.000000 m
0.686291 26.000000 -2.000000 23.313707 -2.000000 20.000000 c
2.000000 20.000000 l
2.000000 21.104568 2.895431 22.000000 4.000000 22.000000 c
4.000000 26.000000 l
h
f
n
Q
Q
endstream
endobj
3 0 obj
1649
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 24.000000 24.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Type /Catalog
/Pages 5 0 R
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000001739 00000 n
0000001762 00000 n
0000001935 00000 n
0000002009 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
2068
%%EOF

View file

@ -1,7 +1,7 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "selectedCheckbox.pdf", "filename" : "check.pdf",
"idiom" : "universal" "idiom" : "universal"
} }
], ],

View file

@ -11,7 +11,7 @@ stream
/DeviceRGB cs /DeviceRGB cs
q q
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
0.000000 0.541176 0.137255 scn 0.000000 0.400000 0.105882 scn
0.000000 20.000000 m 0.000000 20.000000 m
0.000000 22.209139 1.790861 24.000000 4.000000 24.000000 c 0.000000 22.209139 1.790861 24.000000 4.000000 24.000000 c
20.000000 24.000000 l 20.000000 24.000000 l
@ -26,34 +26,34 @@ f
n n
Q Q
q q
1.000000 0.000000 -0.000000 1.000000 4.000000 4.804688 cm 1.000000 0.000000 -0.000000 1.000000 4.000000 3.707031 cm
1.000000 1.000000 1.000000 scn 1.000000 1.000000 1.000000 scn
16.707108 12.488206 m 17.060659 13.232308 m
17.097631 12.878730 17.097631 13.511895 16.707108 13.902419 c 17.646446 13.818095 17.646446 14.767842 17.060659 15.353629 c
16.316582 14.292944 15.683417 14.292944 15.292893 13.902419 c 16.474874 15.939415 15.525126 15.939415 14.939340 15.353629 c
16.707108 12.488206 l 17.060659 13.232308 l
h h
5.000000 2.195312 m 5.000000 3.292969 m
4.292893 1.488206 l 3.939340 2.232308 l
4.683417 1.097681 5.316583 1.097681 5.707107 1.488206 c 4.525126 1.646523 5.474874 1.646523 6.060660 2.232308 c
5.000000 2.195312 l 5.000000 3.292969 l
h h
0.707107 7.902419 m 1.060660 9.353629 m
0.316583 8.292944 -0.316583 8.292944 -0.707107 7.902419 c 0.474874 9.939415 -0.474874 9.939415 -1.060660 9.353629 c
-1.097631 7.511895 -1.097631 6.878730 -0.707107 6.488206 c -1.646447 8.767842 -1.646447 7.818095 -1.060660 7.232308 c
0.707107 7.902419 l 1.060660 9.353629 l
h h
15.292893 13.902419 m 14.939340 15.353629 m
4.292893 2.902419 l 3.939340 4.353629 l
5.707107 1.488206 l 6.060660 2.232308 l
16.707108 12.488206 l 17.060659 13.232308 l
15.292893 13.902419 l 14.939340 15.353629 l
h h
5.707107 2.902419 m 6.060660 4.353629 m
0.707107 7.902419 l 1.060660 9.353629 l
-0.707107 6.488206 l -1.060660 7.232308 l
4.292893 1.488206 l 3.939340 2.232308 l
5.707107 2.902419 l 6.060660 4.353629 l
h h
f f
n n

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,6 @@ struct BluetraceConfig {
static let OrgID = "AU_DTA" static let OrgID = "AU_DTA"
static let ProtocolVersion = 1 static let ProtocolVersion = 1
static let CentralScanInterval = 60 // in seconds static let CentralScanInterval = 60.0 // in seconds
static let CentralScanDuration = 10 // in seconds static let CentralScanDuration = 10 // in seconds
} }

View file

@ -49,7 +49,9 @@ class CentralController: NSObject {
guard central == nil else { guard central == nil else {
return return
} }
central = CBCentralManager(delegate: self, queue: self.queue, options: [CBCentralManagerOptionRestoreIdentifierKey: restoreIdentifierKey, CBCentralManagerOptionShowPowerAlertKey: 1]) let options: [String: Any] = [CBCentralManagerOptionRestoreIdentifierKey: restoreIdentifierKey,
CBCentralManagerOptionShowPowerAlertKey: NSNumber(true)]
central = CBCentralManager(delegate: self, queue: self.queue, options: options )
} }
func turnOff() { func turnOff() {
@ -61,63 +63,74 @@ class CentralController: NSObject {
central = nil central = nil
} }
public func getState() -> CBManagerState? { func shouldRecordEncounter(_ encounter: EncounterRecord) -> Bool {
return central?.state guard let scannedDate = encounter.timestamp else {
return true
}
if abs(scannedDate.timeIntervalSinceNow) > BluetraceConfig.CentralScanInterval {
return true
}
return false
} }
public func getDiscoveredPeripheralsCount() -> Int { func shouldReconnectToPeripheral(peripheral: CBPeripheral) -> Bool {
let COUNT_NOT_FOUND = -1 guard let encounteredPeripheral = scannedPeripherals[peripheral.identifier] else {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return true
return COUNT_NOT_FOUND
} }
let managedContext = appDelegate.persistentContainer.viewContext guard let scannedDate = encounteredPeripheral.encounter.timestamp else {
let fetchRequest = NSFetchRequest<Encounter>(entityName: "Encounter") return true
let sortByDate = NSSortDescriptor(key: "timestamp", ascending: false) }
fetchRequest.sortDescriptors = [sortByDate] if abs(scannedDate.timeIntervalSinceNow) > BluetraceConfig.CentralScanInterval {
let fetchedResultsController = NSFetchedResultsController<Encounter>(fetchRequest: fetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: nil, cacheName: nil) return true
}
return false
}
do { public func getState() -> CBManagerState? {
try fetchedResultsController.performFetch() return central?.state
return fetchedResultsController.fetchedObjects?.count ?? COUNT_NOT_FOUND
} catch let error as NSError {
print("Could not perform fetch. \(error), \(error.userInfo)")
return COUNT_NOT_FOUND
}
} }
} }
extension CentralController: CBCentralManagerDelegate { extension CentralController: CBCentralManagerDelegate {
func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) { } func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {
DLog("CC willRestoreState. Central state: \(BluetraceUtils.centralStateToString(central.state))")
if let peripheralsObject = dict[CBCentralManagerRestoredStatePeripheralsKey] {
let peripherals = peripheralsObject as! Array<CBPeripheral>
DLog("CC restoring \(peripherals.count) peripherals from system.")
for peripheral in peripherals {
recoveredPeripherals.append(peripheral)
peripheral.delegate = self
}
}
}
func centralManagerDidUpdateState(_ central: CBCentralManager) { func centralManagerDidUpdateState(_ central: CBCentralManager) {
centralDidUpdateStateCallback?(central.state) centralDidUpdateStateCallback?(central.state)
switch central.state { switch central.state {
case .poweredOn: case .poweredOn:
DispatchQueue.main.async { DLog("CC Starting a scan")
self.timerForScanning = Timer.scheduledTimer(withTimeInterval: TimeInterval(BluetraceConfig.CentralScanInterval), repeats: true) { _ in Encounter.timestamp(for: .scanningStarted)
DLog("CC Starting a scan")
Encounter.timestamp(for: .scanningStarted)
// for all peripherals that are not disconnected, disconnect them // for all peripherals that are not disconnected, disconnect them
self.scannedPeripherals.forEach { (scannedPeri) in self.scannedPeripherals.forEach { (scannedPeri) in
central.cancelPeripheralConnection(scannedPeri.value.peripheral) central.cancelPeripheralConnection(scannedPeri.value.peripheral)
}
// clear all peripherals, such that a new scan window can take place
self.scannedPeripherals = [UUID: (CBPeripheral, EncounterRecord)]()
self.discoveredAndroidPeriManufacturerToUUIDMap = [Data: UUID]()
central.scanForPeripherals(withServices: [BluetraceConfig.BluetoothServiceID])
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(BluetraceConfig.CentralScanDuration)) {
DLog("CC Stopping a scan")
central.stopScan()
Encounter.timestamp(for: .scanningStopped)
}
}
self.timerForScanning?.fire()
} }
// clear all peripherals, such that a new scan window can take place
self.scannedPeripherals = [UUID: (CBPeripheral, EncounterRecord)]()
self.discoveredAndroidPeriManufacturerToUUIDMap = [Data: UUID]()
// handle a state restoration scenario
for recoveredPeripheral in recoveredPeripherals {
var restoredEncounter = EncounterRecord(rssi: 0, txPower: nil)
restoredEncounter.timestamp = nil
scannedPeripherals.updateValue((recoveredPeripheral, restoredEncounter),
forKey: recoveredPeripheral.identifier)
central.connect(recoveredPeripheral)
}
central.scanForPeripherals(withServices: [BluetraceConfig.BluetoothServiceID], options: [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(true)])
default: default:
timerForScanning?.invalidate() DLog("State chnged to \(central.state)")
} }
} }
@ -161,9 +174,12 @@ extension CentralController: CBCentralManagerDelegate {
"advertisments": advertisementData as AnyObject] as AnyObject "advertisments": advertisementData as AnyObject] as AnyObject
DLog("\(debugLogs)") DLog("\(debugLogs)")
var initialEncounter = EncounterRecord(rssi: RSSI.doubleValue, txPower: advertisementData[CBAdvertisementDataTxPowerLevelKey] as? Double)
initialEncounter.timestamp = nil
// iphones will "mask" the peripheral's identifier for android devices, resulting in the same android device being discovered multiple times with different peripheral identifier. Hence Android is using use CBAdvertisementDataServiceDataKey data for identifying an android pheripheral // iphones will "mask" the peripheral's identifier for android devices, resulting in the same android device being discovered multiple times with different peripheral identifier. Hence Android is using use CBAdvertisementDataServiceDataKey data for identifying an android pheripheral
if let manuData = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data { // Also, check that the length is greater than 2 to prevent crash. Otherwise ignore.
if let manuData = advertisementData[CBAdvertisementDataManufacturerDataKey] as? Data, manuData.count > 2 {
let androidIdentifierData = manuData.subdata(in: 2..<manuData.count) let androidIdentifierData = manuData.subdata(in: 2..<manuData.count)
if discoveredAndroidPeriManufacturerToUUIDMap.keys.contains(androidIdentifierData) { if discoveredAndroidPeriManufacturerToUUIDMap.keys.contains(androidIdentifierData) {
DLog("Android Peripheral \(peripheral) has been discovered already in this window, will not attempt to connect to it again") DLog("Android Peripheral \(peripheral) has been discovered already in this window, will not attempt to connect to it again")
@ -171,18 +187,29 @@ extension CentralController: CBCentralManagerDelegate {
} else { } else {
peripheral.delegate = self peripheral.delegate = self
discoveredAndroidPeriManufacturerToUUIDMap.updateValue(peripheral.identifier, forKey: androidIdentifierData) discoveredAndroidPeriManufacturerToUUIDMap.updateValue(peripheral.identifier, forKey: androidIdentifierData)
scannedPeripherals.updateValue((peripheral, EncounterRecord(rssi: RSSI.doubleValue, txPower: advertisementData[CBAdvertisementDataTxPowerLevelKey] as? Double)), forKey: peripheral.identifier) scannedPeripherals.updateValue((peripheral, initialEncounter), forKey: peripheral.identifier)
central.connect(peripheral) central.connect(peripheral)
} }
} else { } else {
// Means not android device, i will check if the peripheral.identifier exist in the scannedPeripherals // Means not android device, i will check if the peripheral.identifier exist in the scannedPeripherals
DLog("CBAdvertisementDataManufacturerDataKey Data not found. Peripheral is likely not android") DLog("CBAdvertisementDataManufacturerDataKey Data not found. Peripheral is likely not android")
if scannedPeripherals[peripheral.identifier] == nil { if let encounteredPeripheral = scannedPeripherals[peripheral.identifier] {
peripheral.delegate = self if shouldReconnectToPeripheral(peripheral: encounteredPeripheral.peripheral) {
scannedPeripherals.updateValue((peripheral, EncounterRecord(rssi: RSSI.doubleValue, txPower: advertisementData[CBAdvertisementDataTxPowerLevelKey] as? Double)), forKey: peripheral.identifier) peripheral.delegate = self
central.connect(peripheral) if peripheral.state != .connected {
central.connect(peripheral)
DLog("found previous peripheral from more than 60 seconds ago")
}
} else {
DLog("iOS Peripheral \(peripheral) has been discovered already in this window, will not attempt to connect to it again")
if let scannedDate = encounteredPeripheral.encounter.timestamp {
DLog("It was found \(scannedDate.timeIntervalSinceNow) seconds ago")
}
}
} else { } else {
DLog("iOS Peripheral \(peripheral) has been discovered already in this window, will not attempt to connect to it again") peripheral.delegate = self
scannedPeripherals.updateValue((peripheral, initialEncounter), forKey: peripheral.identifier)
central.connect(peripheral)
} }
} }
} }
@ -190,12 +217,19 @@ extension CentralController: CBCentralManagerDelegate {
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
let peripheralStateString = BluetraceUtils.peripheralStateToString(peripheral.state) let peripheralStateString = BluetraceUtils.peripheralStateToString(peripheral.state)
DLog("CC didConnect peripheral peripheralCentral state: \(BluetraceUtils.centralStateToString(central.state)), Peripheral state: \(peripheralStateString)") DLog("CC didConnect peripheral peripheralCentral state: \(BluetraceUtils.centralStateToString(central.state)), Peripheral state: \(peripheralStateString)")
guard shouldReconnectToPeripheral(peripheral: peripheral) else {
central.cancelPeripheralConnection(peripheral)
return
}
peripheral.delegate = self peripheral.delegate = self
peripheral.readRSSI()
peripheral.discoverServices([BluetraceConfig.BluetoothServiceID]) peripheral.discoverServices([BluetraceConfig.BluetoothServiceID])
} }
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
DLog("CC didDisconnectPeripheral \(peripheral) , \(error != nil ? "error: \(error.debugDescription)" : "" )") DLog("CC didDisconnectPeripheral \(peripheral) , \(error != nil ? "error: \(error.debugDescription)" : "" )")
let options = [CBConnectPeripheralOptionStartDelayKey: NSNumber(15)]
central.connect(peripheral, options: options)
} }
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
@ -204,6 +238,23 @@ extension CentralController: CBCentralManagerDelegate {
} }
extension CentralController: CBPeripheralDelegate { extension CentralController: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
if let err = error {
DLog("error: \(err)")
}
if error == nil {
if let existingPeripheral = scannedPeripherals[peripheral.identifier] {
var scannedEncounter = existingPeripheral.encounter
scannedEncounter.rssi = RSSI.doubleValue
scannedPeripherals.updateValue((existingPeripheral.peripheral, scannedEncounter), forKey: peripheral.identifier)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didModifyServices invalidatedServices: [CBService]) {
DLog("Peripheral: \(peripheral) didModifyServices: \(invalidatedServices)")
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if let err = error { if let err = error {
DLog("error: \(err)") DLog("error: \(err)")
@ -254,26 +305,31 @@ extension CentralController: CBPeripheralDelegate {
"encounter": scannedPeripherals[peripheral.identifier] as AnyObject] as AnyObject "encounter": scannedPeripherals[peripheral.identifier] as AnyObject] as AnyObject
DLog("\(debugLogs)") DLog("\(debugLogs)")
if error == nil { guard error == nil else {
if let scannedPeri = scannedPeripherals[peripheral.identifier], DLog("Error: \(String(describing: error))")
let characteristicValue = characteristic.value { return
do { }
let peripheralCharData = try JSONDecoder().decode(PeripheralCharacteristicsData.self, from: characteristicValue)
var encounterStruct = scannedPeri.encounter if let scannedPeri = scannedPeripherals[peripheral.identifier],
encounterStruct.msg = peripheralCharData.msg let characteristicValue = characteristic.value,
encounterStruct.update(modelP: peripheralCharData.modelP) shouldRecordEncounter(scannedPeri.encounter)
encounterStruct.org = peripheralCharData.org {
encounterStruct.v = peripheralCharData.v do {
scannedPeripherals.updateValue((scannedPeri.peripheral, encounterStruct), forKey: peripheral.identifier) let peripheralCharData = try JSONDecoder().decode(PeripheralCharacteristicsData.self, from: characteristicValue)
encounterStruct.saveToCoreData() var encounterStruct = scannedPeri.encounter
} catch { encounterStruct.msg = peripheralCharData.msg
DLog("Error: \(error). CharacteristicValue is \(characteristicValue)") encounterStruct.update(modelP: peripheralCharData.modelP)
} encounterStruct.org = peripheralCharData.org
} else { encounterStruct.v = peripheralCharData.v
DLog("Error: scannedPeripherals[peripheral.identifier] is \(String(describing: scannedPeripherals[peripheral.identifier])), characteristic.value is \(String(describing: characteristic.value))") encounterStruct.timestamp = Date()
scannedPeripherals.updateValue((scannedPeri.peripheral, encounterStruct), forKey: peripheral.identifier)
encounterStruct.saveToCoreData()
DLog("Central recorded encounter with \(String(describing: scannedPeri.peripheral.name))")
} catch {
DLog("Error: \(error). CharacteristicValue is \(characteristicValue)")
} }
} else { } else {
DLog("Error: \(error!)") DLog("Error: scannedPeripherals[peripheral.identifier] is \(String(describing: scannedPeripherals[peripheral.identifier])), characteristic.value is \(String(describing: characteristic.value))")
} }
} }

View file

@ -68,7 +68,7 @@ open class CodeInputView: UIView {
/** /**
The color of the digits The color of the digits
*/ */
open var textColor: UIColor = UIColor.covidSafeButtonColor { open var textColor: UIColor = UIColor.covidSafeLighterColor {
didSet { didSet {
setup() setup()

View file

@ -10,8 +10,6 @@ class HomeViewController: UIViewController {
@IBOutlet weak var bluetoothStatusOnView: UIView! @IBOutlet weak var bluetoothStatusOnView: UIView!
@IBOutlet weak var bluetoothPermissionOffView: UIView! @IBOutlet weak var bluetoothPermissionOffView: UIView!
@IBOutlet weak var bluetoothPermissionOnView: UIView! @IBOutlet weak var bluetoothPermissionOnView: UIView!
@IBOutlet weak var pushNotificationOnView: UIView!
@IBOutlet weak var pushNotificationOffView: UIView!
@IBOutlet weak var homeHeaderView: UIView! @IBOutlet weak var homeHeaderView: UIView!
@IBOutlet weak var homeHeaderInfoText: UILabel! @IBOutlet weak var homeHeaderInfoText: UILabel!
@IBOutlet weak var homeHeaderPermissionsOffImage: UIImageView! @IBOutlet weak var homeHeaderPermissionsOffImage: UIImageView!
@ -24,6 +22,9 @@ class HomeViewController: UIViewController {
@IBOutlet weak var uploadView: UIView! @IBOutlet weak var uploadView: UIView!
@IBOutlet weak var helpButton: UIButton! @IBOutlet weak var helpButton: UIButton!
@IBOutlet weak var seeOurFAQ: UIButton! @IBOutlet weak var seeOurFAQ: UIButton!
@IBOutlet weak var pushNotificationStatusTitle: UILabel!
@IBOutlet weak var pushNotificationStatusIcon: UIImageView!
@IBOutlet weak var pushNotificationStatusLabel: UILabel!
var lottieBluetoothView: AnimationView! var lottieBluetoothView: AnimationView!
@ -141,7 +142,7 @@ class HomeViewController: UIViewController {
self.bluetoothStatusOn = BluetraceManager.shared.isBluetoothOn() self.bluetoothStatusOn = BluetraceManager.shared.isBluetoothOn()
self.bluetoothPermissionOn = BluetraceManager.shared.isBluetoothAuthorized() self.bluetoothPermissionOn = BluetraceManager.shared.isBluetoothAuthorized()
self.pushNotificationOn = notificationSettings.authorizationStatus == .authorized self.pushNotificationOn = notificationSettings.authorizationStatus == .authorized
self.allPermissionOn = self.bluetoothStatusOn && self.bluetoothPermissionOn && self.pushNotificationOn self.allPermissionOn = self.bluetoothStatusOn && self.bluetoothPermissionOn
} }
fileprivate func toggleViewVisibility(view: UIView, isVisible: Bool) { fileprivate func toggleViewVisibility(view: UIView, isVisible: Bool) {
@ -179,17 +180,20 @@ class HomeViewController: UIViewController {
} }
self.helpButton.setImage(UIImage(named: "ic-help-selected"), for: .normal) self.helpButton.setImage(UIImage(named: "ic-help-selected"), for: .normal)
self.helpButton.setTitleColor(UIColor.black, for: .normal) self.helpButton.setTitleColor(UIColor.black, for: .normal)
self.homeHeaderInfoText.font = UIFont.systemFont(ofSize: 18, weight: .regular)
self.homeHeaderInfoText.text = "COVIDSafe is active.\nNo further action is required."
if (!self.allPermissionOn) { if (!self.allPermissionOn) {
self.homeHeaderInfoText.text = "COVIDSafe is not active.\nCheck your permissions." self.homeHeaderInfoText.text = "COVIDSafe is not active.\nCheck your permissions."
self.homeHeaderView.backgroundColor = UIColor.covidHomePermissionErrorColor self.homeHeaderView.backgroundColor = UIColor.covidHomePermissionErrorColor
} else if (self.didUploadData) { } else if (self.didUploadData) {
self.helpButton.setImage(UIImage(named: "ic-help"), for: .normal) self.helpButton.setImage(UIImage(named: "ic-help"), for: .normal)
self.helpButton.setTitleColor(UIColor.white, for: .normal) self.helpButton.setTitleColor(UIColor.white, for: .normal)
self.homeHeaderInfoText.text = "COVIDSafe is active.\nNo further action is required." self.homeHeaderInfoText.font = UIFont.systemFont(ofSize: 18, weight: .bold)
self.homeHeaderView.backgroundColor = UIColor.covidSafeButtonColor self.homeHeaderView.backgroundColor = UIColor.covidSafeButtonDarkerColor
updateAnimationViewWithAnimationName(name: "Spinner_home_upload_complete") updateAnimationViewWithAnimationName(name: "Spinner_home_upload_complete")
} else { } else {
self.homeHeaderInfoText.text = "COVIDSafe is active.\nNo further action is required."
self.homeHeaderView.backgroundColor = UIColor.covidHomeActiveColor self.homeHeaderView.backgroundColor = UIColor.covidHomeActiveColor
updateAnimationViewWithAnimationName(name: "Spinner_home") updateAnimationViewWithAnimationName(name: "Spinner_home")
} }
@ -207,8 +211,38 @@ class HomeViewController: UIViewController {
} }
fileprivate func togglePushNotificationsStatusView() { fileprivate func togglePushNotificationsStatusView() {
toggleViewVisibility(view: pushNotificationOnView, isVisible: !self.allPermissionOn && self.pushNotificationOn) let paragraphStyle = NSMutableParagraphStyle()
toggleViewVisibility(view: pushNotificationOffView, isVisible: !self.allPermissionOn && !self.pushNotificationOn) paragraphStyle.lineSpacing = 4
switch self.pushNotificationOn {
case true:
pushNotificationStatusIcon.isHighlighted = false
pushNotificationStatusTitle.text = "Notifications are enabled"
let newAttributedLabel = NSMutableAttributedString(string: "You will receive a notification if COVIDSafe is not active. Change notification settings")
//set some attributes
guard let linkRange = newAttributedLabel.string.range(of: "Change notification settings") else { return }
let nsRange = NSRange(linkRange, in: newAttributedLabel.string)
newAttributedLabel.addAttribute(.foregroundColor,
value: UIColor.covidSafeColor,
range: nsRange)
newAttributedLabel.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, newAttributedLabel.length))
pushNotificationStatusLabel.attributedText = newAttributedLabel
default:
pushNotificationStatusIcon.isHighlighted = true
pushNotificationStatusTitle.text = "Notifications are disabled"
let newAttributedLabel = NSMutableAttributedString(string: "You will not receive a notification if COVIDSafe is not active. Change notification settings")
//set some attributes
guard let linkRange = newAttributedLabel.string.range(of: "Change notification settings") else { return }
let nsRange = NSRange(linkRange, in: newAttributedLabel.string)
newAttributedLabel.addAttribute(.foregroundColor,
value: UIColor.covidSafeColor,
range: nsRange)
newAttributedLabel.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, newAttributedLabel.length))
pushNotificationStatusLabel.attributedText = newAttributedLabel
}
} }
@IBAction func onSettingsTapped(_ sender: UITapGestureRecognizer) { @IBAction func onSettingsTapped(_ sender: UITapGestureRecognizer) {

View file

@ -29,7 +29,6 @@ final class InfoViewController: UIViewController {
advertisementSwitch.addTarget(self, action: #selector(self.advertisementSwitchChanged), for: UIControl.Event.valueChanged) advertisementSwitch.addTarget(self, action: #selector(self.advertisementSwitchChanged), for: UIControl.Event.valueChanged)
scanningSwitch.addTarget(self, action: #selector(self.scanningSwitchChanged), for: UIControl.Event.valueChanged) scanningSwitch.addTarget(self, action: #selector(self.scanningSwitchChanged), for: UIControl.Event.valueChanged)
clearLogsButton.addTarget(self, action:#selector(self.clearLogsButtonClicked), for: .touchUpInside) clearLogsButton.addTarget(self, action:#selector(self.clearLogsButtonClicked), for: .touchUpInside)
obtainBluetoothStateButton.addTarget(self, action:#selector(self.obtainBluetoothStateButtonClicked), for: .touchUpInside)
} }
@ -98,7 +97,4 @@ final class InfoViewController: UIViewController {
print("Could not perform delete. \(error)") print("Could not perform delete. \(error)")
} }
} }
@objc
func obtainBluetoothStateButtonClicked() { }
} }

View file

@ -11,22 +11,56 @@ import KeychainSwift
class InitialScreenViewController: UIViewController { class InitialScreenViewController: UIViewController {
let displayTimeSeconds: Int = 4 let displayTimeSeconds: Int = 4
let giveupTimeSeconds = 8.0
var isKeychainAvailable = false
var isDisplayTimeElapsed = false
let keychain = KeychainSwift()
var giveupTimer: Timer?
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
switch UIApplication.shared.isProtectedDataAvailable {
case true :
isKeychainAvailable = true
break
case false:
NotificationCenter.default.addObserver(self, selector: #selector(setKeychainAvailable(_:)), name: UIApplication.protectedDataDidBecomeAvailableNotification, object: nil)
break
}
} }
override func viewDidAppear(_ animated: Bool) { override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated) super.viewDidAppear(animated)
view.window?.tintColor = .covidSafeColor view.window?.tintColor = .covidSafeColor
let showAppDelay = DispatchTime.now() + .seconds(displayTimeSeconds) let showAppDelay = DispatchTime.now() + .seconds(displayTimeSeconds)
DispatchQueue.main.asyncAfter(deadline: showAppDelay, execute: { DispatchQueue.main.asyncAfter(deadline: showAppDelay, execute: {
self.performCheck() self.isDisplayTimeElapsed = true
if(self.proceedWithChecks()) {
self.performCheck()
}
}) })
// add give up action in case the keychain notification in not received after 8 seconds
giveupTimer = Timer.scheduledTimer(withTimeInterval: giveupTimeSeconds, repeats: false) { timer in
self.performSegue(withIdentifier: "initialPersonalDetailsSegue", sender: self)
}
}
@objc
func setKeychainAvailable(_ notification: Notification) {
NotificationCenter.default.removeObserver(self, name: UIApplication.protectedDataDidBecomeAvailableNotification, object: nil)
isKeychainAvailable = true
if(self.proceedWithChecks()) {
self.performCheck()
}
}
private func proceedWithChecks() -> Bool {
return isDisplayTimeElapsed && isKeychainAvailable
} }
private func performCheck() { private func performCheck() {
let keychain = KeychainSwift() giveupTimer?.invalidate()
let isLoggedIn: Bool = (keychain.get("JWT_TOKEN") != nil) let isLoggedIn: Bool = (keychain.get("JWT_TOKEN") != nil)
if !UserDefaults.standard.bool(forKey: "completedIWantToHelp") { if !UserDefaults.standard.bool(forKey: "completedIWantToHelp") {
// old app signed out here // old app signed out here

View file

@ -39,7 +39,7 @@ class OTPViewController: UIViewController, RegistrationHandler {
static let fiveMinutes = 300 static let fiveMinutes = 300
var countdownSeconds = fiveMinutes var countdownSeconds = fiveMinutes
let verifyEnabledColor = UIColor.covidSafeButtonColor let verifyEnabledColor = UIColor.covidSafeButtonDarkerColor
let verifyDisabledColor = UIColor(red: 219/255.0, green: 221/255.0, blue: 221.0/255.0, alpha: 1.0) let verifyDisabledColor = UIColor(red: 219/255.0, green: 221/255.0, blue: 221.0/255.0, alpha: 1.0)
let linkButtonAttributes: [NSAttributedString.Key: Any] = [ .foregroundColor: UIColor(red: 53.0/255.0, green: 111.0/255.0, blue: 152.0/255.0, alpha: 1.0), .underlineStyle: NSUnderlineStyle.single.rawValue] let linkButtonAttributes: [NSAttributedString.Key: Any] = [ .foregroundColor: UIColor(red: 53.0/255.0, green: 111.0/255.0, blue: 152.0/255.0, alpha: 1.0), .underlineStyle: NSUnderlineStyle.single.rawValue]

View file

@ -8,16 +8,6 @@
import UIKit import UIKit
import SafariServices import SafariServices
enum AusState: String {
case VIC = "Victoria"
case NSW = "New South Wales"
case QLD = "Queensland"
case SA = "South Australia"
case WA = "Western Australia"
case NT = "Northern Territory"
case ACT = "Australian Capital Territory"
}
class PersonalDetailsViewController: UIViewController, UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource { class PersonalDetailsViewController: UIViewController, UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet weak var firstnameTextField: UITextField! @IBOutlet weak var firstnameTextField: UITextField!
@ -26,6 +16,7 @@ class PersonalDetailsViewController: UIViewController, UITextFieldDelegate, UIPi
@IBOutlet weak var continueButton: UIButton! @IBOutlet weak var continueButton: UIButton!
@IBOutlet weak var scrollview: UIScrollView! @IBOutlet weak var scrollview: UIScrollView!
@IBOutlet weak var dimView: UIView! @IBOutlet weak var dimView: UIView!
@IBOutlet weak var backButton: UIButton!
var agePicker: UIPickerView? var agePicker: UIPickerView?
var pickerBarButtonItem: UIBarButtonItem? var pickerBarButtonItem: UIBarButtonItem?
var currentKeyboardFrame: CGRect? var currentKeyboardFrame: CGRect?
@ -197,8 +188,18 @@ class PersonalDetailsViewController: UIViewController, UITextFieldDelegate, UIPi
func textFieldDidBeginEditing(_ textField: UITextField) { func textFieldDidBeginEditing(_ textField: UITextField) {
if (textField == firstnameTextField || textField == postcodeTextField) { if (textField == firstnameTextField || textField == postcodeTextField) {
nextBarButtonItem?.title = "Done" nextBarButtonItem?.title = "Done"
if(UIAccessibility.isVoiceOverRunning) {
firstnameTextField.isAccessibilityElement = true
postcodeTextField.isAccessibilityElement = true
backButton.isAccessibilityElement = true
}
} else if (textField == ageTextField) { } else if (textField == ageTextField) {
dimView.isHidden = false dimView.isHidden = false
if(UIAccessibility.isVoiceOverRunning) {
firstnameTextField.isAccessibilityElement = false
postcodeTextField.isAccessibilityElement = false
backButton.isAccessibilityElement = false
}
nextBarButtonItem?.title = "Next" nextBarButtonItem?.title = "Next"
} }
} }
@ -230,7 +231,7 @@ class PersonalDetailsViewController: UIViewController, UITextFieldDelegate, UIPi
firstnameTextField.text = firstnameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) firstnameTextField.text = firstnameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines)
if (self.ageTextField.text != "" && self.postcodeTextField.text?.count == 4 && self.firstnameTextField.text != "") { if (self.ageTextField.text != "" && self.postcodeTextField.text?.count == 4 && self.firstnameTextField.text != "") {
self.continueButton.isEnabled = true self.continueButton.isEnabled = true
self.continueButton.backgroundColor = UIColor.covidSafeButtonColor self.continueButton.backgroundColor = UIColor.covidSafeButtonDarkerColor
} else { } else {
self.continueButton.backgroundColor = UIColor(0xDBDDDD) self.continueButton.backgroundColor = UIColor(0xDBDDDD)
self.continueButton.isEnabled = false self.continueButton.isEnabled = false

View file

@ -13,12 +13,4 @@ struct PushNotificationConstants {
"contentBody": "Help stop the spread of COVID-19 by keeping your phones Bluetooth on until the outbreak is over." "contentBody": "Help stop the spread of COVID-19 by keeping your phones Bluetooth on until the outbreak is over."
] ]
] ]
// Daily Reminders
static let dailyRemPushNotifContents = [
[
"contentTitle": "Check if COVIDSafe is active",
"contentBody": "Don't forget to check if COVIDSafe is active before you leave home and when in public places."
]
]
} }

View file

@ -26,6 +26,8 @@ class RegistrationConsentViewController: UIViewController {
sender.isSelected = !sender.isSelected sender.isSelected = !sender.isSelected
self.agreeButton.isEnabled = sender.isSelected self.agreeButton.isEnabled = sender.isSelected
updateContinueButton() updateContinueButton()
consentCheckBox.accessibilityLabel = sender.isSelected ? "I consent checkbox, checked" : "I consent checkbox, unchecked"
} }
@IBAction func onBackTapped(_ sender: UIButton) { @IBAction func onBackTapped(_ sender: UIButton) {
@ -39,7 +41,7 @@ class RegistrationConsentViewController: UIViewController {
func updateContinueButton() { func updateContinueButton() {
if (agreeButton.isEnabled) { if (agreeButton.isEnabled) {
agreeButton.backgroundColor = UIColor.covidSafeButtonColor agreeButton.backgroundColor = UIColor.covidSafeButtonDarkerColor
} else { } else {
agreeButton.backgroundColor = UIColor(0xDBDDDD) agreeButton.backgroundColor = UIColor(0xDBDDDD)
} }

View file

@ -6,7 +6,8 @@ extension UIColor {
static let covidHomeActiveColor = UIColor(0xC8FFB9) static let covidHomeActiveColor = UIColor(0xC8FFB9)
static let covidHomePermissionErrorColor = UIColor(0xE2E2E2) static let covidHomePermissionErrorColor = UIColor(0xE2E2E2)
static let covidSafeColor = UIColor(0x00661B) static let covidSafeColor = UIColor(0x00661B)
static let covidSafeButtonColor = UIColor(0x008A23) static let covidSafeLighterColor = UIColor(0x008A23)
static let covidSafeButtonDarkerColor = UIColor(0x00661B)
var asSolidBackgroundImage: UIImage { var asSolidBackgroundImage: UIImage {
let rect = CGRect(x: 0, y: 0, width: 20, height: 20) let rect = CGRect(x: 0, y: 0, width: 20, height: 20)

View file

@ -31,7 +31,7 @@ class UnderSixteenViewController: UIViewController, RegistrationHandler {
func updateContinueButton() { func updateContinueButton() {
if (agreeButton.isEnabled) { if (agreeButton.isEnabled) {
agreeButton.backgroundColor = UIColor.covidSafeButtonColor agreeButton.backgroundColor = UIColor.covidSafeButtonDarkerColor
} else { } else {
agreeButton.backgroundColor = UIColor(0xDBDDDD) agreeButton.backgroundColor = UIColor(0xDBDDDD)
} }
@ -45,6 +45,7 @@ class UnderSixteenViewController: UIViewController, RegistrationHandler {
sender.isSelected = !sender.isSelected sender.isSelected = !sender.isSelected
self.agreeButton.isEnabled = sender.isSelected self.agreeButton.isEnabled = sender.isSelected
updateContinueButton() updateContinueButton()
consentCheckBox.accessibilityLabel = sender.isSelected ? "I consent checkbox, checked" : "I consent checkbox, unchecked"
} }
@IBAction func doneOntap(_ sender: Any) { @IBAction func doneOntap(_ sender: Any) {

View file

@ -49,6 +49,7 @@
<subviews> <subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AQj-UW-fvt" userLabel="BackBtn"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AQj-UW-fvt" userLabel="BackBtn">
<rect key="frame" x="16" y="16" width="44" height="44"/> <rect key="frame" x="16" y="16" width="44" height="44"/>
<accessibility key="accessibilityConfiguration" label="back"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="44" id="HWn-in-9mc"/> <constraint firstAttribute="height" constant="44" id="HWn-in-9mc"/>
<constraint firstAttribute="width" constant="44" id="czu-6G-Za0"/> <constraint firstAttribute="width" constant="44" id="czu-6G-Za0"/>
@ -60,6 +61,9 @@
</button> </button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Upload your information" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3zY-su-fK0"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Upload your information" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3zY-su-fK0">
<rect key="frame" x="32" y="56" width="311" height="29"/> <rect key="frame" x="32" y="56" width="311" height="29"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" header="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="24"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="24"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -115,11 +119,11 @@
</scrollView> </scrollView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="24k-o7-Lgs" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="24k-o7-Lgs" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target">
<rect key="frame" x="32" y="599" width="311" height="48"/> <rect key="frame" x="32" y="599" width="311" height="48"/>
<color key="backgroundColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.0" green="0.40000000000000002" blue="0.1058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="48" id="aN0-ip-CM7"/> <constraint firstAttribute="height" constant="48" id="aN0-ip-CM7"/>
</constraints> </constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Upload my information"> <state key="normal" title="Upload my information">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@ -226,6 +230,7 @@ Please do not close the app.</string>
<subviews> <subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WvG-1T-uDR" userLabel="BackBtn"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WvG-1T-uDR" userLabel="BackBtn">
<rect key="frame" x="315" y="16" width="44" height="44"/> <rect key="frame" x="315" y="16" width="44" height="44"/>
<accessibility key="accessibilityConfiguration" label="Close"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="44" id="Nrc-LG-i61"/> <constraint firstAttribute="height" constant="44" id="Nrc-LG-i61"/>
<constraint firstAttribute="width" constant="44" id="SvQ-oz-VvC"/> <constraint firstAttribute="width" constant="44" id="SvQ-oz-VvC"/>
@ -253,11 +258,11 @@ Please do not close the app.</string>
</label> </label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sEL-Fh-3RO" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sEL-Fh-3RO" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target">
<rect key="frame" x="0.0" y="358" width="311" height="48"/> <rect key="frame" x="0.0" y="358" width="311" height="48"/>
<color key="backgroundColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.0" green="0.40000000000000002" blue="0.1058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="48" id="8ao-HW-u9m"/> <constraint firstAttribute="height" constant="48" id="8ao-HW-u9m"/>
</constraints> </constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Try again"> <state key="normal" title="Try again">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@ -335,6 +340,7 @@ Please do not close the app.</string>
<subviews> <subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rvr-ky-7ly"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rvr-ky-7ly">
<rect key="frame" x="16" y="16" width="44" height="44"/> <rect key="frame" x="16" y="16" width="44" height="44"/>
<accessibility key="accessibilityConfiguration" label="back"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="44" id="TPE-hl-9Pf"/> <constraint firstAttribute="height" constant="44" id="TPE-hl-9Pf"/>
<constraint firstAttribute="width" constant="44" id="r0m-BO-V14"/> <constraint firstAttribute="width" constant="44" id="r0m-BO-V14"/>
@ -352,6 +358,9 @@ Please do not close the app.</string>
</imageView> </imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Is a health official asking you to upload your information?" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YGP-gN-IjT"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Is a health official asking you to upload your information?" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YGP-gN-IjT">
<rect key="frame" x="32" y="268" width="311" height="57.5"/> <rect key="frame" x="32" y="268" width="311" height="57.5"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" header="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="24"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="24"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -394,11 +403,11 @@ Once you press Yes youll need to provide consent to upload your informa
</scrollView> </scrollView>
<button opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="I1e-ah-JXF" userLabel="No" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target"> <button opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="I1e-ah-JXF" userLabel="No" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target">
<rect key="frame" x="32" y="587" width="151.5" height="48"/> <rect key="frame" x="32" y="587" width="151.5" height="48"/>
<color key="backgroundColor" red="0.0" green="0.54117647058823526" blue="0.13725490196078433" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.0" green="0.40000000000000002" blue="0.1058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="48" id="66Z-n2-IEN"/> <constraint firstAttribute="height" constant="48" id="66Z-n2-IEN"/>
</constraints> </constraints>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<color key="tintColor" red="0.0" green="0.54117647058823526" blue="0.13725490196078433" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="0.0" green="0.54117647058823526" blue="0.13725490196078433" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="No"> <state key="normal" title="No">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@ -414,11 +423,11 @@ Once you press Yes youll need to provide consent to upload your informa
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9xg-wK-gCo" userLabel="Yes" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9xg-wK-gCo" userLabel="Yes" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target">
<rect key="frame" x="191.5" y="587" width="151.5" height="48"/> <rect key="frame" x="191.5" y="587" width="151.5" height="48"/>
<color key="backgroundColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.0" green="0.40000000000000002" blue="0.1058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="48" id="WjV-Sg-A9T"/> <constraint firstAttribute="height" constant="48" id="WjV-Sg-A9T"/>
</constraints> </constraints>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Yes"> <state key="normal" title="Yes">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@ -470,6 +479,9 @@ Once you press Yes youll need to provide consent to upload your informa
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Upload Consent" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ecY-RE-ssa"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Upload Consent" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ecY-RE-ssa">
<rect key="frame" x="32" y="56" width="311" height="29"/> <rect key="frame" x="32" y="56" width="311" height="29"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" header="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="24"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="24"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -488,6 +500,9 @@ Read the COVIDSafe *privacy policy* for further details.</string>
</textView> </textView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mzh-IB-Sem" userLabel="ConsentButton"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mzh-IB-Sem" userLabel="ConsentButton">
<rect key="frame" x="32" y="391" width="24" height="24"/> <rect key="frame" x="32" y="391" width="24" height="24"/>
<accessibility key="accessibilityConfiguration" hint="Check to consent" label="I consent checkbox, unchecked">
<accessibilityTraits key="traits" none="YES"/>
</accessibility>
<constraints> <constraints>
<constraint firstAttribute="height" constant="24" id="FJs-ZV-f7s"/> <constraint firstAttribute="height" constant="24" id="FJs-ZV-f7s"/>
<constraint firstAttribute="width" constant="24" id="rSd-43-LYy"/> <constraint firstAttribute="width" constant="24" id="rSd-43-LYy"/>
@ -505,6 +520,7 @@ Read the COVIDSafe *privacy policy* for further details.</string>
</label> </label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c1v-Px-kY5"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c1v-Px-kY5">
<rect key="frame" x="16" y="16" width="44" height="44"/> <rect key="frame" x="16" y="16" width="44" height="44"/>
<accessibility key="accessibilityConfiguration" label="back"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="44" id="ufi-VP-bXc"/> <constraint firstAttribute="height" constant="44" id="ufi-VP-bXc"/>
<constraint firstAttribute="width" constant="44" id="xGv-7N-ugt"/> <constraint firstAttribute="width" constant="44" id="xGv-7N-ugt"/>
@ -545,11 +561,12 @@ Read the COVIDSafe *privacy policy* for further details.</string>
</scrollView> </scrollView>
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="huH-hW-8ZB" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target"> <button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="huH-hW-8ZB" customClass="GradientButton" customModule="COVIDSafe" customModuleProvider="target">
<rect key="frame" x="32" y="587" width="311" height="48"/> <rect key="frame" x="32" y="587" width="311" height="48"/>
<color key="backgroundColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.0" green="0.40000000000000002" blue="0.1058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<accessibility key="accessibilityConfiguration" hint="please consent to proceed"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="48" id="1pW-Jb-2mj"/> <constraint firstAttribute="height" constant="48" id="1pW-Jb-2mj"/>
</constraints> </constraints>
<fontDescription key="fontDescription" type="system" pointSize="16"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Continue"> <state key="normal" title="Continue">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@ -620,6 +637,9 @@ Read the COVIDSafe *privacy policy* for further details.</string>
</imageView> </imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Thank you for helping to stop the spread of COVID-19!" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="C1n-tc-aEy"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Thank you for helping to stop the spread of COVID-19!" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="C1n-tc-aEy">
<rect key="frame" x="32" y="192" width="311" height="57.5"/> <rect key="frame" x="32" y="192" width="311" height="57.5"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" header="YES"/>
</accessibility>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="24"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="24"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@ -667,11 +687,11 @@ State or territory health officials will notify other COVIDSafe users that have
</scrollView> </scrollView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N0O-fk-ZsF"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="N0O-fk-ZsF">
<rect key="frame" x="32" y="598" width="311" height="49"/> <rect key="frame" x="32" y="598" width="311" height="49"/>
<color key="backgroundColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.0" green="0.40000000000000002" blue="0.1058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="49" id="gDg-cR-S0i"/> <constraint firstAttribute="height" constant="49" id="gDg-cR-S0i"/>
</constraints> </constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="0.0" green="0.54117647059999996" blue="0.13725490200000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<state key="normal" title="Continue"> <state key="normal" title="Continue">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

View file

@ -25,6 +25,7 @@ final class UploadDataHomeViewController: UIViewController {
sender.isSelected = !sender.isSelected sender.isSelected = !sender.isSelected
self.agreeButton.isEnabled = sender.isSelected self.agreeButton.isEnabled = sender.isSelected
updateContinueButton() updateContinueButton()
consentCheckBox.accessibilityLabel = sender.isSelected ? "I consent checkbox, checked" : "I consent checkbox, unchecked"
} }
@IBAction func onBackTapped(_ sender: UIButton) { @IBAction func onBackTapped(_ sender: UIButton) {
@ -33,7 +34,7 @@ final class UploadDataHomeViewController: UIViewController {
func updateContinueButton() { func updateContinueButton() {
if (agreeButton.isEnabled) { if (agreeButton.isEnabled) {
agreeButton.backgroundColor = UIColor.covidSafeButtonColor agreeButton.backgroundColor = UIColor.covidSafeButtonDarkerColor
} else { } else {
agreeButton.backgroundColor = UIColor(0xDBDDDD) agreeButton.backgroundColor = UIColor(0xDBDDDD)
} }

View file

@ -35,7 +35,7 @@ class UploadDataStep2VC: UIViewController, CodeInputViewDelegate {
let uploadFailErrMsg = "Upload failed. Please try again later." let uploadFailErrMsg = "Upload failed. Please try again later."
let invalidPinErrMsg = "Invalid PIN, please ask the health official to send you another PIN." let invalidPinErrMsg = "Invalid PIN, please ask the health official to send you another PIN."
let verifyEnabledColor = UIColor.covidSafeButtonColor let verifyEnabledColor = UIColor.covidSafeButtonDarkerColor
let verifyDisabledColor = UIColor(red: 219/255.0, green: 221/255.0, blue: 221.0/255.0, alpha: 1.0) let verifyDisabledColor = UIColor(red: 219/255.0, green: 221/255.0, blue: 221.0/255.0, alpha: 1.0)
lazy var countdownFormatter: DateComponentsFormatter = { lazy var countdownFormatter: DateComponentsFormatter = {

View file

@ -1,5 +1,7 @@
# COVIDSafe app # COVIDSafe app
# Please report any security vulnerabilities using the details from [https://covidsafe.gov.au/.well-known/security.txt](https://covidsafe.gov.au/.well-known/security.txt)
# [Terms and Conditions for access to COVIDSafe App code](https://github.com/AU-COVIDSafe/mobile-ios/blob/master/LICENSE.md) # [Terms and Conditions for access to COVIDSafe App code](https://github.com/AU-COVIDSafe/mobile-ios/blob/master/LICENSE.md)
By accessing the App Code I accept and agree to the following terms: By accessing the App Code I accept and agree to the following terms:

17
security.txt Normal file
View file

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Contact: mailto:support@covidsafe.gov.au
Canonical: https://www.covidsafe.gov.au/.well-known/security.txt
Encryption: https://www.covidsafe.gov.au/.well-known/pgp-key.txt
-----BEGIN PGP SIGNATURE-----
iQFNBAEBCAA3FiEEbUgetBuPAas8w7zHDyQUNNekxBkFAl6xF6AZHHN1cHBvcnRA
Y292aWRzYWZlLmdvdi5hdQAKCRAPJBQ016TEGd+bCACLrYjCbKRsTsQQyZVVtGxj
wYKW2AWclnKZWX/sxnTexg6D1tlGbZbB0OJpw0gJ0NpMoOLFd0kRZXOzv8RocIdx
xd90Nwwl3NQ2ygGCDXR0Y7uRKX/P/Y1xO7XkyiYXAqVq3YWvI9M04pY/TCRvRZ/1
qBs/WDHv/6eRh2qNy/WGXD66CmTLHBcXilTeihcTZ/27Mny5SPthdfy8odQnhUja
NfFxDm+8gQuFKUUQmr9rd8FEMPSl6BWf/kQtn0YmTeZRzD01uT1ydeHkyPSgn+nq
k9us35AlkI7aZNfNkFVWJ2v5ZVAdTHDh3pgBRZETwVg1of5DEXhc5XJV6mLsu9bM
=tik2
-----END PGP SIGNATURE-----