mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 15:58:39 +09:00
Dactyloidae iOS initial commit
This commit is contained in:
parent
daa6179d22
commit
7154a0497e
2123 changed files with 197052 additions and 0 deletions
65
mobile/ios/Shared/KeychainCache.swift
Normal file
65
mobile/ios/Shared/KeychainCache.swift
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import Foundation
|
||||
import XCGLogger
|
||||
import SwiftKeychainWrapper
|
||||
import SwiftyJSON
|
||||
|
||||
private let log = Logger.keychainLogger
|
||||
|
||||
public protocol JSONLiteralConvertible {
|
||||
func asJSON() -> JSON
|
||||
}
|
||||
|
||||
open class KeychainCache<T: JSONLiteralConvertible> {
|
||||
open let branch: String
|
||||
open let label: String
|
||||
|
||||
open var value: T? {
|
||||
didSet {
|
||||
checkpoint()
|
||||
}
|
||||
}
|
||||
|
||||
public init(branch: String, label: String, value: T?) {
|
||||
self.branch = branch
|
||||
self.label = label
|
||||
self.value = value
|
||||
}
|
||||
|
||||
open class func fromBranch(_ branch: String, withLabel label: String?, withDefault defaultValue: T? = nil, factory: (JSON) -> T?) -> KeychainCache<T> {
|
||||
if let l = label {
|
||||
let key = "\(branch).\(l)"
|
||||
KeychainWrapper.sharedAppContainerKeychain.ensureStringItemAccessibility(.afterFirstUnlock, forKey: key)
|
||||
if let s = KeychainWrapper.sharedAppContainerKeychain.string(forKey: key) {
|
||||
if let t = factory(JSON(parseJSON: s)) {
|
||||
log.info("Read \(branch) from Keychain with label \(branch).\(l).")
|
||||
return KeychainCache(branch: branch, label: l, value: t)
|
||||
} else {
|
||||
log.warning("Found \(branch) in Keychain with label \(branch).\(l), but could not parse it.")
|
||||
}
|
||||
} else {
|
||||
log.warning("Did not find \(branch) in Keychain with label \(branch).\(l).")
|
||||
}
|
||||
} else {
|
||||
log.warning("Did not find \(branch) label in Keychain.")
|
||||
}
|
||||
// Fall through to missing.
|
||||
log.warning("Failed to read \(branch) from Keychain.")
|
||||
let label = label ?? Bytes.generateGUID()
|
||||
return KeychainCache(branch: branch, label: label, value: defaultValue)
|
||||
}
|
||||
|
||||
open func checkpoint() {
|
||||
log.info("Storing \(self.branch) in Keychain with label \(self.branch).\(self.label).")
|
||||
// TODO: PII logging.
|
||||
if let value = value,
|
||||
let jsonString = value.asJSON().stringValue() {
|
||||
KeychainWrapper.sharedAppContainerKeychain.set(jsonString, forKey: "\(branch).\(label)", withAccessibility: .afterFirstUnlock)
|
||||
} else {
|
||||
KeychainWrapper.sharedAppContainerKeychain.removeObject(forKey: "\(branch).\(label)")
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue