mirror of
https://github.com/metabolist/metatext.git
synced 2024-12-22 13:37:01 +00:00
Refactoring
This commit is contained in:
parent
bffcac49e9
commit
330d796442
8 changed files with 72 additions and 47 deletions
|
@ -11,7 +11,7 @@ private let devIdentityID = UUID(uuidString: "E621E1F8-C36C-495A-93FC-0C247A3E6E
|
||||||
private let devAccessToken = "DEVELOPMENT_ACCESS_TOKEN"
|
private let devAccessToken = "DEVELOPMENT_ACCESS_TOKEN"
|
||||||
|
|
||||||
extension Secrets {
|
extension Secrets {
|
||||||
static func fresh() -> Secrets { Secrets(keychain: FakeKeychain()) }
|
static func fresh() -> Secrets { Secrets(keychainService: MockKeychainService()) }
|
||||||
|
|
||||||
static let development: Secrets = {
|
static let development: Secrets = {
|
||||||
let secrets = Secrets.fresh()
|
let secrets = Secrets.fresh()
|
||||||
|
@ -25,7 +25,7 @@ extension Secrets {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Defaults {
|
extension Defaults {
|
||||||
static func fresh() -> Defaults { Defaults(userDefaults: FakeUserDefaults()) }
|
static func fresh() -> Defaults { Defaults(userDefaults: MockUserDefaults()) }
|
||||||
|
|
||||||
static let development: Defaults = {
|
static let development: Defaults = {
|
||||||
let preferences = Defaults.fresh()
|
let preferences = Defaults.fresh()
|
||||||
|
|
|
@ -2,18 +2,20 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
typealias FakeKeychain = [String: Data]
|
class MockKeychainService {
|
||||||
|
private var guts = [String: Data]()
|
||||||
extension FakeKeychain: KeychainType {
|
|
||||||
mutating func set(data: Data, forKey key: String) throws {
|
|
||||||
self[key] = data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func deleteData(key: String) throws {
|
extension MockKeychainService: KeychainServiceType {
|
||||||
self[key] = nil
|
func set(data: Data, forKey key: String) throws {
|
||||||
|
guts[key] = data
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteData(key: String) throws {
|
||||||
|
guts[key] = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getData(key: String) throws -> Data? {
|
func getData(key: String) throws -> Data? {
|
||||||
self[key]
|
guts[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
21
Development Assets/MockKeychainService.swift
Normal file
21
Development Assets/MockKeychainService.swift
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright © 2020 Metabolist. All rights reserved.
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class MockKeychainService {
|
||||||
|
private var items = [String: Data]()
|
||||||
|
}
|
||||||
|
|
||||||
|
extension MockKeychainService: KeychainServiceType {
|
||||||
|
func set(data: Data, forKey key: String) throws {
|
||||||
|
items[key] = data
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteData(key: String) throws {
|
||||||
|
items[key] = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getData(key: String) throws -> Data? {
|
||||||
|
items[key]
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class FakeUserDefaults: UserDefaults {
|
class MockUserDefaults: UserDefaults {
|
||||||
convenience init() {
|
convenience init() {
|
||||||
self.init(suiteName: Self.suiteName)!
|
self.init(suiteName: Self.suiteName)!
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,6 @@ class FakeUserDefaults: UserDefaults {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension FakeUserDefaults {
|
private extension MockUserDefaults {
|
||||||
private static let suiteName = "com.metatext.metabolist.fake-user-defaults"
|
private static let suiteName = "com.metatext.metabolist.mock-user-defaults"
|
||||||
}
|
}
|
|
@ -55,8 +55,8 @@
|
||||||
D04FD74224D4AA34007D572D /* DevelopmentModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04FD74124D4AA34007D572D /* DevelopmentModels.swift */; };
|
D04FD74224D4AA34007D572D /* DevelopmentModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04FD74124D4AA34007D572D /* DevelopmentModels.swift */; };
|
||||||
D04FD74324D4AA34007D572D /* DevelopmentModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04FD74124D4AA34007D572D /* DevelopmentModels.swift */; };
|
D04FD74324D4AA34007D572D /* DevelopmentModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04FD74124D4AA34007D572D /* DevelopmentModels.swift */; };
|
||||||
D052BBC724D749C800A80A7A /* RootViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBC624D749C800A80A7A /* RootViewModelTests.swift */; };
|
D052BBC724D749C800A80A7A /* RootViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBC624D749C800A80A7A /* RootViewModelTests.swift */; };
|
||||||
D052BBCA24D74C9200A80A7A /* FakeUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBC824D74B6400A80A7A /* FakeUserDefaults.swift */; };
|
D052BBCA24D74C9200A80A7A /* MockUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBC824D74B6400A80A7A /* MockUserDefaults.swift */; };
|
||||||
D052BBCB24D74C9300A80A7A /* FakeUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBC824D74B6400A80A7A /* FakeUserDefaults.swift */; };
|
D052BBCB24D74C9300A80A7A /* MockUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBC824D74B6400A80A7A /* MockUserDefaults.swift */; };
|
||||||
D052BBCF24D750C000A80A7A /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBCE24D750C000A80A7A /* Defaults.swift */; };
|
D052BBCF24D750C000A80A7A /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBCE24D750C000A80A7A /* Defaults.swift */; };
|
||||||
D052BBD024D750C000A80A7A /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBCE24D750C000A80A7A /* Defaults.swift */; };
|
D052BBD024D750C000A80A7A /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBCE24D750C000A80A7A /* Defaults.swift */; };
|
||||||
D052BBD124D750CA00A80A7A /* AppEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBCC24D750A100A80A7A /* AppEnvironment.swift */; };
|
D052BBD124D750CA00A80A7A /* AppEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D052BBCC24D750A100A80A7A /* AppEnvironment.swift */; };
|
||||||
|
@ -134,12 +134,12 @@
|
||||||
D0DC175C24D0154F00A75C65 /* MastodonAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC175A24D0154F00A75C65 /* MastodonAPI.swift */; };
|
D0DC175C24D0154F00A75C65 /* MastodonAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC175A24D0154F00A75C65 /* MastodonAPI.swift */; };
|
||||||
D0DC175F24D016EA00A75C65 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = D0DC175E24D016EA00A75C65 /* Alamofire */; };
|
D0DC175F24D016EA00A75C65 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = D0DC175E24D016EA00A75C65 /* Alamofire */; };
|
||||||
D0DC176124D0171800A75C65 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = D0DC176024D0171800A75C65 /* Alamofire */; };
|
D0DC176124D0171800A75C65 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = D0DC176024D0171800A75C65 /* Alamofire */; };
|
||||||
D0DC177424D0B58800A75C65 /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC177324D0B58800A75C65 /* Keychain.swift */; };
|
D0DC177724D0CF2600A75C65 /* MockKeychainService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC177624D0CF2600A75C65 /* MockKeychainService.swift */; };
|
||||||
D0DC177524D0B58800A75C65 /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC177324D0B58800A75C65 /* Keychain.swift */; };
|
D0DC177824D0CF2600A75C65 /* MockKeychainService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC177624D0CF2600A75C65 /* MockKeychainService.swift */; };
|
||||||
D0DC177724D0CF2600A75C65 /* FakeKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC177624D0CF2600A75C65 /* FakeKeychain.swift */; };
|
|
||||||
D0DC177824D0CF2600A75C65 /* FakeKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DC177624D0CF2600A75C65 /* FakeKeychain.swift */; };
|
|
||||||
D0EC8DC224DF7D9C00A08489 /* IdentityService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0EC8DC124DF7D9C00A08489 /* IdentityService.swift */; };
|
D0EC8DC224DF7D9C00A08489 /* IdentityService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0EC8DC124DF7D9C00A08489 /* IdentityService.swift */; };
|
||||||
D0EC8DC324DF7D9C00A08489 /* IdentityService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0EC8DC124DF7D9C00A08489 /* IdentityService.swift */; };
|
D0EC8DC324DF7D9C00A08489 /* IdentityService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0EC8DC124DF7D9C00A08489 /* IdentityService.swift */; };
|
||||||
|
D0EC8DC524DF842700A08489 /* KeychainService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0EC8DC424DF842700A08489 /* KeychainService.swift */; };
|
||||||
|
D0EC8DC624DF842700A08489 /* KeychainService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0EC8DC424DF842700A08489 /* KeychainService.swift */; };
|
||||||
D0ED1B6E24CE100C00B4899C /* AddIdentityViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0ED1B6D24CE100C00B4899C /* AddIdentityViewModelTests.swift */; };
|
D0ED1B6E24CE100C00B4899C /* AddIdentityViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0ED1B6D24CE100C00B4899C /* AddIdentityViewModelTests.swift */; };
|
||||||
D0ED1BB724CE47F400B4899C /* WebAuthSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0ED1BB624CE47F400B4899C /* WebAuthSession.swift */; };
|
D0ED1BB724CE47F400B4899C /* WebAuthSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0ED1BB624CE47F400B4899C /* WebAuthSession.swift */; };
|
||||||
D0ED1BB824CE47F400B4899C /* WebAuthSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0ED1BB624CE47F400B4899C /* WebAuthSession.swift */; };
|
D0ED1BB824CE47F400B4899C /* WebAuthSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0ED1BB624CE47F400B4899C /* WebAuthSession.swift */; };
|
||||||
|
@ -204,7 +204,7 @@
|
||||||
D04FD73B24D4A83A007D572D /* InstanceEndpoint+Stubbing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InstanceEndpoint+Stubbing.swift"; sourceTree = "<group>"; };
|
D04FD73B24D4A83A007D572D /* InstanceEndpoint+Stubbing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "InstanceEndpoint+Stubbing.swift"; sourceTree = "<group>"; };
|
||||||
D04FD74124D4AA34007D572D /* DevelopmentModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DevelopmentModels.swift; sourceTree = "<group>"; };
|
D04FD74124D4AA34007D572D /* DevelopmentModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DevelopmentModels.swift; sourceTree = "<group>"; };
|
||||||
D052BBC624D749C800A80A7A /* RootViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewModelTests.swift; sourceTree = "<group>"; };
|
D052BBC624D749C800A80A7A /* RootViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
D052BBC824D74B6400A80A7A /* FakeUserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeUserDefaults.swift; sourceTree = "<group>"; };
|
D052BBC824D74B6400A80A7A /* MockUserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUserDefaults.swift; sourceTree = "<group>"; };
|
||||||
D052BBCC24D750A100A80A7A /* AppEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppEnvironment.swift; sourceTree = "<group>"; };
|
D052BBCC24D750A100A80A7A /* AppEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppEnvironment.swift; sourceTree = "<group>"; };
|
||||||
D052BBCE24D750C000A80A7A /* Defaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Defaults.swift; sourceTree = "<group>"; };
|
D052BBCE24D750C000A80A7A /* Defaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Defaults.swift; sourceTree = "<group>"; };
|
||||||
D065F53A24D3B33A00741304 /* View+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extensions.swift"; sourceTree = "<group>"; };
|
D065F53A24D3B33A00741304 /* View+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -242,9 +242,9 @@
|
||||||
D0DC175424D00F0A00A75C65 /* AccessTokenEndpoint+Stubbing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccessTokenEndpoint+Stubbing.swift"; sourceTree = "<group>"; };
|
D0DC175424D00F0A00A75C65 /* AccessTokenEndpoint+Stubbing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccessTokenEndpoint+Stubbing.swift"; sourceTree = "<group>"; };
|
||||||
D0DC175724D0130800A75C65 /* HTTPStubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPStubs.swift; sourceTree = "<group>"; };
|
D0DC175724D0130800A75C65 /* HTTPStubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPStubs.swift; sourceTree = "<group>"; };
|
||||||
D0DC175A24D0154F00A75C65 /* MastodonAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonAPI.swift; sourceTree = "<group>"; };
|
D0DC175A24D0154F00A75C65 /* MastodonAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonAPI.swift; sourceTree = "<group>"; };
|
||||||
D0DC177324D0B58800A75C65 /* Keychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keychain.swift; sourceTree = "<group>"; };
|
D0DC177624D0CF2600A75C65 /* MockKeychainService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockKeychainService.swift; sourceTree = "<group>"; };
|
||||||
D0DC177624D0CF2600A75C65 /* FakeKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeKeychain.swift; sourceTree = "<group>"; };
|
|
||||||
D0EC8DC124DF7D9C00A08489 /* IdentityService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdentityService.swift; sourceTree = "<group>"; };
|
D0EC8DC124DF7D9C00A08489 /* IdentityService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdentityService.swift; sourceTree = "<group>"; };
|
||||||
|
D0EC8DC424DF842700A08489 /* KeychainService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainService.swift; sourceTree = "<group>"; };
|
||||||
D0ED1B6D24CE100C00B4899C /* AddIdentityViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddIdentityViewModelTests.swift; sourceTree = "<group>"; };
|
D0ED1B6D24CE100C00B4899C /* AddIdentityViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddIdentityViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
D0ED1BB624CE47F400B4899C /* WebAuthSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebAuthSession.swift; sourceTree = "<group>"; };
|
D0ED1BB624CE47F400B4899C /* WebAuthSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebAuthSession.swift; sourceTree = "<group>"; };
|
||||||
D0ED1BC024CED48800B4899C /* HTTPClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPClient.swift; sourceTree = "<group>"; };
|
D0ED1BC024CED48800B4899C /* HTTPClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPClient.swift; sourceTree = "<group>"; };
|
||||||
|
@ -350,6 +350,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D0EC8DC124DF7D9C00A08489 /* IdentityService.swift */,
|
D0EC8DC124DF7D9C00A08489 /* IdentityService.swift */,
|
||||||
|
D0EC8DC424DF842700A08489 /* KeychainService.swift */,
|
||||||
);
|
);
|
||||||
path = Services;
|
path = Services;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -437,7 +438,6 @@
|
||||||
D0666A5324C6C3E500F3F04B /* Emoji.swift */,
|
D0666A5324C6C3E500F3F04B /* Emoji.swift */,
|
||||||
D0666A4A24C6C37700F3F04B /* Identity.swift */,
|
D0666A4A24C6C37700F3F04B /* Identity.swift */,
|
||||||
D0666A4D24C6C39600F3F04B /* Instance.swift */,
|
D0666A4D24C6C39600F3F04B /* Instance.swift */,
|
||||||
D0DC177324D0B58800A75C65 /* Keychain.swift */,
|
|
||||||
D0ED1BE224CFA84400B4899C /* MastodonError.swift */,
|
D0ED1BE224CFA84400B4899C /* MastodonError.swift */,
|
||||||
D0CD847224DBDEC700CF380C /* MastodonPreferences.swift */,
|
D0CD847224DBDEC700CF380C /* MastodonPreferences.swift */,
|
||||||
D0666A7124C6E0D300F3F04B /* Secrets.swift */,
|
D0666A7124C6E0D300F3F04B /* Secrets.swift */,
|
||||||
|
@ -536,8 +536,8 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D04FD74124D4AA34007D572D /* DevelopmentModels.swift */,
|
D04FD74124D4AA34007D572D /* DevelopmentModels.swift */,
|
||||||
D0DC177624D0CF2600A75C65 /* FakeKeychain.swift */,
|
D0DC177624D0CF2600A75C65 /* MockKeychainService.swift */,
|
||||||
D052BBC824D74B6400A80A7A /* FakeUserDefaults.swift */,
|
D052BBC824D74B6400A80A7A /* MockUserDefaults.swift */,
|
||||||
D0DC175724D0130800A75C65 /* HTTPStubs.swift */,
|
D0DC175724D0130800A75C65 /* HTTPStubs.swift */,
|
||||||
D0DC174824CFF13700A75C65 /* Mastodon API Stubs */,
|
D0DC174824CFF13700A75C65 /* Mastodon API Stubs */,
|
||||||
D0DC174C24CFF1F100A75C65 /* Stubbing.swift */,
|
D0DC174C24CFF1F100A75C65 /* Stubbing.swift */,
|
||||||
|
@ -783,13 +783,14 @@
|
||||||
D0DC175524D00F0A00A75C65 /* AccessTokenEndpoint+Stubbing.swift in Sources */,
|
D0DC175524D00F0A00A75C65 /* AccessTokenEndpoint+Stubbing.swift in Sources */,
|
||||||
D0B23F0D24D210E90066F411 /* NSError+Extensions.swift in Sources */,
|
D0B23F0D24D210E90066F411 /* NSError+Extensions.swift in Sources */,
|
||||||
D019E6D924DF728400697C7D /* MastodonDecoder.swift in Sources */,
|
D019E6D924DF728400697C7D /* MastodonDecoder.swift in Sources */,
|
||||||
D052BBCA24D74C9200A80A7A /* FakeUserDefaults.swift in Sources */,
|
D052BBCA24D74C9200A80A7A /* MockUserDefaults.swift in Sources */,
|
||||||
D0DC175224D008E300A75C65 /* MastodonTarget+Stubbing.swift in Sources */,
|
D0DC175224D008E300A75C65 /* MastodonTarget+Stubbing.swift in Sources */,
|
||||||
D0BEC94A24CA231200E864C4 /* TimelineView.swift in Sources */,
|
D0BEC94A24CA231200E864C4 /* TimelineView.swift in Sources */,
|
||||||
D0BEC93B24C96FD500E864C4 /* RootView.swift in Sources */,
|
D0BEC93B24C96FD500E864C4 /* RootView.swift in Sources */,
|
||||||
D04FD74224D4AA34007D572D /* DevelopmentModels.swift in Sources */,
|
D04FD74224D4AA34007D572D /* DevelopmentModels.swift in Sources */,
|
||||||
|
D0EC8DC524DF842700A08489 /* KeychainService.swift in Sources */,
|
||||||
D0DC175824D0130800A75C65 /* HTTPStubs.swift in Sources */,
|
D0DC175824D0130800A75C65 /* HTTPStubs.swift in Sources */,
|
||||||
D0DC177724D0CF2600A75C65 /* FakeKeychain.swift in Sources */,
|
D0DC177724D0CF2600A75C65 /* MockKeychainService.swift in Sources */,
|
||||||
D0EC8DC224DF7D9C00A08489 /* IdentityService.swift in Sources */,
|
D0EC8DC224DF7D9C00A08489 /* IdentityService.swift in Sources */,
|
||||||
D0C963FB24CC359D003BD330 /* AlertItem.swift in Sources */,
|
D0C963FB24CC359D003BD330 /* AlertItem.swift in Sources */,
|
||||||
D0DC174624CFEC2000A75C65 /* StubbingURLProtocol.swift in Sources */,
|
D0DC174624CFEC2000A75C65 /* StubbingURLProtocol.swift in Sources */,
|
||||||
|
@ -802,7 +803,6 @@
|
||||||
D0091B6E24DD68090040E8D2 /* PreferencesView.swift in Sources */,
|
D0091B6E24DD68090040E8D2 /* PreferencesView.swift in Sources */,
|
||||||
D0159F8F24DE743700E78478 /* IdentitiesView.swift in Sources */,
|
D0159F8F24DE743700E78478 /* IdentitiesView.swift in Sources */,
|
||||||
D0DB6EF424C5228A00D965FE /* AddIdentityView.swift in Sources */,
|
D0DB6EF424C5228A00D965FE /* AddIdentityView.swift in Sources */,
|
||||||
D0DC177424D0B58800A75C65 /* Keychain.swift in Sources */,
|
|
||||||
D074577724D29006004758DB /* StubbingWebAuthSession.swift in Sources */,
|
D074577724D29006004758DB /* StubbingWebAuthSession.swift in Sources */,
|
||||||
D0159FA524DE989700E78478 /* NSMutableAttributedString+Extensions.swift in Sources */,
|
D0159FA524DE989700E78478 /* NSMutableAttributedString+Extensions.swift in Sources */,
|
||||||
D0ED1BCE24CF768200B4899C /* MastodonEndpoint.swift in Sources */,
|
D0ED1BCE24CF768200B4899C /* MastodonEndpoint.swift in Sources */,
|
||||||
|
@ -855,7 +855,7 @@
|
||||||
D019E6E424DF72E700697C7D /* PreferencesEndpoint.swift in Sources */,
|
D019E6E424DF72E700697C7D /* PreferencesEndpoint.swift in Sources */,
|
||||||
D0DC175624D00F0A00A75C65 /* AccessTokenEndpoint+Stubbing.swift in Sources */,
|
D0DC175624D00F0A00A75C65 /* AccessTokenEndpoint+Stubbing.swift in Sources */,
|
||||||
D0B23F0E24D210E90066F411 /* NSError+Extensions.swift in Sources */,
|
D0B23F0E24D210E90066F411 /* NSError+Extensions.swift in Sources */,
|
||||||
D052BBCB24D74C9300A80A7A /* FakeUserDefaults.swift in Sources */,
|
D052BBCB24D74C9300A80A7A /* MockUserDefaults.swift in Sources */,
|
||||||
D0DC175324D008E300A75C65 /* MastodonTarget+Stubbing.swift in Sources */,
|
D0DC175324D008E300A75C65 /* MastodonTarget+Stubbing.swift in Sources */,
|
||||||
D0BEC94B24CA231200E864C4 /* TimelineView.swift in Sources */,
|
D0BEC94B24CA231200E864C4 /* TimelineView.swift in Sources */,
|
||||||
D0BEC93C24C96FD500E864C4 /* RootView.swift in Sources */,
|
D0BEC93C24C96FD500E864C4 /* RootView.swift in Sources */,
|
||||||
|
@ -863,7 +863,7 @@
|
||||||
D04FD74324D4AA34007D572D /* DevelopmentModels.swift in Sources */,
|
D04FD74324D4AA34007D572D /* DevelopmentModels.swift in Sources */,
|
||||||
D0DC175924D0130800A75C65 /* HTTPStubs.swift in Sources */,
|
D0DC175924D0130800A75C65 /* HTTPStubs.swift in Sources */,
|
||||||
D019E6DA24DF728400697C7D /* MastodonDecoder.swift in Sources */,
|
D019E6DA24DF728400697C7D /* MastodonDecoder.swift in Sources */,
|
||||||
D0DC177824D0CF2600A75C65 /* FakeKeychain.swift in Sources */,
|
D0DC177824D0CF2600A75C65 /* MockKeychainService.swift in Sources */,
|
||||||
D0C963FC24CC359D003BD330 /* AlertItem.swift in Sources */,
|
D0C963FC24CC359D003BD330 /* AlertItem.swift in Sources */,
|
||||||
D019E6E224DF72E700697C7D /* AppAuthorizationEndpoint.swift in Sources */,
|
D019E6E224DF72E700697C7D /* AppAuthorizationEndpoint.swift in Sources */,
|
||||||
D0DC174724CFEC2000A75C65 /* StubbingURLProtocol.swift in Sources */,
|
D0DC174724CFEC2000A75C65 /* StubbingURLProtocol.swift in Sources */,
|
||||||
|
@ -874,7 +874,6 @@
|
||||||
D0091B6F24DD68090040E8D2 /* PreferencesView.swift in Sources */,
|
D0091B6F24DD68090040E8D2 /* PreferencesView.swift in Sources */,
|
||||||
D0DB6EF524C5233E00D965FE /* AddIdentityView.swift in Sources */,
|
D0DB6EF524C5233E00D965FE /* AddIdentityView.swift in Sources */,
|
||||||
D019E6EA24DF72E700697C7D /* InstanceEndpoint.swift in Sources */,
|
D019E6EA24DF72E700697C7D /* InstanceEndpoint.swift in Sources */,
|
||||||
D0DC177524D0B58800A75C65 /* Keychain.swift in Sources */,
|
|
||||||
D0159F9C24DE748C00E78478 /* SidebarNavigationView.swift in Sources */,
|
D0159F9C24DE748C00E78478 /* SidebarNavigationView.swift in Sources */,
|
||||||
D019E6F124DF7C2F00697C7D /* DatabaseError.swift in Sources */,
|
D019E6F124DF7C2F00697C7D /* DatabaseError.swift in Sources */,
|
||||||
D074577824D29006004758DB /* StubbingWebAuthSession.swift in Sources */,
|
D074577824D29006004758DB /* StubbingWebAuthSession.swift in Sources */,
|
||||||
|
@ -889,6 +888,7 @@
|
||||||
D04FD73D24D4A83A007D572D /* InstanceEndpoint+Stubbing.swift in Sources */,
|
D04FD73D24D4A83A007D572D /* InstanceEndpoint+Stubbing.swift in Sources */,
|
||||||
D0DC175C24D0154F00A75C65 /* MastodonAPI.swift in Sources */,
|
D0DC175C24D0154F00A75C65 /* MastodonAPI.swift in Sources */,
|
||||||
D0ED1BD224CF779B00B4899C /* MastodonTarget.swift in Sources */,
|
D0ED1BD224CF779B00B4899C /* MastodonTarget.swift in Sources */,
|
||||||
|
D0EC8DC624DF842700A08489 /* KeychainService.swift in Sources */,
|
||||||
D0CD847D24DBEA9F00CF380C /* Unknowable.swift in Sources */,
|
D0CD847D24DBEA9F00CF380C /* Unknowable.swift in Sources */,
|
||||||
D0666A7024C6DFB300F3F04B /* AccessToken.swift in Sources */,
|
D0666A7024C6DFB300F3F04B /* AccessToken.swift in Sources */,
|
||||||
D0ED1BCC24CF744200B4899C /* MastodonClient.swift in Sources */,
|
D0ED1BCC24CF744200B4899C /* MastodonClient.swift in Sources */,
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct MetatextApp: App {
|
||||||
URLSessionConfiguration: .default,
|
URLSessionConfiguration: .default,
|
||||||
identityDatabase: identityDatabase,
|
identityDatabase: identityDatabase,
|
||||||
defaults: Defaults(userDefaults: .standard),
|
defaults: Defaults(userDefaults: .standard),
|
||||||
secrets: Secrets(keychain: Keychain(service: "com.metabolist.metatext")),
|
secrets: Secrets(keychainService: KeychainService(serviceName: "com.metabolist.metatext")),
|
||||||
webAuthSessionType: RealWebAuthSession.self)
|
webAuthSessionType: RealWebAuthSession.self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,10 @@ enum SecretsStorableError: Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Secrets {
|
class Secrets {
|
||||||
private var keychain: KeychainType
|
private let keychainService: KeychainServiceType
|
||||||
|
|
||||||
init(keychain: KeychainType) {
|
init(keychainService: KeychainServiceType) {
|
||||||
self.keychain = keychain
|
self.keychainService = keychainService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,17 +29,19 @@ extension Secrets {
|
||||||
|
|
||||||
extension Secrets {
|
extension Secrets {
|
||||||
func set(_ data: SecretsStorable, forItem item: Item, forIdentityID identityID: UUID) throws {
|
func set(_ data: SecretsStorable, forItem item: Item, forIdentityID identityID: UUID) throws {
|
||||||
try keychain.set(data: data.dataStoredInSecrets, forKey: Self.key(item: item, identityID: identityID))
|
try keychainService.set(data: data.dataStoredInSecrets, forKey: Self.key(item: item, identityID: identityID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func item<T: SecretsStorable>(_ item: Item, forIdentityID identityID: UUID) throws -> T? {
|
func item<T: SecretsStorable>(_ item: Item, forIdentityID identityID: UUID) throws -> T? {
|
||||||
guard let data = try keychain.getData(key: Self.key(item: item, identityID: identityID)) else { return nil }
|
guard let data = try keychainService.getData(key: Self.key(item: item, identityID: identityID)) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return try T.fromDataStoredInSecrets(data)
|
return try T.fromDataStoredInSecrets(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func delete(_ item: Item, forIdentityID identityID: UUID) throws {
|
func delete(_ item: Item, forIdentityID identityID: UUID) throws {
|
||||||
try keychain.deleteData(key: Self.key(item: item, identityID: identityID))
|
try keychainService.deleteData(key: Self.key(item: item, identityID: identityID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,18 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
protocol KeychainType {
|
protocol KeychainServiceType {
|
||||||
mutating func set(data: Data, forKey key: String) throws
|
func set(data: Data, forKey key: String) throws
|
||||||
mutating func deleteData(key: String) throws
|
func deleteData(key: String) throws
|
||||||
func getData(key: String) throws -> Data?
|
func getData(key: String) throws -> Data?
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Keychain {
|
struct KeychainService {
|
||||||
let service: String
|
let serviceName: String
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Keychain: KeychainType {
|
extension KeychainService: KeychainServiceType {
|
||||||
mutating func set(data: Data, forKey key: String) throws {
|
func set(data: Data, forKey key: String) throws {
|
||||||
var query = queryDictionary(key: key)
|
var query = queryDictionary(key: key)
|
||||||
|
|
||||||
query[kSecValueData as String] = data
|
query[kSecValueData as String] = data
|
||||||
|
@ -25,7 +25,7 @@ extension Keychain: KeychainType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func deleteData(key: String) throws {
|
func deleteData(key: String) throws {
|
||||||
let status = SecItemDelete(queryDictionary(key: key) as CFDictionary)
|
let status = SecItemDelete(queryDictionary(key: key) as CFDictionary)
|
||||||
|
|
||||||
if status != errSecSuccess {
|
if status != errSecSuccess {
|
||||||
|
@ -53,10 +53,10 @@ extension Keychain: KeychainType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension Keychain {
|
private extension KeychainService {
|
||||||
private func queryDictionary(key: String) -> [String: Any] {
|
private func queryDictionary(key: String) -> [String: Any] {
|
||||||
[
|
[
|
||||||
kSecAttrService as String: service,
|
kSecAttrService as String: serviceName,
|
||||||
kSecAttrAccount as String: key,
|
kSecAttrAccount as String: key,
|
||||||
kSecClass as String: kSecClassGenericPassword
|
kSecClass as String: kSecClassGenericPassword
|
||||||
]
|
]
|
Loading…
Reference in a new issue