mirror of
https://github.com/AU-COVIDSafe/mobile-ios.git
synced 2025-01-18 00:36:34 +00:00
COVIDSafe code from version 2.6 (#51)
This commit is contained in:
parent
195798ddd5
commit
4d98b6c5e4
43 changed files with 910 additions and 144 deletions
49
.circleci/README.md
Normal file
49
.circleci/README.md
Normal file
|
@ -0,0 +1,49 @@
|
|||
|
||||
## Introduction
|
||||
|
||||
CircleCI has a workflow configured to build and upload UAT builds once a merge is done to the dev branch. In the same way, there is a workflow for production and it runs when a merge is done to the master branch.
|
||||
|
||||
Fastlane is used to build and distribute the app.
|
||||
|
||||
|
||||
## Fastlane Configuration
|
||||
|
||||
The approach taken for the app build and distribution was to provide the `provisioning profile` and the `certificate` manually rather than retrieving it automatically from appstore connect. For this, environment variables are set with the required values for both UAT and PROD.
|
||||
|
||||
This aliviates the requirements for authentication and interaction with the appstore leaving upload as the only outstanding task in the lanes. With fastlane's `pilot` we upload the app to TestFlight using application specific password, this action **requires** both `apple_id` and `skip_waiting_for_build_processing`. For more information see https://docs.fastlane.tools/actions/upload_to_testflight/#use-an-application-specific-password-to-upload
|
||||
|
||||
Note: Build numbers need to be set correctly on merge otherwise the upload will fail. In order to automate the build number update it is recomended to use an api_key.
|
||||
|
||||
### Lanes
|
||||
|
||||
There are 2 lanes defined per app build (UAT and PROD):
|
||||
|
||||
- import_uat_distribution_certificate: This lane will decode and install the needed provisioning profile and signing certificate for the UAT build.
|
||||
- import_distribution_certificate: This lane will decode and install the needed provisioning profile and signing certificate for the PROD build.
|
||||
- beta: This lane will build and upload the UAT build to testflight
|
||||
- release: This lane will build and upload the PROD build to testflight
|
||||
|
||||
## CircleCI Project Configuration
|
||||
|
||||
The following environment variables need to be set in the CircleCI web console project configuration.
|
||||
|
||||
|
||||
- APP_STORE_UAT_PROFILE_B64: Base64 encoded provisioning profile to use with UAT builds
|
||||
- DISTRIBUTION_UAT_P12_B64: Base64 encoded distribution certificate to use with UAT builds
|
||||
- DISTRIBUTION_UAT_P12_PASSWORD: Password for the UAT certificate above.
|
||||
- APPLE_ID_UAT: This is the apps apple id. Can be found in appstore connect under App information -> General information.
|
||||
|
||||
- APP_STORE_PROFILE_B64: Base64 encoded provisioning profile to use with UAT builds
|
||||
- DISTRIBUTION_P12_B64: Base64 encoded distribution certificate to use with UAT builds
|
||||
- DISTRIBUTION_P12_PASSWORD: Password for the UAT certificate above.
|
||||
- APPLE_ID: This is the apps apple id. Can be found in appstore connect under App information -> General information.
|
||||
|
||||
- FASTLANE_USER: App store connect user
|
||||
- FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: Application specific password generated for Fastlane. This is account specific rather than app specific, share the same for UAT and PROD. For more information on how to generate the password see https://docs.fastlane.tools/best-practices/continuous-integration/#method-3-application-specific-passwords
|
||||
|
||||
|
||||
To get a base64 encoded string of the desired secret run
|
||||
|
||||
```
|
||||
openssl base64 -A -in "filename.extension"
|
||||
```
|
69
.circleci/config.yml
Normal file
69
.circleci/config.yml
Normal file
|
@ -0,0 +1,69 @@
|
|||
# Circle CI Build config for COVIDSafe
|
||||
|
||||
version: 2.1
|
||||
|
||||
|
||||
commands:
|
||||
|
||||
prepare-uat:
|
||||
steps:
|
||||
- checkout
|
||||
- run: bundle install
|
||||
- run: mkdir -pv ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
- run: echo ${APP_STORE_UAT_PROFILE_B64} | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/AppStore_UAT.mobileprovision
|
||||
- run: echo ${DISTRIBUTION_UAT_P12_B64} | base64 --decode > Distribution_UAT.p12
|
||||
- run: bundle exec fastlane import_uat_distribution_certificate
|
||||
|
||||
prepare-release:
|
||||
steps:
|
||||
- checkout
|
||||
- run: bundle install
|
||||
- run: mkdir -pv ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
- run: echo ${APP_STORE_PROFILE_B64} | base64 --decode > ~/Library/MobileDevice/Provisioning\ Profiles/AppStore.mobileprovision
|
||||
- run: echo ${DISTRIBUTION_P12_B64} | base64 --decode > Distribution.p12
|
||||
- run: bundle exec fastlane import_distribution_certificate
|
||||
|
||||
jobs:
|
||||
|
||||
build-uat:
|
||||
|
||||
macos:
|
||||
xcode: 12.4.0 # Specify the Xcode version to use
|
||||
environment:
|
||||
FL_OUTPUT_DIR: output
|
||||
steps:
|
||||
- prepare-uat
|
||||
- checkout
|
||||
- run: bundle exec pod install
|
||||
- run: bundle exec fastlane beta
|
||||
- store_artifacts:
|
||||
path: output
|
||||
|
||||
build-release:
|
||||
|
||||
macos:
|
||||
xcode: 12.4.0 # Specify the Xcode version to use
|
||||
environment:
|
||||
FL_OUTPUT_DIR: output
|
||||
steps:
|
||||
- prepare-release
|
||||
- checkout
|
||||
- run: bundle exec pod install
|
||||
- run: bundle exec fastlane release
|
||||
- store_artifacts:
|
||||
path: output
|
||||
|
||||
workflows:
|
||||
build-uat:
|
||||
jobs:
|
||||
- build-uat:
|
||||
filters:
|
||||
branches:
|
||||
only: dev
|
||||
|
||||
build-release:
|
||||
jobs:
|
||||
- build-release:
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
|
@ -316,6 +316,8 @@
|
|||
5BA3624225E463B6002CFF41 /* WebContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BA3624025E463B5002CFF41 /* WebContentView.xib */; };
|
||||
5BA3624625E4654F002CFF41 /* WebContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA3624525E4654E002CFF41 /* WebContentView.swift */; };
|
||||
5BA3624725E4654F002CFF41 /* WebContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA3624525E4654E002CFF41 /* WebContentView.swift */; };
|
||||
5BB9B8A0262FE0870056C47E /* KeychainSwift+Singleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB9B89F262FE0870056C47E /* KeychainSwift+Singleton.swift */; };
|
||||
5BB9B8A1262FE0870056C47E /* KeychainSwift+Singleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB9B89F262FE0870056C47E /* KeychainSwift+Singleton.swift */; };
|
||||
5BBC571D25526F99005E90AA /* staging-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5BBC571C25526F99005E90AA /* staging-Info.plist */; };
|
||||
5BBE61B125633B6D00B8C983 /* CSGenericContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BBE61B025633B6D00B8C983 /* CSGenericContentView.xib */; };
|
||||
5BBE61B225633B6D00B8C983 /* CSGenericContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5BBE61B025633B6D00B8C983 /* CSGenericContentView.xib */; };
|
||||
|
@ -564,6 +566,7 @@
|
|||
5BA3623325DE133D002CFF41 /* CSGenericErrorController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSGenericErrorController.swift; sourceTree = "<group>"; };
|
||||
5BA3624025E463B5002CFF41 /* WebContentView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WebContentView.xib; sourceTree = "<group>"; };
|
||||
5BA3624525E4654E002CFF41 /* WebContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebContentView.swift; sourceTree = "<group>"; };
|
||||
5BB9B89F262FE0870056C47E /* KeychainSwift+Singleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeychainSwift+Singleton.swift"; sourceTree = "<group>"; };
|
||||
5BBC571C25526F99005E90AA /* staging-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "staging-Info.plist"; sourceTree = "<group>"; };
|
||||
5BBE61B025633B6D00B8C983 /* CSGenericContentView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CSGenericContentView.xib; sourceTree = "<group>"; };
|
||||
5BBE61B625633E8D00B8C983 /* CSGenericViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CSGenericViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -800,6 +803,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
B605A7B02427429D008BA819 /* PlistHelper.swift */,
|
||||
5BB9B89F262FE0870056C47E /* KeychainSwift+Singleton.swift */,
|
||||
5B900FC02485C4EE00CAA419 /* String+Localization.swift */,
|
||||
5B69C06525D382AF00DF536D /* String+HtmlAttributed.swift */,
|
||||
0B1810112431EE610005D11F /* PhoneNumberParser.swift */,
|
||||
|
@ -1240,7 +1244,7 @@
|
|||
5B92D66A243018040049877B /* Sources */,
|
||||
5B92D6B7243018040049877B /* Frameworks */,
|
||||
5B92D6B9243018040049877B /* Resources */,
|
||||
67401E6C50CE0E543E47346A /* [CP] Embed Pods Frameworks */,
|
||||
34C60B5DD40F4458AB9E6FD0 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -1259,7 +1263,7 @@
|
|||
5DD41D3323DCB03B00FD4AB0 /* Sources */,
|
||||
5DD41D3423DCB03B00FD4AB0 /* Frameworks */,
|
||||
5DD41D3523DCB03B00FD4AB0 /* Resources */,
|
||||
2D8EF319C5D6408D45C0B585 /* [CP] Embed Pods Frameworks */,
|
||||
DB7F6C492EEEEFCD9ACA09F9 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -1432,24 +1436,7 @@
|
|||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
2D8EF319C5D6408D45C0B585 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-CovidSafe/Pods-CovidSafe-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-CovidSafe/Pods-CovidSafe-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CovidSafe/Pods-CovidSafe-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
67401E6C50CE0E543E47346A /* [CP] Embed Pods Frameworks */ = {
|
||||
34C60B5DD40F4458AB9E6FD0 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
|
@ -1488,6 +1475,23 @@
|
|||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
DB7F6C492EEEEFCD9ACA09F9 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-CovidSafe/Pods-CovidSafe-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-CovidSafe/Pods-CovidSafe-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CovidSafe/Pods-CovidSafe-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
DC4D19AF69C7C819FCC35F09 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -1576,6 +1580,7 @@
|
|||
5B92D68A243018040049877B /* Outcome.swift in Sources */,
|
||||
5B92D68B243018040049877B /* Encounter+EncounterRecord.swift in Sources */,
|
||||
0B42D0DE2432B39E00E4F44C /* Question2ErrorViewController.swift in Sources */,
|
||||
5BB9B8A1262FE0870056C47E /* KeychainSwift+Singleton.swift in Sources */,
|
||||
594E77C024736B77009B8B34 /* EncounterDB.swift in Sources */,
|
||||
5B728B4724B5667000654ABC /* BLELogViewController.swift in Sources */,
|
||||
590888B42431B9F5008C9B9F /* UploadDataNavigationController.swift in Sources */,
|
||||
|
@ -1796,6 +1801,7 @@
|
|||
A767D32F242DF1B100DC9E2A /* Errors.swift in Sources */,
|
||||
5905462A2543E0F6009B82AD /* PayloadDataSupplier.swift in Sources */,
|
||||
0B22A56B242F286900D1FE60 /* UINavigationBar+Style.swift in Sources */,
|
||||
5BB9B8A0262FE0870056C47E /* KeychainSwift+Singleton.swift in Sources */,
|
||||
0B1810122431EE610005D11F /* PhoneNumberParser.swift in Sources */,
|
||||
1B86119B24303FA200EA4B6B /* Question3ErrorViewController.swift in Sources */,
|
||||
5BEDEF5425CBC4A900AEEC20 /* RestrictionsViewController.swift in Sources */,
|
||||
|
@ -1971,9 +1977,9 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 121;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 127;
|
||||
DEVELOPMENT_TEAM = 45792XH5L8;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
|
@ -1981,11 +1987,11 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5;
|
||||
MARKETING_VERSION = 2.6;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
|
||||
PRODUCT_NAME = COVIDSafe;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = COVIDSafe;
|
||||
SERVICE_UUID = "17E033D3-490E-4BC9-9FE8-2F567643F4D3";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CovidSafe/covid-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
@ -2055,9 +2061,9 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 121;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 127;
|
||||
DEVELOPMENT_TEAM = 45792XH5L8;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
|
@ -2065,10 +2071,10 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5;
|
||||
MARKETING_VERSION = 2.6;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
|
||||
PRODUCT_NAME = COVIDSafe;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = COVIDSafe;
|
||||
SERVICE_UUID = "B82AB3FC-1595-4F6A-80F0-FE094CC218F9";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CovidSafe/covid-Bridging-Header.h";
|
||||
SWIFT_REFLECTION_METADATA_LEVEL = none;
|
||||
|
@ -2083,9 +2089,9 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 120;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 126;
|
||||
DEVELOPMENT_TEAM = 45792XH5L8;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/staging-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
|
@ -2093,13 +2099,13 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5;
|
||||
MARKETING_VERSION = 2.6;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe.uat;
|
||||
PRODUCT_MODULE_NAME = COVIDSafe;
|
||||
PRODUCT_NAME = "COVIDSafe-staging";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "CovidSafe UAT";
|
||||
SERVICE_UUID = "CC0AC8B7-03B5-4252-8D84-44D199E16065";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CovidSafe/covid-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
@ -2113,9 +2119,9 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 120;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 126;
|
||||
DEVELOPMENT_TEAM = 45792XH5L8;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/staging-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
|
@ -2123,13 +2129,13 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5;
|
||||
MARKETING_VERSION = 2.6;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe.uat;
|
||||
PRODUCT_MODULE_NAME = COVIDSafe;
|
||||
PRODUCT_NAME = "COVIDSafe-staging";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "CovidSafe UAT";
|
||||
SERVICE_UUID = "CC0AC8B7-03B5-4252-8D84-44D199E16065";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CovidSafe/covid-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
@ -2143,9 +2149,9 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 120;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 126;
|
||||
DEVELOPMENT_TEAM = 45792XH5L8;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/staging-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
|
@ -2153,12 +2159,12 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5;
|
||||
MARKETING_VERSION = 2.6;
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe.uat;
|
||||
PRODUCT_MODULE_NAME = COVIDSafe;
|
||||
PRODUCT_NAME = "COVIDSafe-staging";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "CovidSafe UAT";
|
||||
SERVICE_UUID = "CC0AC8B7-03B5-4252-8D84-44D199E16065";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CovidSafe/covid-Bridging-Header.h";
|
||||
SWIFT_REFLECTION_METADATA_LEVEL = none;
|
||||
|
@ -2173,9 +2179,9 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 120;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 126;
|
||||
DEVELOPMENT_TEAM = 45792XH5L8;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/staging-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
|
@ -2183,12 +2189,12 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5;
|
||||
MARKETING_VERSION = 2.6;
|
||||
OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe.uat;
|
||||
PRODUCT_MODULE_NAME = COVIDSafe;
|
||||
PRODUCT_NAME = "COVIDSafe-staging";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "CovidSafe UAT";
|
||||
SERVICE_UUID = "CC0AC8B7-03B5-4252-8D84-44D199E16065";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CovidSafe/covid-Bridging-Header.h";
|
||||
SWIFT_REFLECTION_METADATA_LEVEL = none;
|
||||
|
@ -2321,9 +2327,9 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 121;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 127;
|
||||
DEVELOPMENT_TEAM = 45792XH5L8;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
|
@ -2331,11 +2337,11 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5;
|
||||
MARKETING_VERSION = 2.6;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
|
||||
PRODUCT_NAME = COVIDSafe;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = COVIDSafe;
|
||||
SERVICE_UUID = "CC0AC8B7-03B5-4252-8D84-44D199E16065";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CovidSafe/covid-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
@ -2349,9 +2355,9 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 121;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 127;
|
||||
DEVELOPMENT_TEAM = 45792XH5L8;
|
||||
INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
|
@ -2359,10 +2365,10 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 2.5;
|
||||
MARKETING_VERSION = 2.6;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe;
|
||||
PRODUCT_NAME = COVIDSafe;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = COVIDSafe;
|
||||
SERVICE_UUID = "B82AB3FC-1595-4F6A-80F0-FE094CC218F9";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CovidSafe/covid-Bridging-Header.h";
|
||||
SWIFT_REFLECTION_METADATA_LEVEL = none;
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
|
|
|
@ -16,10 +16,15 @@ class AuthenticationAPI: CovidSafeAuthenticatedAPI {
|
|||
return
|
||||
}
|
||||
|
||||
guard let authHeaders = try? authenticatedHeaders() else {
|
||||
completion(nil, .RequestError)
|
||||
return
|
||||
}
|
||||
|
||||
CovidNetworking.shared.session.request("\(apiHost)/issueInitialRefreshToken",
|
||||
method: .post,
|
||||
encoding: JSONEncoding.default,
|
||||
headers: authenticatedHeaders
|
||||
headers: authHeaders
|
||||
).validate().responseDecodable(of: ChallengeResponse.self) { (response) in
|
||||
switch response.result {
|
||||
case .success:
|
||||
|
@ -55,7 +60,7 @@ class AuthenticationAPI: CovidSafeAuthenticatedAPI {
|
|||
return
|
||||
}
|
||||
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
|
||||
guard let token = keychain.get("JWT_TOKEN"),
|
||||
let refreshToken = keychain.get("REFRESH_TOKEN"),
|
||||
|
@ -105,7 +110,7 @@ class AuthenticationAPI: CovidSafeAuthenticatedAPI {
|
|||
}
|
||||
|
||||
static func issueTokensAPI(completion: @escaping (ChallengeResponse?, CovidSafeAPIError?) -> Void) {
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
|
||||
// block api call only if refresh token exists, if it doesn't it means the app should get it for the first time
|
||||
if UserDefaults.standard.bool(forKey: "ReauthenticationNeededKey") && keychain.get("REFRESH_TOKEN") != nil {
|
||||
|
@ -132,13 +137,20 @@ class AuthenticationAPI: CovidSafeAuthenticatedAPI {
|
|||
completion(response, nil)
|
||||
}
|
||||
} else {
|
||||
let refreshTokenBeforeRefresh = keychain.get("REFRESH_TOKEN")
|
||||
AuthenticationAPI.issueJWTTokenAPI { (response, error) in
|
||||
|
||||
guard let jwt = response?.token,
|
||||
let refresh = response?.refreshToken,
|
||||
error == nil else {
|
||||
|
||||
// set corrupted
|
||||
// if the token in the system before the call is different than the one in keychain, this is a concurrency issue, the token was refresh already and that is why this failed. We should not start re-authentication
|
||||
guard refreshTokenBeforeRefresh == keychain.get("REFRESH_TOKEN") else {
|
||||
completion(response, .TokenAlreadyRefreshedError)
|
||||
return
|
||||
}
|
||||
|
||||
// set corrupted only when it has not been changed
|
||||
UserDefaults.standard.set(true, forKey: "ReauthenticationNeededKey")
|
||||
completion(response, .TokenExpiredError)
|
||||
return
|
||||
|
|
|
@ -20,11 +20,17 @@ class ChangePostcodeAPI: CovidSafeAuthenticatedAPI {
|
|||
let params = [
|
||||
"postcode": newPostcode,
|
||||
]
|
||||
|
||||
guard let authHeaders = try? authenticatedHeaders() else {
|
||||
completion(.RequestError)
|
||||
return
|
||||
}
|
||||
|
||||
CovidNetworking.shared.session.request("\(apiHost)/device",
|
||||
method: .post,
|
||||
parameters: params,
|
||||
encoding: JSONEncoding.default,
|
||||
headers: authenticatedHeaders,
|
||||
headers: authHeaders,
|
||||
interceptor: CovidRequestRetrier(retries:3)).validate().responseDecodable(of: DeviceResponse.self) { (response) in
|
||||
switch response.result {
|
||||
case .success:
|
||||
|
|
|
@ -56,6 +56,8 @@ enum CovidSafeAPIError: Error {
|
|||
case ResponseError
|
||||
case ServerError
|
||||
case TokenExpiredError
|
||||
case TokenAlreadyRefreshedError
|
||||
case MaxRegistrationError
|
||||
case UnknownError
|
||||
}
|
||||
|
||||
|
@ -63,18 +65,16 @@ class CovidSafeAuthenticatedAPI {
|
|||
|
||||
static var isBusy = false
|
||||
|
||||
static var authenticatedHeaders: HTTPHeaders {
|
||||
get {
|
||||
let keychain = KeychainSwift()
|
||||
|
||||
guard let token = keychain.get("JWT_TOKEN") else {
|
||||
return []
|
||||
}
|
||||
let headers: HTTPHeaders = [
|
||||
"Authorization": "Bearer \(token)"
|
||||
]
|
||||
return headers
|
||||
static func authenticatedHeaders() throws -> HTTPHeaders {
|
||||
let keychain = KeychainSwift.shared
|
||||
|
||||
guard let token = keychain.get("JWT_TOKEN") else {
|
||||
throw CovidSafeAPIError.RequestError
|
||||
}
|
||||
let headers: HTTPHeaders = [
|
||||
"Authorization": "Bearer \(token)"
|
||||
]
|
||||
return headers
|
||||
}
|
||||
|
||||
static func processUnauthorizedError(_ data: Data) -> CovidSafeAPIError {
|
||||
|
|
|
@ -20,8 +20,12 @@ final class CovidRequestRetrier: Alamofire.RequestInterceptor {
|
|||
|
||||
func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
|
||||
var urlRequest = urlRequest
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
let refreshExists = keychain.get("REFRESH_TOKEN") != nil
|
||||
|
||||
// turn off geolock error
|
||||
UserDefaults.standard.setValue(false, forKey: showGeolockErrorKey)
|
||||
|
||||
// prevent authenticated api calls if the re-registration flow has been started
|
||||
if UserDefaults.standard.bool(forKey: "ReauthenticationNeededKey") &&
|
||||
refreshExists {
|
||||
|
@ -81,13 +85,19 @@ final class CovidRequestRetrier: Alamofire.RequestInterceptor {
|
|||
return completion(.retryWithDelay(1.0))
|
||||
}
|
||||
|
||||
if let serverHeader = response.headers.first(where: { $0.name == "Server" }),
|
||||
response.statusCode == 403 && serverHeader.value == "CloudFront" {
|
||||
UserDefaults.standard.setValue(true, forKey: showGeolockErrorKey)
|
||||
return completion(.doNotRetryWithError(error))
|
||||
}
|
||||
|
||||
if !triedRefresh &&
|
||||
(response.statusCode == 403 || response.statusCode == 401) {
|
||||
(response.statusCode == 401 || response.statusCode == 403) {
|
||||
triedRefresh = true
|
||||
retriesExecuted += 1
|
||||
AuthenticationAPI.issueTokensAPI { (response, authError) in
|
||||
// this will update the tokens automatically
|
||||
guard let respError = authError, respError == .TokenExpiredError else {
|
||||
if let respError = authError, respError == .TokenExpiredError {
|
||||
completion(.doNotRetryWithError(error))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ class GetTempIdAPI: CovidSafeAuthenticatedAPI {
|
|||
"version" : apiVersion
|
||||
]
|
||||
|
||||
guard authenticatedHeaders.count > 0 else {
|
||||
guard let authHeaders = try? authenticatedHeaders(), authHeaders.count > 0 else {
|
||||
completion(nil, nil, nil, .TokenExpiredError)
|
||||
return
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class GetTempIdAPI: CovidSafeAuthenticatedAPI {
|
|||
CovidNetworking.shared.session.request("\(apiHost)/getTempId",
|
||||
method: .get,
|
||||
parameters: params,
|
||||
headers: authenticatedHeaders,
|
||||
headers: authHeaders,
|
||||
interceptor: CovidRequestRetrier(retries: 3)).validate().responseDecodable(of: TempIdResponse.self) { (response) in
|
||||
switch response.result {
|
||||
case .success:
|
||||
|
|
|
@ -65,7 +65,7 @@ class MessageAPI: CovidSafeAuthenticatedAPI {
|
|||
var shouldGetMessages = true
|
||||
|
||||
let calendar = NSCalendar.current
|
||||
let currentDate = calendar.startOfDay(for: Date())
|
||||
let currentDate = Date()
|
||||
|
||||
// if the current version is newer than the last version checked, allow messages call
|
||||
if let currVersionStr = Bundle.main.version, let currVersion = Int(currVersionStr), currVersion > versionChecked {
|
||||
|
@ -77,7 +77,7 @@ class MessageAPI: CovidSafeAuthenticatedAPI {
|
|||
let components = calendar.dateComponents([.hour], from: lastCheckedDate, to: currentDate)
|
||||
|
||||
if let numHours = components.hour {
|
||||
shouldGetMessages = numHours > 4
|
||||
shouldGetMessages = numHours >= 4
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,10 +109,15 @@ class MessageAPI: CovidSafeAuthenticatedAPI {
|
|||
|
||||
isBusy = true
|
||||
|
||||
guard let authHeaders = try? authenticatedHeaders() else {
|
||||
completion(nil, .RequestError)
|
||||
return
|
||||
}
|
||||
|
||||
CovidNetworking.shared.session.request("\(apiHost)/messages",
|
||||
method: .get,
|
||||
parameters: params,
|
||||
headers: authenticatedHeaders,
|
||||
headers: authHeaders,
|
||||
interceptor: CovidRequestRetrier(retries: 3)
|
||||
).validate().responseDecodable(of: MessageResponse.self) { (response) in
|
||||
switch response.result {
|
||||
|
@ -120,7 +125,7 @@ class MessageAPI: CovidSafeAuthenticatedAPI {
|
|||
guard let messageResponse = response.value else { return }
|
||||
|
||||
// save successful timestamp
|
||||
let minutesToDefer = Int.random(in: 0..<10)
|
||||
let minutesToDefer = Int.random(in: 0..<30)
|
||||
let calendar = NSCalendar.current
|
||||
let currentDate = Date()
|
||||
if let deferredDate = calendar.date(byAdding: .minute, value: minutesToDefer, to: currentDate) {
|
||||
|
|
|
@ -11,7 +11,7 @@ import Alamofire
|
|||
class PhoneValidationAPI {
|
||||
|
||||
static func verifyPhoneNumber(regInfo: RegistrationRequest,
|
||||
completion: @escaping (String?, Swift.Error?) -> Void) {
|
||||
completion: @escaping (String?, CovidSafeAPIError?) -> Void) {
|
||||
|
||||
guard let apiHost = PlistHelper.getvalueFromInfoPlist(withKey: "API_Host", plistName: "CovidSafe-config") else {
|
||||
return
|
||||
|
@ -33,8 +33,22 @@ class PhoneValidationAPI {
|
|||
case .success:
|
||||
guard let authResponse = response.value else { return }
|
||||
completion(authResponse.session, nil)
|
||||
case let .failure(error):
|
||||
completion(nil, error)
|
||||
case .failure(_):
|
||||
var apiError = CovidSafeAPIError.RequestError
|
||||
|
||||
if let respData = response.data {
|
||||
do {
|
||||
let errorResponse = try JSONDecoder().decode(CovidSafeErrorResponse.self, from: respData)
|
||||
if errorResponse.message == "MaxRegistrationsReached" {
|
||||
apiError = .MaxRegistrationError
|
||||
}
|
||||
} catch {
|
||||
// unable to parse response
|
||||
apiError = .ResponseError
|
||||
}
|
||||
}
|
||||
completion(nil, apiError)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,10 +24,15 @@ class RestrictionsAPI: CovidSafeAuthenticatedAPI {
|
|||
|
||||
let params = ["state": "\(forState.rawValue.lowercased())"]
|
||||
|
||||
guard let authHeaders = try? authenticatedHeaders() else {
|
||||
completion(nil, .RequestError)
|
||||
return
|
||||
}
|
||||
|
||||
CovidNetworking.shared.session.request("\(apiHost)/restrictions",
|
||||
method: .get,
|
||||
parameters: params,
|
||||
headers: authenticatedHeaders,
|
||||
headers: authHeaders,
|
||||
interceptor: CovidRequestRetrier(retries: 3)
|
||||
).validate().responseDecodable(of: StateRestriction.self) { (response) in
|
||||
switch response.result {
|
||||
|
|
|
@ -20,10 +20,15 @@ class StatisticsAPI: CovidSafeAuthenticatedAPI {
|
|||
|
||||
let parameters = ["state" : "\(forState.rawValue)"]
|
||||
|
||||
guard let authHeaders = try? authenticatedHeaders() else {
|
||||
completion(nil, .RequestError)
|
||||
return
|
||||
}
|
||||
|
||||
CovidNetworking.shared.session.request("\(apiHost)/v2/statistics",
|
||||
method: .get,
|
||||
parameters: parameters,
|
||||
headers: authenticatedHeaders,
|
||||
headers: authHeaders,
|
||||
interceptor: CovidRequestRetrier(retries: 3)
|
||||
).validate().responseDecodable(of: StatisticsResponse.self) { (response) in
|
||||
switch response.result {
|
||||
|
|
|
@ -21,7 +21,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
setupCoredataDir()
|
||||
let firstRun = UserDefaults.standard.bool(forKey: "HasBeenLaunched")
|
||||
if( !firstRun ) {
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
keychain.clear()
|
||||
UserDefaults.standard.set(true, forKey: "HasBeenLaunched")
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<outlet property="covidStatisticsContainer" destination="eZl-C5-gSv" id="37c-CV-VgS"/>
|
||||
<outlet property="covidStatisticsSection" destination="Aop-Ae-hRv" id="Qpd-Hv-uA8"/>
|
||||
<outlet property="inactiveAppSectionView" destination="784-Jf-kOX" id="J3m-Pu-697"/>
|
||||
<outlet property="inactiveGenericError" destination="5Pd-c8-CYx" id="Fez-q4-Oc5"/>
|
||||
<outlet property="inactiveSettingsContent" destination="AUW-C2-ven" id="NNP-o9-zkK"/>
|
||||
<outlet property="inactiveTokenExpiredView" destination="nxM-ji-ttb" id="vVC-KW-yek"/>
|
||||
<outlet property="locationPermissionsView" destination="u4f-uR-ri3" id="70q-Jr-1cc"/>
|
||||
|
@ -127,19 +128,19 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="h36-8c-K2n">
|
||||
<rect key="frame" x="0.0" y="120" width="414" height="1940.5"/>
|
||||
<rect key="frame" x="0.0" y="120" width="414" height="2105"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bRs-XW-qzv" userLabel="StatusView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="1136"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="1300.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="rcS-nL-IAO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="1124"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="1288.5"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="784-Jf-kOX" userLabel="InactiveView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="696.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="861"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="1" translatesAutoresizingMaskIntoConstraints="NO" id="xti-6W-zko" userLabel="Inactive Stack View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="696.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="861"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4fe-SU-8Q6" userLabel="InActiveHeader">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="81"/>
|
||||
|
@ -246,7 +247,7 @@
|
|||
</subviews>
|
||||
<accessibility key="accessibilityConfiguration" label="Bluetooth permissions off">
|
||||
<accessibilityTraits key="traits" button="YES"/>
|
||||
<bool key="isElement" value="YES"/>
|
||||
<bool key="isElement" value="NO"/>
|
||||
</accessibility>
|
||||
<constraints>
|
||||
<constraint firstItem="reL-DQ-aFx" firstAttribute="leading" secondItem="nxM-ji-ttb" secondAttribute="leading" id="DNN-Va-LUA"/>
|
||||
|
@ -255,8 +256,69 @@
|
|||
<constraint firstAttribute="bottom" secondItem="reL-DQ-aFx" secondAttribute="bottom" id="qeE-Hu-OAb"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5Pd-c8-CYx" userLabel="Generic Error View">
|
||||
<rect key="frame" x="0.0" y="369" width="414" height="163.5"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8Nu-a1-6fd" userLabel="Generic Error Bar">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="163.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Error connectiong to server" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yw4-mY-Pvb">
|
||||
<rect key="frame" x="16" y="16" width="238.5" height="0.0"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" id="K73-MG-bAA"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle3"/>
|
||||
<color key="textColor" red="0.63921568630000003" green="0.098039215690000001" blue="0.098039215690000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Iw2-bN-Bjb">
|
||||
<rect key="frame" x="16" y="16" width="350" height="131.5"/>
|
||||
<accessibility key="accessibilityConfiguration">
|
||||
<bool key="isElement" value="NO"/>
|
||||
</accessibility>
|
||||
<string key="text">It looks like you may be accessing the internet from outside Australia. This sometimes happens when roaming on an international simcard. Please connect to an Australian network to continue.</string>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleCallout"/>
|
||||
<color key="textColor" red="0.63921568630000003" green="0.098039215690000001" blue="0.098039215690000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="localizationKey" value="geoblock_error_message"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="chevron-right-red" highlightedImage="redcross" translatesAutoresizingMaskIntoConstraints="NO" id="JZ8-95-6mR">
|
||||
<rect key="frame" x="374" y="16" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="24" id="5Dg-TP-jeV"/>
|
||||
<constraint firstAttribute="height" constant="24" id="QDY-8b-rGB"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="yw4-mY-Pvb" firstAttribute="top" secondItem="8Nu-a1-6fd" secondAttribute="top" constant="16" id="8lj-Mp-QPd"/>
|
||||
<constraint firstItem="Iw2-bN-Bjb" firstAttribute="top" secondItem="yw4-mY-Pvb" secondAttribute="bottom" id="BG1-vf-8aa"/>
|
||||
<constraint firstItem="yw4-mY-Pvb" firstAttribute="leading" secondItem="8Nu-a1-6fd" secondAttribute="leading" constant="16" id="FB0-Gh-26E"/>
|
||||
<constraint firstItem="Iw2-bN-Bjb" firstAttribute="leading" secondItem="8Nu-a1-6fd" secondAttribute="leading" constant="16" id="MsQ-XB-0Cp"/>
|
||||
<constraint firstItem="JZ8-95-6mR" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="yw4-mY-Pvb" secondAttribute="trailing" constant="8" id="N9H-1e-dzZ"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Iw2-bN-Bjb" secondAttribute="bottom" constant="16" id="SmG-4M-0Ir"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Iw2-bN-Bjb" secondAttribute="trailing" constant="48" id="YQ6-nh-9k7"/>
|
||||
<constraint firstAttribute="trailing" secondItem="JZ8-95-6mR" secondAttribute="trailing" constant="16" id="jSl-T3-bbB"/>
|
||||
<constraint firstItem="JZ8-95-6mR" firstAttribute="top" secondItem="8Nu-a1-6fd" secondAttribute="top" constant="16" id="toG-5o-Kri"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<accessibility key="accessibilityConfiguration">
|
||||
<accessibilityTraits key="traits" button="YES"/>
|
||||
<bool key="isElement" value="NO"/>
|
||||
</accessibility>
|
||||
<constraints>
|
||||
<constraint firstItem="8Nu-a1-6fd" firstAttribute="leading" secondItem="5Pd-c8-CYx" secondAttribute="leading" id="GvM-yl-CrV"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8Nu-a1-6fd" secondAttribute="bottom" id="gZR-KX-tky"/>
|
||||
<constraint firstItem="8Nu-a1-6fd" firstAttribute="top" secondItem="5Pd-c8-CYx" secondAttribute="top" id="gl7-zv-NsS"/>
|
||||
<constraint firstAttribute="trailing" secondItem="8Nu-a1-6fd" secondAttribute="trailing" id="tnp-QS-aoM"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a5D-xk-n0n" userLabel="Bluetooth Permission Off Section">
|
||||
<rect key="frame" x="0.0" y="369" width="414" height="80.5"/>
|
||||
<rect key="frame" x="0.0" y="533.5" width="414" height="80.5"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZoL-pC-0bR" userLabel="Bluetooth Permission Off Bar">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="80.5"/>
|
||||
|
@ -327,7 +389,7 @@
|
|||
</connections>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ers-f9-BFH" userLabel="Bluetooth Status Off Section">
|
||||
<rect key="frame" x="0.0" y="450.5" width="414" height="101.5"/>
|
||||
<rect key="frame" x="0.0" y="615" width="414" height="101.5"/>
|
||||
<subviews>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="p5d-dk-foR" userLabel="Bluetooth Status Bar Off">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="101.5"/>
|
||||
|
@ -394,7 +456,7 @@
|
|||
</connections>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="u4f-uR-ri3" userLabel="Location Settings">
|
||||
<rect key="frame" x="0.0" y="553" width="414" height="143.5"/>
|
||||
<rect key="frame" x="0.0" y="717.5" width="414" height="143.5"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aGh-Fm-LNa" userLabel="Location Off bar">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="142.5"/>
|
||||
|
@ -473,7 +535,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="m1D-93-7sF" userLabel="ActiveView">
|
||||
<rect key="frame" x="0.0" y="696.5" width="414" height="427.5"/>
|
||||
<rect key="frame" x="0.0" y="861" width="414" height="427.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="1" translatesAutoresizingMaskIntoConstraints="NO" id="981-Cd-Xm3" userLabel="Active Stack View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="427.5"/>
|
||||
|
@ -592,7 +654,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Aop-Ae-hRv" userLabel="StatisticsViewSection">
|
||||
<rect key="frame" x="0.0" y="1136" width="414" height="124"/>
|
||||
<rect key="frame" x="0.0" y="1300.5" width="414" height="124"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="1" translatesAutoresizingMaskIntoConstraints="NO" id="eZl-C5-gSv" userLabel="StatisticsView">
|
||||
<rect key="frame" x="0.0" y="12" width="414" height="100"/>
|
||||
|
@ -610,7 +672,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9cE-NC-A20" userLabel="Help">
|
||||
<rect key="frame" x="0.0" y="1260" width="414" height="153"/>
|
||||
<rect key="frame" x="0.0" y="1424.5" width="414" height="153"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="co1-dK-1WU">
|
||||
<rect key="frame" x="0.0" y="12" width="414" height="129"/>
|
||||
|
@ -743,7 +805,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7cN-DY-lc3" userLabel="Change language">
|
||||
<rect key="frame" x="0.0" y="1413" width="414" height="153"/>
|
||||
<rect key="frame" x="0.0" y="1577.5" width="414" height="153"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bE9-gT-Hba">
|
||||
<rect key="frame" x="0.0" y="12" width="414" height="129"/>
|
||||
|
@ -876,7 +938,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CGS-rw-uZS" userLabel="PrivacyPolicy">
|
||||
<rect key="frame" x="0.0" y="1566" width="414" height="153"/>
|
||||
<rect key="frame" x="0.0" y="1730.5" width="414" height="153"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BBB-zD-Non">
|
||||
<rect key="frame" x="0.0" y="12" width="414" height="129"/>
|
||||
|
@ -885,7 +947,7 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="414" height="129"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Privacy Policy" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mFo-iF-cX3">
|
||||
<rect key="frame" x="72" y="16" width="302" height="24"/>
|
||||
<rect key="frame" x="72" y="16" width="302" height="77.5"/>
|
||||
<accessibility key="accessibilityConfiguration">
|
||||
<accessibilityTraits key="traits" none="YES"/>
|
||||
<bool key="isElement" value="NO"/>
|
||||
|
@ -908,7 +970,7 @@
|
|||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Privacy Policy for COVIDSafe Application" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gF9-eh-ER2">
|
||||
<rect key="frame" x="72" y="40" width="302" height="73"/>
|
||||
<rect key="frame" x="72" y="93.5" width="302" height="19.5"/>
|
||||
<accessibility key="accessibilityConfiguration">
|
||||
<accessibilityTraits key="traits" none="YES"/>
|
||||
<bool key="isElement" value="NO"/>
|
||||
|
@ -1009,7 +1071,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vs9-rS-UOM" userLabel="Share CovidSafe">
|
||||
<rect key="frame" x="0.0" y="1719" width="414" height="56"/>
|
||||
<rect key="frame" x="0.0" y="1883.5" width="414" height="56"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RCa-zU-3Vo">
|
||||
<rect key="frame" x="0.0" y="12" width="414" height="32"/>
|
||||
|
@ -1120,7 +1182,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JSe-D6-hyV" userLabel="Upload Data">
|
||||
<rect key="frame" x="0.0" y="1719" width="414" height="165.5"/>
|
||||
<rect key="frame" x="0.0" y="1883.5" width="414" height="165.5"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8pS-Df-p0U">
|
||||
<rect key="frame" x="0.0" y="12" width="414" height="141.5"/>
|
||||
|
@ -1240,7 +1302,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eZ2-CQ-dtQ" userLabel="Version View">
|
||||
<rect key="frame" x="0.0" y="1884.5" width="414" height="56"/>
|
||||
<rect key="frame" x="0.0" y="2049" width="414" height="56"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Version number:" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="O1w-Sl-OIH" userLabel="Version">
|
||||
<rect key="frame" x="16" y="12" width="382" height="20"/>
|
||||
|
|
|
@ -4,15 +4,18 @@ import KeychainSwift
|
|||
import SafariServices
|
||||
import Reachability
|
||||
|
||||
let reauthenticationNeededKey = "ReauthenticationNeededKey"
|
||||
let showGeolockErrorKey = "showGeolockErrorKey"
|
||||
|
||||
class HomeViewController: UIViewController, HomeDelegate {
|
||||
private var observer: NSObjectProtocol?
|
||||
private let reauthenticationNeededKey = "ReauthenticationNeededKey"
|
||||
|
||||
@IBOutlet weak var bluetoothStatusOffView: UIView!
|
||||
@IBOutlet weak var bluetoothPermissionOffView: UIView!
|
||||
@IBOutlet weak var locationPermissionsView: UIView!
|
||||
@IBOutlet weak var inactiveSettingsContent: UIView!
|
||||
@IBOutlet weak var inactiveTokenExpiredView: UIView!
|
||||
@IBOutlet weak var inactiveGenericError: UIView!
|
||||
@IBOutlet weak var shareView: UIView!
|
||||
@IBOutlet weak var inactiveAppSectionView: UIView!
|
||||
@IBOutlet weak var activeAppSectionView: UIView!
|
||||
|
@ -42,8 +45,17 @@ class HomeViewController: UIViewController, HomeDelegate {
|
|||
|
||||
var allPermissionOn = true
|
||||
|
||||
var registrationNeeded: Bool {
|
||||
return UserDefaults.standard.bool(forKey: reauthenticationNeededKey)
|
||||
var showErrorToUser: Bool {
|
||||
return showRegistrationError ||
|
||||
showGenericError
|
||||
}
|
||||
|
||||
var showGenericError: Bool {
|
||||
return UserDefaults.standard.bool(forKey: showGeolockErrorKey)
|
||||
}
|
||||
|
||||
var showRegistrationError: Bool {
|
||||
return UserDefaults.standard.bool(forKey: reauthenticationNeededKey)
|
||||
}
|
||||
|
||||
var bluetoothStatusOn = true
|
||||
|
@ -222,7 +234,7 @@ class HomeViewController: UIViewController, HomeDelegate {
|
|||
|
||||
func updateJWTKeychainAccess() {
|
||||
let hasUpdatedKeychainAccess = UserDefaults.standard.bool(forKey: "HasUpdatedKeychainAccess")
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
if (!hasUpdatedKeychainAccess) {
|
||||
if let jwt = keychain.get("JWT_TOKEN") {
|
||||
if (keychain.set(jwt, forKey: "JWT_TOKEN", withAccess: .accessibleAfterFirstUnlock)) {
|
||||
|
@ -272,6 +284,7 @@ class HomeViewController: UIViewController, HomeDelegate {
|
|||
self?.toggleShareView()
|
||||
self?.toggleStatisticsView()
|
||||
self?.toggleRegistrationNeededView()
|
||||
self?.toggleGenericErrorView()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -349,37 +362,41 @@ class HomeViewController: UIViewController, HomeDelegate {
|
|||
}
|
||||
|
||||
fileprivate func toggleUploadView() {
|
||||
toggleViewVisibility(view: self.uploadView, isVisible: !self.didUploadData && !self.registrationNeeded)
|
||||
toggleViewVisibility(view: self.uploadView, isVisible: !self.didUploadData && !self.showErrorToUser)
|
||||
}
|
||||
|
||||
fileprivate func toggleShareView() {
|
||||
toggleViewVisibility(view: shareView, isVisible: !registrationNeeded)
|
||||
toggleViewVisibility(view: shareView, isVisible: !showErrorToUser)
|
||||
}
|
||||
|
||||
fileprivate func toggleStatisticsView() {
|
||||
toggleViewVisibility(view: covidStatisticsSection, isVisible: !registrationNeeded)
|
||||
toggleViewVisibility(view: covidStatisticsSection, isVisible: !showErrorToUser)
|
||||
}
|
||||
|
||||
fileprivate func toggleHeaderView() {
|
||||
toggleViewVisibility(view: inactiveAppSectionView, isVisible: !self.allPermissionOn || registrationNeeded)
|
||||
toggleViewVisibility(view: inactiveSettingsContent, isVisible: !self.allPermissionOn && !registrationNeeded)
|
||||
toggleViewVisibility(view: activeAppSectionView, isVisible: self.allPermissionOn)
|
||||
toggleViewVisibility(view: inactiveAppSectionView, isVisible: !self.allPermissionOn || showErrorToUser)
|
||||
toggleViewVisibility(view: inactiveSettingsContent, isVisible: !self.allPermissionOn && !showErrorToUser)
|
||||
toggleViewVisibility(view: activeAppSectionView, isVisible: self.allPermissionOn && !showErrorToUser)
|
||||
}
|
||||
|
||||
fileprivate func toggleBluetoothStatusView() {
|
||||
toggleViewVisibility(view: bluetoothStatusOffView, isVisible: self.bluetoothPermissionOn && !self.bluetoothStatusOn && !registrationNeeded)
|
||||
toggleViewVisibility(view: bluetoothStatusOffView, isVisible: self.bluetoothPermissionOn && !self.bluetoothStatusOn && !showErrorToUser)
|
||||
}
|
||||
|
||||
fileprivate func toggleBluetoothPermissionStatusView() {
|
||||
toggleViewVisibility(view: bluetoothPermissionOffView, isVisible: !self.allPermissionOn && !self.bluetoothPermissionOn && !registrationNeeded)
|
||||
toggleViewVisibility(view: bluetoothPermissionOffView, isVisible: !self.allPermissionOn && !self.bluetoothPermissionOn && !showErrorToUser)
|
||||
}
|
||||
|
||||
fileprivate func toggleLocationPermissionStatusView() {
|
||||
toggleViewVisibility(view: locationPermissionsView, isVisible: !allPermissionOn && !locationPermissionOn && (bluetoothPermissionOn && bluetoothStatusOn) && !registrationNeeded)
|
||||
toggleViewVisibility(view: locationPermissionsView, isVisible: !allPermissionOn && !locationPermissionOn && (bluetoothPermissionOn && bluetoothStatusOn) && !showErrorToUser)
|
||||
}
|
||||
|
||||
fileprivate func toggleRegistrationNeededView() {
|
||||
toggleViewVisibility(view: inactiveTokenExpiredView, isVisible: registrationNeeded)
|
||||
toggleViewVisibility(view: inactiveTokenExpiredView, isVisible: showRegistrationError)
|
||||
}
|
||||
|
||||
fileprivate func toggleGenericErrorView() {
|
||||
toggleViewVisibility(view: inactiveGenericError, isVisible: showGenericError)
|
||||
}
|
||||
|
||||
func attemptTurnOnBluetooth() {
|
||||
|
|
|
@ -53,7 +53,7 @@ final class InfoViewController: UIViewController {
|
|||
silentNotificationsCountLabel.text = "\(UserDefaults.standard.integer(forKey: "debugSilentNotificationCount"))"
|
||||
apnTokenLabel.text = UserDefaults.standard.string(forKey: "deviceTokenForAPN")
|
||||
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateStyle = .short
|
||||
dateFormatter.timeStyle = .medium
|
||||
|
@ -92,7 +92,7 @@ final class InfoViewController: UIViewController {
|
|||
}
|
||||
|
||||
@IBAction func requestUploadOTP(_ sender: UIButton) {
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
guard let jwt = keychain.get("JWT_TOKEN") else {
|
||||
DLog("Error trying to upload when not logged in")
|
||||
return
|
||||
|
@ -199,7 +199,7 @@ final class InfoViewController: UIViewController {
|
|||
}
|
||||
|
||||
@IBAction func setReauthenticationNeeded(_ sender: Any) {
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
keychain.set("corruptedjwt", forKey: "JWT_TOKEN", withAccess: .accessibleAfterFirstUnlock)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ class InitialScreenViewController: UIViewController, EncounterDBMigrationProgres
|
|||
var migrationStart: Date?
|
||||
var isKeychainAvailable = false
|
||||
var isDisplayTimeElapsed = false
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
var giveupTimer: Timer?
|
||||
var initialDelayTimer: Timer?
|
||||
var migrationViewController: UIViewController?
|
||||
|
|
13
CovidSafe/KeychainSwift+Singleton.swift
Normal file
13
CovidSafe/KeychainSwift+Singleton.swift
Normal file
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// KeychainSwift+Singleton.swift
|
||||
// CovidSafe
|
||||
//
|
||||
// Copyright © 2021 Australian Government. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import KeychainSwift
|
||||
|
||||
extension KeychainSwift {
|
||||
static var shared = KeychainSwift()
|
||||
}
|
|
@ -240,7 +240,7 @@ class OTPViewController: UIViewController, RegistrationHandler {
|
|||
result(.WrongOTP)
|
||||
return
|
||||
}
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
keychain.set(tokenToStore, forKey: "JWT_TOKEN", withAccess: .accessibleAfterFirstUnlock)
|
||||
keychain.set(refreshToken, forKey: "REFRESH_TOKEN", withAccess: .accessibleAfterFirstUnlock)
|
||||
UserDefaults.standard.set(true, forKey: "HasUpdatedKeychainAccess")
|
||||
|
|
|
@ -135,12 +135,34 @@ class PhoneNumberViewController: UIViewController, UITextFieldDelegate, Registra
|
|||
self?.activityIndicator.stopAnimating()
|
||||
self?.getOTPButton.isEnabled = true
|
||||
if let error = error {
|
||||
|
||||
let alertMessage = error == .MaxRegistrationError ? "max_registrations".localizedString() : "PhoneVerificationErrorMessage".localizedString()
|
||||
|
||||
let errorAlert = UIAlertController(title: "PhoneVerificationErrorTitle".localizedString(),
|
||||
message: "PhoneVerificationErrorMessage".localizedString(),
|
||||
message: alertMessage,
|
||||
preferredStyle: .alert)
|
||||
errorAlert.addAction(UIAlertAction(title: "global_OK".localizedString(), style: .default, handler: { _ in
|
||||
DLog("Unable to verify phone number")
|
||||
}))
|
||||
if error == .MaxRegistrationError {
|
||||
errorAlert.addAction(UIAlertAction(title: "max_registrations_button1".localizedString(), style: .default, handler: { _ in
|
||||
DLog("Max registrations error, request deletion tapped")
|
||||
|
||||
let deleteUrl = URLHelper.getDataDeletionURL()
|
||||
guard let url = URL(string: deleteUrl) else {
|
||||
DLog("Unable to create url")
|
||||
return
|
||||
}
|
||||
|
||||
let safariVC = SFSafariViewController(url: url)
|
||||
self?.present(safariVC, animated: true, completion: nil)
|
||||
|
||||
}))
|
||||
errorAlert.addAction(UIAlertAction(title: "max_registration_button2".localizedString(), style: .default, handler: { _ in
|
||||
DLog("Max registrations error, close alert")
|
||||
}))
|
||||
} else {
|
||||
errorAlert.addAction(UIAlertAction(title: "global_OK".localizedString(), style: .default, handler: { _ in
|
||||
DLog("Unable to verify phone number")
|
||||
}))
|
||||
}
|
||||
self?.present(errorAlert, animated: true)
|
||||
DLog("Phone number verification error: \(error.localizedDescription)")
|
||||
return
|
||||
|
|
|
@ -21,7 +21,7 @@ class QuestionUploadDataViewController: UIViewController {
|
|||
// MARK: -
|
||||
|
||||
private func showUploadDataFlow() {
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
setIsLoading(true)
|
||||
guard let jwt = keychain.get("JWT_TOKEN") else {
|
||||
DLog("Error trying to upload when not logged in")
|
||||
|
|
|
@ -11,7 +11,7 @@ import KeychainSwift
|
|||
|
||||
class RegistrationIntroViewController: UIViewController {
|
||||
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
|
|
@ -64,7 +64,6 @@ class RegistrationSuccessViewController: UIViewController {
|
|||
if reauthenticating {
|
||||
dismiss(animated: true, completion: nil)
|
||||
} else {
|
||||
let homeVC = HomeViewController(nibName: "HomeView", bundle: nil)
|
||||
let tabVC = MainTabBarViewController()
|
||||
self.navigationController?.setViewControllers([tabVC], animated: true)
|
||||
}
|
||||
|
|
|
@ -62,4 +62,8 @@ struct URLHelper {
|
|||
return "\(getHelpURL())#location-permissions"
|
||||
}
|
||||
|
||||
static func getDataDeletionURL() -> String {
|
||||
return "https://covidsafe-form.service.gov.au"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import KeychainSwift
|
|||
final class UploadHelper {
|
||||
|
||||
public static func uploadEncounterData(pin: String?, _ result: @escaping (UploadResult, String?) -> Void) {
|
||||
let keychain = KeychainSwift()
|
||||
let keychain = KeychainSwift.shared
|
||||
|
||||
guard let managedContext = EncounterDB.shared.persistentContainer?.viewContext else {
|
||||
result(.Failed, "[001]")
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "";
|
||||
"action_continue" = "تابع";
|
||||
"action_report_an_issue" = "بلِّغ عن مشكلة";
|
||||
"action_upload_done" = "تمّ";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "كما يمكن أن تتأثر المصافحات بالعوامل البيئية، بما في ذلك:";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "";
|
||||
"global_back" = "رجوع";
|
||||
"global_close" = "إغلاق";
|
||||
"global_double_tap" = "أنقر مرتين للتصحيح";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "الموقع الجغرافي: معطّل";
|
||||
"location_off_description" = "يتطلب جهاز iphone الخاص بك تشغيل الموقع الجغرافي ليتمكن تطبيق COVIDSafe من العمل. لا يقوم تطبيق COVIDSafe بتتبّع بيانات الموقع الجغرافي أو تخزينها.";
|
||||
"main_restrictions" = "القيود الرئيسية";
|
||||
"max_registration_button2" = "";
|
||||
"max_registrations" = "";
|
||||
"max_registrations_button1" = "";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = "تحديث تطبيق COVIDSafe قيد الإنجاز. \n\nيُرجى التأكد من عدم إغلاق هاتفك إلى أن يتم اكتمال التحديث.";
|
||||
"minute" = "دقيقة";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "";
|
||||
"action_continue" = "Συνεχίστε";
|
||||
"action_report_an_issue" = "Αναφέρετε το πρόβλημα";
|
||||
"action_upload_done" = "Συνεχίστε";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "Οι χειραψίες μπορούν επίσης να επηρεαστούν από περιβαλλοντικούς παράγοντες, όπως:";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "";
|
||||
"global_back" = "Πίσω";
|
||||
"global_close" = "Κλείστε";
|
||||
"global_double_tap" = "πατήστε δύο φορές για επεξεργασία";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "Τοποθεσία: ΑΠΕΝΕΡΓΟΠΟΙΗΜΕΝΗ";
|
||||
"location_off_description" = "Το iPhone σας απαιτεί άδεια τοποθεσίας για να λειτουργήσει την COVIDSafe. Η COVIDSafe ΔΕΝ παρακολουθεί ούτε αποθηκεύει τα δεδομένα τοποθεσίας σας.";
|
||||
"main_restrictions" = "Κύριοι περιορισμοί";
|
||||
"max_registration_button2" = "";
|
||||
"max_registrations" = "";
|
||||
"max_registrations_button1" = "";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = "Η ενημέρωση της COVIDSafe συνεχίζεται. \n\nΒεβαιωθείτε ότι το τηλέφωνό σας δεν είναι απενεργοποιημένο έως ότου ολοκληρωθεί η ενημέρωση.";
|
||||
"minute" = "Λεπτό";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "Delete this app now";
|
||||
"action_continue" = "Continue";
|
||||
"action_report_an_issue" = "Report an issue";
|
||||
"action_upload_done" = "Done";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "Handshakes can also be affected by environmental factors, including:";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "From";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "You may be connected using an internet provider from outside Australia. This could happen when using international data roaming on a non-Australian SIM card.\n\nPlease connect to an Australian network or use a local Wi-Fi internet connection to continue.";
|
||||
"global_back" = "Back";
|
||||
"global_close" = "Close";
|
||||
"global_double_tap" = "double tap to edit";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "Location: OFF";
|
||||
"location_off_description" = "Your iPhone requires Location permission for COVIDSafe to work. COVIDSafe does NOT track or store your location data.";
|
||||
"main_restrictions" = "Main restrictions";
|
||||
"max_registration_button2" = "Cancel";
|
||||
"max_registrations" = "You've reached the limit to register using the same mobile number.\n\nTo use the same mobile number to register again, you must request to delete your current registration information.";
|
||||
"max_registrations_button1" = "Request deletion";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = " COVIDSafe update in progress. \n\n Please make sure you phone is not switched off until the update is complete.";
|
||||
"minute" = "Minute";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "";
|
||||
"action_continue" = "Continua";
|
||||
"action_report_an_issue" = "Segnala un problema";
|
||||
"action_upload_done" = "Eseguito";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "Anche le strette di mano possono essere influenzate da fattori ambientali:";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "";
|
||||
"global_back" = "Indietro";
|
||||
"global_close" = "Chiudi";
|
||||
"global_double_tap" = "Fai un doppio click per modificare";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "Posizione: OFF";
|
||||
"location_off_description" = "Il tuo iPhone richiede l'autorizzazione alla localizzazione affinché COVIDSafe funzioni. COVIDSafe NON memorizza né utilizza i dati relativi alla tua posizione.";
|
||||
"main_restrictions" = "Restrizioni principali";
|
||||
"max_registration_button2" = "";
|
||||
"max_registrations" = "";
|
||||
"max_registrations_button1" = "";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = "Aggiornamento COVIDSafe in corso. \n\nAssicurati che il cellulare non sia spento fino al completamento dell'aggiornamento.";
|
||||
"minute" = "Minuto";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "";
|
||||
"action_continue" = "계속";
|
||||
"action_report_an_issue" = "문제 신고하기";
|
||||
"action_upload_done" = "완료";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "다음과 같은 환경 요인 역시 블루투스 악수에 영향을 미칠 수 있습니다.";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "부터";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "";
|
||||
"global_back" = "뒤로";
|
||||
"global_close" = "닫기";
|
||||
"global_double_tap" = "두 번 탭해서 수정하세요";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "위치 서비스: 꺼짐";
|
||||
"location_off_description" = "COVIDSafe가 제대로 실행되기 위해서는 여러분의 아이폰에서 위치 서비스 기능을 허용해야 합니다. COVIDSafe는 여러분의 위치 정보를 추적하거나 저장하지 않습니다.";
|
||||
"main_restrictions" = "주요 규제 조치";
|
||||
"max_registration_button2" = "";
|
||||
"max_registrations" = "";
|
||||
"max_registrations_button1" = "";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = "COVIDSafe 업데이트 진행 중. \n\n업데이트가 완료될 때까지 휴대폰이 꺼지지 않도록 해주세요.";
|
||||
"minute" = "분";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "";
|
||||
"action_continue" = "ਜਾਰੀ ਰੱਖੋ";
|
||||
"action_report_an_issue" = "ਮੁੱਦੇ/ਮਸਲੇ ਬਾਰੇ ਰਿਪੋਰਟ ਕਰੋ|";
|
||||
"action_upload_done" = "ਕਰ ਦਿੱਤਾ";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "ਹੱਥ ਮਿਲਾਉਣੇ, ਵਾਤਾਵਰਣਕ ਕਾਰਕਾਂ ਦੁਆਰਾ ਵੀ ਪ੍ਰਭਾਵਤ ਹੋ ਸਕਦੇ ਹਨ, ਜਿੰਨ੍ਹਾਂ ਵਿੱਚ ਸ਼ਾਮਲ ਹਨ :";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "ਵੱਲੋਂ";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "";
|
||||
"global_back" = "ਪਿੱਛੇ";
|
||||
"global_close" = "ਬੰਦ ਕਰੋ";
|
||||
"global_double_tap" = "ਸੋਧਣ ਲਈ ਡਬਲ ਟੈਪ ਕਰੋ";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "ਲੋਕੇਸ਼ਨ: ਔਫ";
|
||||
"location_off_description" = "COVIDSafe ਕੰਮ ਕਰ ਸਕੇ, ਇਸ ਦੇ ਲਈ ਤੁਹਾਡੇ iPhone ਨੂੰ ਲੋਕੇਸ਼ਨ ਆਗਿਆ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। *COVIDSafe ਤੁਹਾਡੇ ਸਥਾਨਕ ਅੰਕੜਿਆਂ ਨੂੰ ਨਹੀਂ ਢੂੰਡਦਾ ਜਾਂ ਸੰਭਾਲਦਾ।*";
|
||||
"main_restrictions" = "ਮੁੱਖ ਪਾਬੰਦੀਆਂ";
|
||||
"max_registration_button2" = "";
|
||||
"max_registrations" = "";
|
||||
"max_registrations_button1" = "";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = "COVIDSafe ਅੱਪਡੇਟ ਚੱਲ ਰਿਹਾ ਹੈ। \n\nਕਿਰਪਾ ਕਰਕੇ ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡਾ ਫ਼ੋਨ ਤਦ ਤੱਕ ਬੰਦ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਜਦ ਤੱਕ ਅੱਪਡੇਟ ਪੂਰਾ ਨਹੀਂ ਹੋ ਜਾਂਦਾ।";
|
||||
"minute" = "ਮਿੰਟ";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "";
|
||||
"action_continue" = "Devam";
|
||||
"action_report_an_issue" = "Sorun bildir";
|
||||
"action_upload_done" = "Bitti";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "El sıkışmalar çevresel faktörlerden de etkilenebilir, örneğin:";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "";
|
||||
"global_back" = "Geri";
|
||||
"global_close" = "Kapat";
|
||||
"global_double_tap" = "düzeltme yapmak için iki defa tıklayınız";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "Konum: KAPALI";
|
||||
"location_off_description" = "iPhone’unuz, COVIDSafe’in çalışması için Konum iznine ihtiyaç duyar. COVIDSafe konum verilerinizi İZLEMEZ veya SAKLAMAZ.";
|
||||
"main_restrictions" = "Ana kısıtlamalar";
|
||||
"max_registration_button2" = "";
|
||||
"max_registrations" = "";
|
||||
"max_registrations_button1" = "";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = " COVIDSafe güncellemesi devam ediyor. \n\n Lütfen güncelleme tamamlanana kadar telefonunuzu kapatmayın.";
|
||||
"minute" = "Dakika";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "";
|
||||
"action_continue" = "Tiếp tục";
|
||||
"action_report_an_issue" = "Báo cáo sự cố";
|
||||
"action_upload_done" = "Hoàn tất";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "Chức năng bắt tay cũng có thể bị ảnh hưởng bởi các yếu tố môi trường, bao gồm:";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "";
|
||||
"global_back" = "Trở lại";
|
||||
"global_close" = "Đóng";
|
||||
"global_double_tap" = "nhấn đúp để chỉnh sửa";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "Vị trí: TẮT";
|
||||
"location_off_description" = "iPhone của bạn yêu cầu quyền truy cập Vị trí để COVIDSafe hoạt động. COVIDSafe KHÔNG theo dõi hoặc lưu trữ dữ liệu vị trí của bạn.";
|
||||
"main_restrictions" = "Những hạn chế chính";
|
||||
"max_registration_button2" = "";
|
||||
"max_registrations" = "";
|
||||
"max_registrations_button1" = "";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = "COVIDSafe trong tiến trình cập nhật. \n\nVui lòng đảm bảo điện thoại của bạn không bị tắt cho đến khi cập nhật hoàn tất.";
|
||||
"minute" = "Phút";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "";
|
||||
"action_continue" = "继续";
|
||||
"action_report_an_issue" = "报告问题";
|
||||
"action_upload_done" = "完成";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "蓝牙握手也会受到环境因素的影响,这些因素包括:";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "";
|
||||
"global_back" = "返回";
|
||||
"global_close" = "关闭";
|
||||
"global_double_tap" = "双击进行编辑";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "位置:关闭";
|
||||
"location_off_description" = "您的 iPhone 要求COVIDSafe 获得位置权限才能运行。COVIDSafe 不会跟踪或存储您的位置数据。";
|
||||
"main_restrictions" = "主要限制措施";
|
||||
"max_registration_button2" = "";
|
||||
"max_registrations" = "";
|
||||
"max_registrations_button1" = "";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = "COVIDSafe正在更新。 \n\n请保持开机状态直至更新完成。";
|
||||
"minute" = "分钟";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"[test]decommission_message" = "";
|
||||
"action_continue" = "繼續";
|
||||
"action_report_an_issue" = "報告問題";
|
||||
"action_upload_done" = "完成";
|
||||
|
@ -286,6 +287,8 @@
|
|||
"factors_intro_2" = "藍牙握手也可以受到環境因素影響,包括:";
|
||||
/* Example: "From 22 to 28 January 2021" */
|
||||
"from" = "";
|
||||
/* Error message for when a user tries to signup outside of Australia. */
|
||||
"geoblock_error_message" = "";
|
||||
"global_back" = "返回";
|
||||
"global_close" = "關閉";
|
||||
"global_double_tap" = "點觸兩次來編輯";
|
||||
|
@ -367,6 +370,9 @@
|
|||
"location_off" = "位置:關閉";
|
||||
"location_off_description" = "你的iPhone要求COVIDSafe獲得位置許可權才能正常運作。COVIDSafe不會跟蹤或者存儲你的位置資料。";
|
||||
"main_restrictions" = "主要限制措施";
|
||||
"max_registration_button2" = "";
|
||||
"max_registrations" = "";
|
||||
"max_registrations_button1" = "";
|
||||
/* Splash Screen */
|
||||
"migration_in_progress" = "正在更新 COVIDSafe。\n\n請保持開機狀態直至更新完成為止。";
|
||||
"minute" = "分鐘 ";
|
||||
|
|
5
Gemfile
Normal file
5
Gemfile
Normal file
|
@ -0,0 +1,5 @@
|
|||
source "https://rubygems.org"
|
||||
|
||||
gem "fastlane"
|
||||
gem 'cocoapods'
|
||||
gem 'shellwords'
|
269
Gemfile.lock
Normal file
269
Gemfile.lock
Normal file
|
@ -0,0 +1,269 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.3)
|
||||
activesupport (5.2.5)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
artifactory (3.0.15)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.1.1)
|
||||
aws-partitions (1.443.0)
|
||||
aws-sdk-core (3.113.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.239.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-kms (1.43.0)
|
||||
aws-sdk-core (~> 3, >= 3.112.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.93.0)
|
||||
aws-sdk-core (~> 3, >= 3.112.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sigv4 (1.2.3)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.4)
|
||||
claide (1.0.3)
|
||||
cocoapods (1.10.1)
|
||||
addressable (~> 2.6)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.10.1)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.4.0, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.4.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (>= 2.3.0, < 3.0)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.6.6)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (~> 1.4)
|
||||
xcodeproj (>= 1.19.0, < 2.0)
|
||||
cocoapods-core (1.10.1)
|
||||
activesupport (> 5.0, < 6)
|
||||
addressable (~> 2.6)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
netrc (~> 0.11)
|
||||
public_suffix
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.4)
|
||||
cocoapods-downloader (1.4.0)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.0)
|
||||
cocoapods-trunk (1.5.0)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored (1.2)
|
||||
colored2 (3.1.2)
|
||||
commander-fastlane (4.4.6)
|
||||
highline (~> 1.7.2)
|
||||
concurrent-ruby (1.1.8)
|
||||
declarative (0.0.20)
|
||||
declarative-option (0.1.0)
|
||||
digest-crc (0.6.3)
|
||||
rake (>= 12.0.0, < 14.0.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
dotenv (2.7.6)
|
||||
emoji_regex (3.2.2)
|
||||
escape (0.0.4)
|
||||
ethon (0.12.0)
|
||||
ffi (>= 1.3.0)
|
||||
excon (0.79.0)
|
||||
faraday (1.3.0)
|
||||
faraday-net_http (~> 1.0)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ruby2_keywords
|
||||
faraday-cookie_jar (0.0.7)
|
||||
faraday (>= 0.8.0)
|
||||
http-cookie (~> 1.0.0)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday_middleware (1.0.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.3)
|
||||
fastlane (2.180.1)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.3, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
aws-sdk-s3 (~> 1.0)
|
||||
babosa (>= 1.0.3, < 2.0.0)
|
||||
bundler (>= 1.12.0, < 3.0.0)
|
||||
colored
|
||||
commander-fastlane (>= 4.4.6, < 5.0.0)
|
||||
dotenv (>= 2.1.1, < 3.0.0)
|
||||
emoji_regex (>= 0.1, < 4.0)
|
||||
excon (>= 0.71.0, < 1.0.0)
|
||||
faraday (~> 1.0)
|
||||
faraday-cookie_jar (~> 0.0.6)
|
||||
faraday_middleware (~> 1.0)
|
||||
fastimage (>= 2.1.0, < 3.0.0)
|
||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||
google-api-client (>= 0.37.0, < 0.39.0)
|
||||
google-cloud-storage (>= 1.15.0, < 2.0.0)
|
||||
highline (>= 1.7.2, < 2.0.0)
|
||||
json (< 3.0.0)
|
||||
jwt (>= 2.1.0, < 3)
|
||||
mini_magick (>= 4.9.4, < 5.0.0)
|
||||
multipart-post (~> 2.0.0)
|
||||
naturally (~> 2.2)
|
||||
plist (>= 3.1.0, < 4.0.0)
|
||||
rubyzip (>= 2.0.0, < 3.0.0)
|
||||
security (= 0.1.3)
|
||||
simctl (~> 1.6.3)
|
||||
slack-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-table (>= 1.4.5, < 2.0.0)
|
||||
tty-screen (>= 0.6.3, < 1.0.0)
|
||||
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||
word_wrap (~> 1.0.0)
|
||||
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||
xcpretty (~> 0.3.0)
|
||||
xcpretty-travis-formatter (>= 0.0.3)
|
||||
ffi (1.15.0)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
google-api-client (0.38.0)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (~> 0.9)
|
||||
httpclient (>= 2.8.1, < 3.0)
|
||||
mini_mime (~> 1.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
signet (~> 0.12)
|
||||
google-apis-core (0.3.0)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (~> 0.14)
|
||||
httpclient (>= 2.8.1, < 3.0)
|
||||
mini_mime (~> 1.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
rexml
|
||||
signet (~> 0.14)
|
||||
webrick
|
||||
google-apis-iamcredentials_v1 (0.3.0)
|
||||
google-apis-core (~> 0.1)
|
||||
google-apis-storage_v1 (0.3.0)
|
||||
google-apis-core (~> 0.1)
|
||||
google-cloud-core (1.6.0)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.5.0)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
google-cloud-errors (1.1.0)
|
||||
google-cloud-storage (1.31.0)
|
||||
addressable (~> 2.5)
|
||||
digest-crc (~> 0.4)
|
||||
google-apis-iamcredentials_v1 (~> 0.1)
|
||||
google-apis-storage_v1 (~> 0.1)
|
||||
google-cloud-core (~> 1.2)
|
||||
googleauth (~> 0.9)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (0.16.1)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (~> 0.14)
|
||||
highline (1.7.10)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.8.10)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jmespath (1.4.0)
|
||||
json (2.5.1)
|
||||
jwt (2.2.2)
|
||||
memoist (0.16.2)
|
||||
mini_magick (4.11.0)
|
||||
mini_mime (1.1.0)
|
||||
minitest (5.14.4)
|
||||
molinillo (0.6.6)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.0.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
naturally (2.2.1)
|
||||
netrc (0.11.0)
|
||||
os (1.1.1)
|
||||
plist (3.6.0)
|
||||
public_suffix (4.0.6)
|
||||
rake (13.0.3)
|
||||
representable (3.0.4)
|
||||
declarative (< 0.1.0)
|
||||
declarative-option (< 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.2)
|
||||
rexml (3.2.5)
|
||||
rouge (2.0.7)
|
||||
ruby-macho (1.4.0)
|
||||
ruby2_keywords (0.0.4)
|
||||
rubyzip (2.3.0)
|
||||
security (0.1.3)
|
||||
shellwords (0.1.0)
|
||||
signet (0.15.0)
|
||||
addressable (~> 2.3)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
multi_json (~> 1.10)
|
||||
simctl (1.6.8)
|
||||
CFPropertyList
|
||||
naturally
|
||||
slack-notifier (2.3.2)
|
||||
terminal-notifier (2.0.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thread_safe (0.3.6)
|
||||
tty-cursor (0.7.1)
|
||||
tty-screen (0.8.1)
|
||||
tty-spinner (0.9.3)
|
||||
tty-cursor (~> 0.7)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (1.2.9)
|
||||
thread_safe (~> 0.1)
|
||||
uber (0.1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
webrick (1.7.0)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.19.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
xcpretty (0.3.0)
|
||||
rouge (~> 2.0.7)
|
||||
xcpretty-travis-formatter (1.0.1)
|
||||
xcpretty (~> 0.2, >= 0.0.7)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods
|
||||
fastlane
|
||||
shellwords
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
8
Podfile
8
Podfile
|
@ -31,3 +31,11 @@ target 'CovidSafe-staging' do
|
|||
pod 'FlagKit'
|
||||
pod 'ReachabilitySwift'
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '10.0'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
12
Podfile.lock
12
Podfile.lock
|
@ -1,8 +1,8 @@
|
|||
PODS:
|
||||
- Alamofire (5.0.5)
|
||||
- Alamofire (5.4.0)
|
||||
- FlagKit (2.2)
|
||||
- KeychainSwift (19.0.0)
|
||||
- lottie-ios (3.1.6)
|
||||
- lottie-ios (3.1.9)
|
||||
- ReachabilitySwift (5.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
|
@ -21,12 +21,12 @@ SPEC REPOS:
|
|||
- ReachabilitySwift
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Alamofire: df2f8f826963b08b9a870791ad48e07a10090b2e
|
||||
Alamofire: 3b6a534a3df22db367e4dedeeca73d1ddfcf0e2f
|
||||
FlagKit: eca7dc89064b0c986302ba9acefad1bf80a435b1
|
||||
KeychainSwift: a06190cf933ad46b1e0abc3d77d29c06331715c7
|
||||
lottie-ios: 85ce835dd8c53e02509f20729fc7d6a4e6645a0a
|
||||
lottie-ios: 3a3758ef5a008e762faec9c9d50a39842f26d124
|
||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||
|
||||
PODFILE CHECKSUM: 5c536190b2facfc3f56594f2313066237ffac6ab
|
||||
PODFILE CHECKSUM: 3075a84136d3a2d8fde2aeecdc0d0c5147e0306f
|
||||
|
||||
COCOAPODS: 1.10.1
|
||||
COCOAPODS: 1.9.1
|
||||
|
|
6
fastlane/Appfile
Normal file
6
fastlane/Appfile
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
itc_team_id(<idhere>) # App Store Connect Team ID
|
||||
team_id(<portalTeamId>) # Developer Portal Team ID
|
||||
|
||||
# For more information about the Appfile, see:
|
||||
# https://docs.fastlane.tools/advanced/#appfile
|
96
fastlane/Fastfile
Normal file
96
fastlane/Fastfile
Normal file
|
@ -0,0 +1,96 @@
|
|||
# This file contains the fastlane.tools configuration
|
||||
# You can find the documentation at https://docs.fastlane.tools
|
||||
#
|
||||
# For a list of all available actions, check out
|
||||
#
|
||||
# https://docs.fastlane.tools/actions
|
||||
#
|
||||
# For a list of all available plugins, check out
|
||||
#
|
||||
# https://docs.fastlane.tools/plugins/available-plugins
|
||||
#
|
||||
|
||||
# Uncomment the line if you want fastlane to automatically update itself
|
||||
# update_fastlane
|
||||
|
||||
default_platform(:ios)
|
||||
|
||||
platform :ios do
|
||||
before_all do
|
||||
setup_circle_ci
|
||||
end
|
||||
|
||||
desc "Install UAT certificate (in CI)"
|
||||
lane :import_uat_distribution_certificate do
|
||||
|
||||
import_certificate(
|
||||
certificate_path: "Distribution_UAT.p12",
|
||||
certificate_password: ENV["DISTRIBUTION_UAT_P12_PASSWORD"] || "default",
|
||||
keychain_name: ENV["MATCH_KEYCHAIN_NAME"],
|
||||
keychain_password: ENV["MATCH_KEYCHAIN_PASSWORD"],
|
||||
)
|
||||
|
||||
install_provisioning_profile(path: "~/Library/MobileDevice/Provisioning\ Profiles/AppStore_UAT.mobileprovision")
|
||||
end
|
||||
|
||||
desc "Install PROD certificate (in CI)"
|
||||
lane :import_distribution_certificate do
|
||||
|
||||
import_certificate(
|
||||
certificate_path: "Distribution.p12",
|
||||
certificate_password: ENV["DISTRIBUTION_P12_PASSWORD"] || "default",
|
||||
keychain_name: ENV["MATCH_KEYCHAIN_NAME"],
|
||||
keychain_password: ENV["MATCH_KEYCHAIN_PASSWORD"],
|
||||
)
|
||||
|
||||
install_provisioning_profile(path: "~/Library/MobileDevice/Provisioning\ Profiles/AppStore.mobileprovision")
|
||||
end
|
||||
|
||||
desc "Push a new UAT build to TestFlight"
|
||||
lane :beta do
|
||||
|
||||
# To increment build number is recommended to use api_key
|
||||
# increment_build_number(
|
||||
# build_number: app_store_build_number + 1,
|
||||
# xcodeproj: "CovidSafe.xcodeproj"
|
||||
# )
|
||||
|
||||
gym(workspace: "CovidSafe.xcworkspace",
|
||||
scheme: "covid-staging",
|
||||
export_options: {
|
||||
method: "app-store",
|
||||
provisioningProfiles: {
|
||||
"au.gov.health.covidsafe.uat" => "CovidSafe UAT"
|
||||
}
|
||||
},
|
||||
configuration: "Release")
|
||||
|
||||
upload_to_testflight(apple_id: ENV["APPLE_ID_UAT"],
|
||||
skip_submission: true,
|
||||
skip_waiting_for_build_processing: true)
|
||||
end
|
||||
|
||||
desc "Push a new PROD build to TestFlight"
|
||||
lane :release do
|
||||
|
||||
# To increment build number is recommended to use api_key
|
||||
# increment_build_number(
|
||||
# build_number: app_store_build_number + 1,
|
||||
# xcodeproj: "CovidSafe.xcodeproj"
|
||||
# )
|
||||
|
||||
gym(workspace: "CovidSafe.xcworkspace",
|
||||
scheme: "covid-production",
|
||||
export_options: {
|
||||
method: "app-store",
|
||||
provisioningProfiles: {
|
||||
"au.gov.health.covidsafe" => "COVIDSafe"
|
||||
}
|
||||
},
|
||||
configuration: "Release")
|
||||
|
||||
upload_to_testflight(apple_id: ENV["APPLE_ID"],
|
||||
skip_submission: true,
|
||||
skip_waiting_for_build_processing: true)
|
||||
end
|
||||
end
|
24
fastlane/README.md
Normal file
24
fastlane/README.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
fastlane documentation
|
||||
================
|
||||
# Installation
|
||||
|
||||
Make sure you have the latest version of the Xcode command line tools installed:
|
||||
|
||||
```
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
Install _fastlane_ using
|
||||
```
|
||||
[sudo] gem install fastlane -NV
|
||||
```
|
||||
or alternatively using `brew install fastlane`
|
||||
|
||||
# Available Actions
|
||||
## iOS
|
||||
|
||||
- import_uat_distribution_certificate: This lane will decode and install the needed provisioning profile and signing certificate for the UAT build.
|
||||
- import_distribution_certificate: This lane will decode and install the needed provisioning profile and signing certificate for the PROD build.
|
||||
- beta: This lane will build and upload the UAT build to testflight
|
||||
- release: This lane will build and upload the PROD build to testflight
|
||||
|
Loading…
Reference in a new issue