Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
980f1c8f15
commit
2a63802b24
8
.gitignore
vendored
8
.gitignore
vendored
@ -2,5 +2,9 @@
|
|||||||
.build/
|
.build/
|
||||||
.swiftpm/
|
.swiftpm/
|
||||||
DerivedData/
|
DerivedData/
|
||||||
*.xcodeproj/project.xcworkspace/xcuserdata
|
|
||||||
*.xcodeproj/xcuserdata
|
# Xcode User Data
|
||||||
|
xcuserdata/
|
||||||
|
*.xcodeproj/project.xcworkspace/xcuserdata/
|
||||||
|
*.xcodeproj/xcuserdata/
|
||||||
|
*.xcworkspace/xcuserdata/
|
||||||
|
|||||||
@ -5,5 +5,6 @@ INFOPLIST_KEY_CFBundleDisplayName = SecureStorage
|
|||||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES
|
||||||
INFOPLIST_KEY_BaseBundleID = $(BASE_BUNDLE_ID)
|
INFOPLIST_KEY_BaseBundleID = $(BASE_BUNDLE_ID)
|
||||||
INFOPLIST_KEY_TeamID = $(TEAM_ID)
|
INFOPLIST_KEY_TeamID = $(TEAM_ID)
|
||||||
|
INFOPLIST_KEY_AppGroupID = $(APP_GROUP_ID)
|
||||||
|
|
||||||
CODE_SIGN_ENTITLEMENTS = SecureStorageSample/SecureStorageSample.entitlements
|
CODE_SIGN_ENTITLEMENTS = SecureStorageSample/SecureStorageSample.entitlements
|
||||||
|
|||||||
@ -8,5 +8,6 @@ WATCHOS_DEPLOYMENT_TARGET = 10.0
|
|||||||
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES
|
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES
|
||||||
INFOPLIST_KEY_BaseBundleID = $(BASE_BUNDLE_ID)
|
INFOPLIST_KEY_BaseBundleID = $(BASE_BUNDLE_ID)
|
||||||
INFOPLIST_KEY_TeamID = $(TEAM_ID)
|
INFOPLIST_KEY_TeamID = $(TEAM_ID)
|
||||||
|
INFOPLIST_KEY_AppGroupID = $(APP_GROUP_ID)
|
||||||
|
|
||||||
CODE_SIGN_ENTITLEMENTS = SecureStorageSample Watch App/SecureStorageSample Watch App.entitlements
|
CODE_SIGN_ENTITLEMENTS = SecureStorageSample Watch App/SecureStorageSample Watch App.entitlements
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import SharedKit
|
|||||||
@main
|
@main
|
||||||
struct SecureStorageSampleApp: App {
|
struct SecureStorageSampleApp: App {
|
||||||
init() {
|
init() {
|
||||||
|
StorageServiceIdentifiers.logConfiguration()
|
||||||
_ = WatchConnectivityService.shared
|
_ = WatchConnectivityService.shared
|
||||||
Task {
|
Task {
|
||||||
// 1. Global Encryption Configuration
|
// 1. Global Encryption Configuration
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import LocalData
|
import LocalData
|
||||||
|
|
||||||
|
@MainActor
|
||||||
struct EncryptedStorageDemo: View {
|
struct EncryptedStorageDemo: View {
|
||||||
@State private var logEntry = ""
|
@State private var logEntry = ""
|
||||||
@State private var storedLogs: [String] = []
|
@State private var storedLogs: [String] = []
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import SwiftUI
|
|||||||
import LocalData
|
import LocalData
|
||||||
import SharedKit
|
import SharedKit
|
||||||
|
|
||||||
|
@MainActor
|
||||||
struct FileSystemDemo: View {
|
struct FileSystemDemo: View {
|
||||||
@State private var profileName = ""
|
@State private var profileName = ""
|
||||||
@State private var profileEmail = ""
|
@State private var profileEmail = ""
|
||||||
@ -191,7 +192,14 @@ struct FileSystemDemo: View {
|
|||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
let key = StorageKeys.UserProfileFileKey(directory: selectedDirectory)
|
let key = StorageKeys.UserProfileFileKey(directory: selectedDirectory)
|
||||||
storedProfile = try await StorageRouter.shared.get(key)
|
let profile = try await StorageRouter.shared.get(key)
|
||||||
|
storedProfile = profile
|
||||||
|
|
||||||
|
// Sync to text fields
|
||||||
|
profileName = profile.name
|
||||||
|
profileEmail = profile.email
|
||||||
|
profileAge = profile.age.map(String.init) ?? ""
|
||||||
|
|
||||||
statusMessage = "✓ Loaded from file system"
|
statusMessage = "✓ Loaded from file system"
|
||||||
} catch StorageError.notFound {
|
} catch StorageError.notFound {
|
||||||
storedProfile = nil
|
storedProfile = nil
|
||||||
@ -243,7 +251,14 @@ struct FileSystemDemo: View {
|
|||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
let key = StorageKeys.AppGroupUserProfileKey(directory: selectedDirectory)
|
let key = StorageKeys.AppGroupUserProfileKey(directory: selectedDirectory)
|
||||||
appGroupProfile = try await StorageRouter.shared.get(key)
|
let profile = try await StorageRouter.shared.get(key)
|
||||||
|
appGroupProfile = profile
|
||||||
|
|
||||||
|
// Sync to text fields
|
||||||
|
profileName = profile.name
|
||||||
|
profileEmail = profile.email
|
||||||
|
profileAge = profile.age.map(String.init) ?? ""
|
||||||
|
|
||||||
appGroupStatusMessage = "✓ App Group loaded from file system"
|
appGroupStatusMessage = "✓ App Group loaded from file system"
|
||||||
} catch StorageError.notFound {
|
} catch StorageError.notFound {
|
||||||
appGroupProfile = nil
|
appGroupProfile = nil
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import LocalData
|
import LocalData
|
||||||
|
|
||||||
|
@MainActor
|
||||||
struct KeychainDemo: View {
|
struct KeychainDemo: View {
|
||||||
@State private var username = ""
|
@State private var username = ""
|
||||||
@State private var password = ""
|
@State private var password = ""
|
||||||
@ -141,6 +142,11 @@ struct KeychainDemo: View {
|
|||||||
)
|
)
|
||||||
let credential = try await StorageRouter.shared.get(key)
|
let credential = try await StorageRouter.shared.get(key)
|
||||||
storedCredential = "Username: \(credential.username)\nPassword: ****"
|
storedCredential = "Username: \(credential.username)\nPassword: ****"
|
||||||
|
|
||||||
|
// Sync to fields
|
||||||
|
username = credential.username
|
||||||
|
password = credential.password
|
||||||
|
|
||||||
statusMessage = "✓ Retrieved from Keychain"
|
statusMessage = "✓ Retrieved from Keychain"
|
||||||
} catch StorageError.notFound {
|
} catch StorageError.notFound {
|
||||||
storedCredential = ""
|
storedCredential = ""
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import LocalData
|
import LocalData
|
||||||
|
|
||||||
|
@MainActor
|
||||||
struct PlatformSyncDemo: View {
|
struct PlatformSyncDemo: View {
|
||||||
@State private var settingValue = ""
|
@State private var settingValue = ""
|
||||||
@State private var storedValue = ""
|
@State private var storedValue = ""
|
||||||
@ -181,7 +182,9 @@ struct PlatformSyncDemo: View {
|
|||||||
availability: selectedPlatform,
|
availability: selectedPlatform,
|
||||||
syncPolicy: selectedSync
|
syncPolicy: selectedSync
|
||||||
)
|
)
|
||||||
storedValue = try await StorageRouter.shared.get(key)
|
let value = try await StorageRouter.shared.get(key)
|
||||||
|
storedValue = value
|
||||||
|
settingValue = value // Sync to field
|
||||||
statusMessage = "✓ Loaded value"
|
statusMessage = "✓ Loaded value"
|
||||||
} catch StorageError.notFound {
|
} catch StorageError.notFound {
|
||||||
storedValue = ""
|
storedValue = ""
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import LocalData
|
import LocalData
|
||||||
|
|
||||||
|
@MainActor
|
||||||
struct UserDefaultsDemo: View {
|
struct UserDefaultsDemo: View {
|
||||||
@State private var inputText = ""
|
@State private var inputText = ""
|
||||||
@State private var storedValue = ""
|
@State private var storedValue = ""
|
||||||
@ -155,7 +156,9 @@ struct UserDefaultsDemo: View {
|
|||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
let key = StorageKeys.AppVersionKey()
|
let key = StorageKeys.AppVersionKey()
|
||||||
storedValue = try await StorageRouter.shared.get(key)
|
let value = try await StorageRouter.shared.get(key)
|
||||||
|
storedValue = value
|
||||||
|
inputText = value // Sync to field
|
||||||
statusMessage = "✓ Loaded successfully"
|
statusMessage = "✓ Loaded successfully"
|
||||||
} catch StorageError.notFound {
|
} catch StorageError.notFound {
|
||||||
storedValue = ""
|
storedValue = ""
|
||||||
@ -201,7 +204,9 @@ struct UserDefaultsDemo: View {
|
|||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
let key = StorageKeys.AppGroupUserDefaultsKey()
|
let key = StorageKeys.AppGroupUserDefaultsKey()
|
||||||
appGroupStoredValue = try await StorageRouter.shared.get(key)
|
let value = try await StorageRouter.shared.get(key)
|
||||||
|
appGroupStoredValue = value
|
||||||
|
inputText = value // Sync to field
|
||||||
statusMessage = "✓ App Group loaded successfully"
|
statusMessage = "✓ App Group loaded successfully"
|
||||||
} catch StorageError.notFound {
|
} catch StorageError.notFound {
|
||||||
appGroupStoredValue = ""
|
appGroupStoredValue = ""
|
||||||
|
|||||||
@ -2,9 +2,10 @@ import Foundation
|
|||||||
|
|
||||||
public enum StorageServiceIdentifiers {
|
public enum StorageServiceIdentifiers {
|
||||||
public static var bundleIdentifier: String {
|
public static var bundleIdentifier: String {
|
||||||
Bundle.main.object(forInfoDictionaryKey: "BaseBundleID") as? String ??
|
let identifier = Bundle.main.object(forInfoDictionaryKey: "BaseBundleID") as? String ??
|
||||||
Bundle.main.bundleIdentifier ??
|
Bundle.main.bundleIdentifier ??
|
||||||
"com.example.securestorage"
|
"com.example.securestorage"
|
||||||
|
return identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
private static var teamIDPrefix: String {
|
private static var teamIDPrefix: String {
|
||||||
@ -15,7 +16,17 @@ public enum StorageServiceIdentifiers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static var appGroupIdentifier: String {
|
public static var appGroupIdentifier: String {
|
||||||
"group.\(bundleIdentifier)"
|
let identifier = Bundle.main.object(forInfoDictionaryKey: "AppGroupID") as? String ??
|
||||||
|
"group.\(bundleIdentifier.lowercased())"
|
||||||
|
return identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func logConfiguration() {
|
||||||
|
Logger.debug("--- STORAGE CONFIGURATION ---")
|
||||||
|
Logger.debug("Bundle ID: \(bundleIdentifier)")
|
||||||
|
Logger.debug("Team ID Prefix: \(teamIDPrefix)")
|
||||||
|
Logger.debug("App Group ID: \(appGroupIdentifier)")
|
||||||
|
Logger.debug("---------------------------")
|
||||||
}
|
}
|
||||||
|
|
||||||
public static var keychainCredentials: String {
|
public static var keychainCredentials: String {
|
||||||
|
|||||||
@ -0,0 +1,26 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Public logging utility for the SecureStorage workspace.
|
||||||
|
public enum Logger {
|
||||||
|
public static var isLoggingEnabled = true
|
||||||
|
|
||||||
|
public static func debug(_ message: String) {
|
||||||
|
#if DEBUG
|
||||||
|
if isLoggingEnabled {
|
||||||
|
print(" {SECURE_STORAGE} ℹ️ \(message)")
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func error(_ message: String, error: Error? = nil) {
|
||||||
|
#if DEBUG
|
||||||
|
var logMessage = " {SECURE_STORAGE} ❌ \(message)"
|
||||||
|
if let error = error {
|
||||||
|
logMessage += " | Error: \(error.localizedDescription)"
|
||||||
|
}
|
||||||
|
if isLoggingEnabled {
|
||||||
|
print(logMessage)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user