Skip to content

SecureStorage is a Swift package that simplifies secure Keychain storage for Codable values with a type-safe property wrapper and protocol integration for SwiftUI.

License

Notifications You must be signed in to change notification settings

vlaminck/SecureStorage

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SecureStorage

SecureStorage is a Swift package that provides a simple, secure, and type-safe way to store, retrieve, and delete Codable values using Apple's Keychain. It is designed with SwiftUI in mind, offering a property wrapper (@SecStorage) for easy integration into your views, as well as a protocol-based approach (Securable) for managing secure persistence across your app.


Features

  • Property Wrapper (SecStorage)
    Easily wrap any Codable value for secure storage with minimal boilerplate code. Automatically encodes to and decodes from JSON when saving or retrieving data.

  • Securable Protocol
    Conform your types to the Securable protocol to gain default implementations for secure storage, retrieval, and clearing of persisted data.

  • Keychain Integration
    Leverages the Security framework to handle secure storage with methods for adding, retrieving, and deleting Keychain items.

  • Error Handling
    Provides a custom SecureStorageError enum to handle various error cases, such as encoding/decoding issues and Keychain operation failures.


Installation

Swift Package Manager

Add SecureStorage to your project by updating your Package.swift file:

dependencies: [
    .package(url: "https://github.com/oldgrowth-games/SecureStorage.git", from: "1.0.0")
]

Then, add "SecureStorage" as a dependency to your target:

.target(
    name: "YourTargetName",
    dependencies: ["SecureStorage"]
)

Alternatively, in Xcode, navigate to File > Add Package Dependencies... and enter the repository URL.


Usage

Using the @SecStorage Property Wrapper

Integrate secure storage directly into your SwiftUI views by annotating your properties with @SecStorage.

import SwiftUI
import SecureStorage

struct UserProfile: Codable {
    var username: String
    var email: String
}

struct ContentView: View {
    // "userProfile" is the key for secure storage.
    @SecStorage("userProfile") var userProfile: UserProfile?

    var body: some View {
        VStack {
            if let profile = userProfile {
                Text("Username: \(profile.username)")
                Text("Email: \(profile.email)")
            } else {
                Text("No user profile found.")
            }
        }
        .onAppear {
            // Example: Save a user profile if none exists.
            if userProfile == nil {
                userProfile = UserProfile(username: "JohnDoe", email: "john.doe@example.com")
            }
        }
    }
}

Conforming to the Securable Protocol

For more complex data types or when you need custom storage logic, conform your Codable type to Securable.

import SecureStorage

struct User: Codable, Securable {
    // Unique key for secure storage.
    var securableKey: String { "currentUser" }
    
    var name: String
    var age: Int
}

// Storing the user:
let user = User(name: "Jane Doe", age: 28)
user.store()

// Retrieving the user:
do {
    let storedUser = try User(securableKey: "currentUser")
    print("Retrieved User: \(storedUser.name)")
} catch {
    print("Error retrieving user: \(error)")
}

// Clearing the stored data:
user.clear()

API Overview

SecStorage<T: Codable>

A property wrapper that provides a convenient interface for storing and retrieving Codable values using a unique key.

  • wrappedValue: Automatically encodes/decodes the value to/from JSON stored in the Keychain.

Securable Protocol

Defines a contract for securely persisting data. Types conforming to Securable are required to provide a unique key and gain default implementations for:

  • Initialization: Retrieve and decode stored data.
  • Store: Encode and save the instance securely.
  • Clear: Delete the stored data from the Keychain.

SecureStorage

A utility struct that wraps the Keychain operations:

  • store(key:value:): Stores a Codable value by encoding it as JSON.
  • store(key:data:): Stores raw Data.
  • retrieve(key:): Retrieves stored data.
  • delete(key:): Deletes data associated with the given key.

SecureStorageError

An error enumeration that encapsulates various errors which may occur during secure storage operations:

  • codable(Error): Errors during encoding/decoding.
  • itemDelete(OSStatus): Errors when deleting a Keychain item.
  • itemAdd(OSStatus): Errors when adding a new Keychain item.
  • itemCopyMatching(OSStatus): Errors during data retrieval.

Contributing

Contributions are welcome! If you find a bug, have an idea for a new feature, or want to improve the documentation, please open an issue or submit a pull request.

  1. Fork the repository.
  2. Create a feature branch (git checkout -b feature/YourFeature).
  3. Commit your changes.
  4. Push to the branch (git push origin feature/YourFeature).
  5. Open a pull request.

License

This project is available under the MIT License.


Contact

For any questions, suggestions, or feedback, please open an issue

About

SecureStorage is a Swift package that simplifies secure Keychain storage for Codable values with a type-safe property wrapper and protocol integration for SwiftUI.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 100.0%