From 83053e867e305c1a051caf91d1ce08f71a884eb1 Mon Sep 17 00:00:00 2001 From: Yannick Spreen Date: Mon, 3 May 2021 08:37:34 +0200 Subject: [PATCH] Add certificate list screens (#7) * Blue color scheme. * Add wallet viewer. * Add pages. * Add code prefetching. * Set brightness. * Add data model for certificate storage. * Add list. --- DGCAWallet.xcodeproj/project.pbxproj | 20 ++ DGCAWallet/Components/WalletCell.swift | 44 ++++ DGCAWallet/Models/LocalData.swift | 45 ++-- DGCAWallet/Services/Brightness.swift | 54 +++++ .../Storyboards/Base.lproj/Main.storyboard | 82 ++++++- .../Storyboards/CertificateViewer.storyboard | 202 ++++++++++++------ DGCAWallet/ViewControllers/CertCode.swift | 43 ++++ DGCAWallet/ViewControllers/CertPages.swift | 102 +++++++++ DGCAWallet/ViewControllers/CertTable.swift | 61 ++++++ .../ViewControllers/CertificateViewer.swift | 32 +-- DGCAWallet/ViewControllers/Home.swift | 2 + DGCAWallet/ViewControllers/List.swift | 93 +++++++- DGCAWallet/ViewControllers/Scan.swift | 19 +- 13 files changed, 653 insertions(+), 146 deletions(-) create mode 100644 DGCAWallet/Components/WalletCell.swift create mode 100644 DGCAWallet/Services/Brightness.swift create mode 100644 DGCAWallet/ViewControllers/CertCode.swift create mode 100644 DGCAWallet/ViewControllers/CertPages.swift create mode 100644 DGCAWallet/ViewControllers/CertTable.swift diff --git a/DGCAWallet.xcodeproj/project.pbxproj b/DGCAWallet.xcodeproj/project.pbxproj index 938f149..60e0541 100644 --- a/DGCAWallet.xcodeproj/project.pbxproj +++ b/DGCAWallet.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ CE13CF23262DDF810070C80E /* RoundedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE13CF22262DDF810070C80E /* RoundedButton.swift */; }; CE1D1EF6263597A2004C8919 /* LocalData.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1D1EF5263597A2004C8919 /* LocalData.swift */; }; CE1F155C2639F9E700736D48 /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = CE1F155B2639F9E700736D48 /* SwiftyJSON */; }; + CE260F56263DD1720083A200 /* WalletCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE260F55263DD1720083A200 /* WalletCell.swift */; }; CE37B643263867D700DEE13D /* SecureBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE37B642263867D700DEE13D /* SecureBackground.swift */; }; CE56B5052639F48E00FB31B1 /* SwiftDGC in Frameworks */ = {isa = PBXBuildFile; productRef = CE56B5042639F48E00FB31B1 /* SwiftDGC */; }; CE8096D9263B07BB00A65AD6 /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE8096D8263B07BB00A65AD6 /* UIColor.swift */; }; @@ -33,6 +34,10 @@ CEA6D70E261F8D2900715333 /* DGCAWalletUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA6D70D261F8D2900715333 /* DGCAWalletUITests.swift */; }; CED2726026398683003D47A9 /* UIFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED2725F26398683003D47A9 /* UIFont.swift */; }; CED949CA263B50CE00883558 /* List.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED949C9263B50CE00883558 /* List.swift */; }; + CEDABD40263C5FF4007A9B97 /* CertTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDABD3F263C5FF4007A9B97 /* CertTable.swift */; }; + CEDABD49263C70EF007A9B97 /* CertPages.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDABD48263C70EF007A9B97 /* CertPages.swift */; }; + CEE9DA55263C7D4000A31532 /* CertCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9DA54263C7D4000A31532 /* CertCode.swift */; }; + CEE9DA5D263C865200A31532 /* Brightness.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9DA5C263C865200A31532 /* Brightness.swift */; }; CEFAD87F262714C4009AFEF9 /* EHNTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFAD87E262714C4009AFEF9 /* EHNTests.swift */; }; /* End PBXBuildFile section */ @@ -59,6 +64,7 @@ CE13CF0E262DD0D80070C80E /* FullFloatingPanelLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullFloatingPanelLayout.swift; sourceTree = ""; }; CE13CF22262DDF810070C80E /* RoundedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedButton.swift; sourceTree = ""; }; CE1D1EF5263597A2004C8919 /* LocalData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalData.swift; sourceTree = ""; }; + CE260F55263DD1720083A200 /* WalletCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletCell.swift; sourceTree = ""; }; CE37B642263867D700DEE13D /* SecureBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackground.swift; sourceTree = ""; }; CE8096D8263B07BB00A65AD6 /* UIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = ""; }; CE891304263581D900CB92AF /* Home.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Home.swift; sourceTree = ""; }; @@ -82,8 +88,12 @@ CEA6D70F261F8D2900715333 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; CED2725F26398683003D47A9 /* UIFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFont.swift; sourceTree = ""; }; CED949C9263B50CE00883558 /* List.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = List.swift; sourceTree = ""; }; + CEDABD3F263C5FF4007A9B97 /* CertTable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CertTable.swift; sourceTree = ""; }; + CEDABD48263C70EF007A9B97 /* CertPages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CertPages.swift; sourceTree = ""; }; CEDCA7972639E6E700FCB83E /* SwiftDGC */ = {isa = PBXFileReference; lastKnownFileType = folder; name = SwiftDGC; path = "../dgca-app-core-ios"; sourceTree = ""; }; CEDCA79B2639E77800FCB83E /* Package.resolved */ = {isa = PBXFileReference; lastKnownFileType = text; name = Package.resolved; path = DGCAWallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved; sourceTree = SOURCE_ROOT; }; + CEE9DA54263C7D4000A31532 /* CertCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CertCode.swift; sourceTree = ""; }; + CEE9DA5C263C865200A31532 /* Brightness.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Brightness.swift; sourceTree = ""; }; CEFAD87E262714C4009AFEF9 /* EHNTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EHNTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -130,6 +140,7 @@ isa = PBXGroup; children = ( CE37B642263867D700DEE13D /* SecureBackground.swift */, + CEE9DA5C263C865200A31532 /* Brightness.swift */, ); path = Services; sourceTree = ""; @@ -149,7 +160,10 @@ CE13CF09262DCDDA0070C80E /* CertificateViewer.swift */, CED949C9263B50CE00883558 /* List.swift */, CEA6D6EF261F8D2700715333 /* Scan.swift */, + CEE9DA54263C7D4000A31532 /* CertCode.swift */, CE891304263581D900CB92AF /* Home.swift */, + CEDABD48263C70EF007A9B97 /* CertPages.swift */, + CEDABD3F263C5FF4007A9B97 /* CertTable.swift */, ); path = ViewControllers; sourceTree = ""; @@ -159,6 +173,7 @@ children = ( CE13CF0E262DD0D80070C80E /* FullFloatingPanelLayout.swift */, CE13CF22262DDF810070C80E /* RoundedButton.swift */, + CE260F55263DD1720083A200 /* WalletCell.swift */, CEA1556A262F784E0024B7AC /* SelfSizedTableView.swift */, CEA1556F262F79DE0024B7AC /* InfoCell.swift */, ); @@ -399,19 +414,24 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CEE9DA5D263C865200A31532 /* Brightness.swift in Sources */, CE13CF0A262DCDDA0070C80E /* CertificateViewer.swift in Sources */, + CEDABD40263C5FF4007A9B97 /* CertTable.swift in Sources */, CE37B643263867D700DEE13D /* SecureBackground.swift in Sources */, CE13CF0F262DD0D80070C80E /* FullFloatingPanelLayout.swift in Sources */, CEA1556B262F784E0024B7AC /* SelfSizedTableView.swift in Sources */, CE8096D9263B07BB00A65AD6 /* UIColor.swift in Sources */, + CEDABD49263C70EF007A9B97 /* CertPages.swift in Sources */, CE1D1EF6263597A2004C8919 /* LocalData.swift in Sources */, CED2726026398683003D47A9 /* UIFont.swift in Sources */, + CEE9DA55263C7D4000A31532 /* CertCode.swift in Sources */, CEA1555D262F63B30024B7AC /* EuDgcSchema.swift in Sources */, CEA6D6F0261F8D2700715333 /* Scan.swift in Sources */, CE13CF23262DDF810070C80E /* RoundedButton.swift in Sources */, CEA6D6EC261F8D2700715333 /* AppDelegate.swift in Sources */, CE891305263581D900CB92AF /* Home.swift in Sources */, CEA15563262F6DAB0024B7AC /* CertViewerDelegate.swift in Sources */, + CE260F56263DD1720083A200 /* WalletCell.swift in Sources */, CEA15570262F79DE0024B7AC /* InfoCell.swift in Sources */, CED949CA263B50CE00883558 /* List.swift in Sources */, CEA6D6EE261F8D2700715333 /* SceneDelegate.swift in Sources */, diff --git a/DGCAWallet/Components/WalletCell.swift b/DGCAWallet/Components/WalletCell.swift new file mode 100644 index 0000000..cd45f28 --- /dev/null +++ b/DGCAWallet/Components/WalletCell.swift @@ -0,0 +1,44 @@ +/*- + * ---license-start + * eu-digital-green-certificates / dgca-wallet-app-ios + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ +// +// InfoCell.swift +// DGCAWallet +// +// Created by Yannick Spreen on 4/20/21. +// + +import UIKit +import SwiftDGC + +class WalletCell: UITableViewCell { + @IBOutlet weak var typeLabel: UILabel! + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var dateLabel: UILabel! + + func draw(_ dated: DatedCertString) { + guard let cert = dated.cert else { + return + } + + typeLabel.text = cert.certTypeString + nameLabel.text = cert.fullName + dateLabel.text = "scanned \(dated.date.dateString)" + } +} diff --git a/DGCAWallet/Models/LocalData.swift b/DGCAWallet/Models/LocalData.swift index 218f556..eb8d9dc 100644 --- a/DGCAWallet/Models/LocalData.swift +++ b/DGCAWallet/Models/LocalData.swift @@ -29,36 +29,28 @@ import Foundation import SwiftDGC -struct LocalData: Codable { - static var sharedInstance = LocalData() - - var encodedPublicKeys = [String: String]() - var resumeToken: String? - var lastFetch_: Date? - var lastFetch: Date { - get { - lastFetch_ ?? .init(timeIntervalSince1970: 0) - } - set(v) { - lastFetch_ = v - } +struct DatedCertString: Codable { + var date: Date + var certString: String + var cert: HCert? { + HCert(from: certString) } +} - mutating func add(encodedPublicKey: String) { - let kid = KID.from(encodedPublicKey) - let kidStr = KID.string(from: kid) - - encodedPublicKeys[kidStr] = encodedPublicKey - } +struct LocalData: Codable { + static var sharedInstance = LocalData() - static func set(resumeToken: String) { - sharedInstance.resumeToken = resumeToken - } + var certStrings = [DatedCertString]() public func save() { Self.storage.save(self) } + public static func add(_ cert: HCert) { + sharedInstance.certStrings.append(.init(date: Date(), certString: cert.payloadString)) + sharedInstance.save() + } + static let storage = SecureStorage() static func initialize(completion: @escaping () -> Void) { @@ -66,16 +58,9 @@ struct LocalData: Codable { guard let result = success else { return } - print("\(result.encodedPublicKeys.count) certs loaded.") + print("\(result.certStrings.count) certs loaded.") LocalData.sharedInstance = result completion() } - HCert.publicKeyStorageDelegate = LocalDataDelegate() - } -} - -struct LocalDataDelegate: PublicKeyStorageDelegate { - func getEncodedPublicKey(for kidStr: String) -> String? { - LocalData.sharedInstance.encodedPublicKeys[kidStr] } } diff --git a/DGCAWallet/Services/Brightness.swift b/DGCAWallet/Services/Brightness.swift new file mode 100644 index 0000000..be041d2 --- /dev/null +++ b/DGCAWallet/Services/Brightness.swift @@ -0,0 +1,54 @@ +// +/*- + * ---license-start + * eu-digital-green-certificates / dgca-wallet-app-ios + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ +// +// Brightness.swift +// DGCAWallet +// +// Created by Yannick Spreen on 4/30/21. +// + + +import Foundation +import UIKit + +struct Brightness { + static var fallback: CGFloat? + + static func setTo(_ val: CGFloat) { + UIScreen.main.brightness = val + } + + public static func forceFull() { + if fallback != nil { + return + } + fallback = UIScreen.main.brightness + setTo(1.0) + } + + public static func reset() { + guard let val = fallback else { + return + } + fallback = nil + setTo(val) + } +} diff --git a/DGCAWallet/Storyboards/Base.lproj/Main.storyboard b/DGCAWallet/Storyboards/Base.lproj/Main.storyboard index 2c1a764..d7e93d0 100644 --- a/DGCAWallet/Storyboards/Base.lproj/Main.storyboard +++ b/DGCAWallet/Storyboards/Base.lproj/Main.storyboard @@ -113,9 +113,14 @@ + + + + - + + + + + + + + + + + + - + - + diff --git a/DGCAWallet/Storyboards/CertificateViewer.storyboard b/DGCAWallet/Storyboards/CertificateViewer.storyboard index 0c53937..b77990a 100644 --- a/DGCAWallet/Storyboards/CertificateViewer.storyboard +++ b/DGCAWallet/Storyboards/CertificateViewer.storyboard @@ -6,6 +6,7 @@ + @@ -19,14 +20,14 @@ - +