Skip to content

Commit

Permalink
Update Documentation in Conformance to the Documentation Guide (#14)
Browse files Browse the repository at this point in the history
<!--

This source file is part of the Stanford Spezi open-source project

SPDX-FileCopyrightText: 2022 Stanford University and the project authors
(see CONTRIBUTORS.md)

SPDX-License-Identifier: MIT

-->

# Update Documentation in Conformance to the Documentation Guide

## ♻️ Current situation & Problem
Addresses issue #11.

## 📝 Code of Conduct & Contributing Guidelines 

By submitting creating this pull request, you agree to follow our [Code
of
Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md)
and [Contributing
Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md):
- [X] I agree to follow the [Code of
Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md)
and [Contributing
Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md).

---------

Co-authored-by: Paul Schmiedmayer <[email protected]>
  • Loading branch information
vishnuravi and PSchmiedmayer authored Oct 8, 2023
1 parent 739ee1e commit 58f79a2
Show file tree
Hide file tree
Showing 10 changed files with 337 additions and 74 deletions.
88 changes: 87 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,93 @@ SPDX-License-Identifier: MIT
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FStanfordSpezi%2FSpeziStorage%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FStanfordSpezi%2FSpeziStorage%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage)

The Spezi Storage module enables an encrypted storage of information, credentials, and keys.
The Spezi Storage module consists of two sub-modules that enable on-disk storage of information.
The [`LocalStorage`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage) module can be used to store information that does not need to be encrypted.
Credentials, keys, and other sensitive information that needs to be encrypted may be stored by using the [`SecureStorage`](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation/spezisecurestorage) module.


## Setup

You need to add the Spezi Storage Swift package to
[your app in Xcode](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app#) or
[Swift package](https://developer.apple.com/documentation/xcode/creating-a-standalone-swift-package-with-xcode#Add-a-dependency-on-another-Swift-package).

> [!IMPORTANT]
> If your application is not yet configured to use Spezi, follow the [Spezi setup article](https://swiftpackageindex.com/stanfordspezi/spezi/documentation/spezi/setup) to set up the core Spezi infrastructure.
You can configure the [`LocalStorage`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage) or [`SecureStorage`](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation/spezisecurestorage) module in the [`SpeziAppDelegate`](https://swiftpackageindex.com/stanfordspezi/spezi/documentation/spezi/speziappdelegate).
```swift
import Spezi
import SpeziLocalStorage
import SpeziSecureStorage


class ExampleDelegate: SpeziAppDelegate {
override var configuration: Configuration {
Configuration {
LocalStorage()
SecureStorage()
// ...
}
}
}
```

You can then use the [`LocalStorage`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage) or [`SecureStorage`](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation/spezisecurestorage) class in any SwiftUI view.

```swift
struct ExampleStorageView: View {
@EnvironmentObject var secureStorage: LocalStorage
@EnvironmentObject var secureStorage: SecureStorage


var body: some View {
// ...
}
}
```

Alternatively, it is common to use the [`LocalStorage`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage) or [`SecureStorage`](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation/spezisecurestorage) module in other modules as a dependency: [Spezi component dependencies](https://swiftpackageindex.com/stanfordspezi/spezi/documentation/spezi/component#Dependencies).


## Local Storage

The [`LocalStorage`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage) module enables the on-disk storage of data in mobile applications.

The [`LocalStorage`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage) module defaults to storing data encrypted supported by the [`SecureStorage`](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation/spezisecurestorage) module.
The [`LocalStorageSetting`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstoragesetting) enables configuring how data in the [`LocalStorage`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage) module can be stored and retrieved.

- Store or update new elements: [`store(_:storageKey:settings:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage/store(_:storagekey:settings:))
- Retrieve existing elements: [`read(_:storageKey:settings:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage/read(_:storagekey:settings:))
- Delete existing elements: [`delete(_:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezilocalstorage/localstorage/delete(_:))


## Secure Storage

The [`SecureStorage`](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation/spezisecurestorage) module allows for the encrypted storage of small chunks of sensitive user data, such as usernames and passwords for internet services, using Apple's [Keychain documentation](https://developer.apple.com/documentation/security/keychain_services/keychain_items/using_the_keychain_to_manage_user_secrets).

Credentials can be stored in the Secure Enclave (if available) or the Keychain. Credentials stored in the Keychain can be made synchronizable between different instances of user devices.

### Handling Credentials

Use the [`SecureStorage`](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation/spezisecurestorage) module to store a set of [`Credentials`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/credentials) instances in the Keychain associated with a server that is synchronizable between different devices.

- Store new credentials: [`store(credentials:server:removeDuplicate:storageScope:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/store(credentials:server:removeduplicate:storagescope:))
- Retrieve existing credentials: [`retrieveCredentials(_:server:accessGroup:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/retrievecredentials(_:server:accessgroup:))
- Retrieve all matching existing credentials: [`retrieveAllCredentials(forServer:accessGroup:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/retrieveallcredentials(forserver:accessgroup:))
- Update existing credentials: [`updateCredentials(_:server:newCredentials:newServer:removeDuplicate:storageScope:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/updatecredentials(_:server:newcredentials:newserver:removeduplicate:storagescope:))
- Delete existing credentials: [`deleteCredentials(_:server:accessGroup:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/deletecredentials(_:server:accessgroup:))
- Delete all matching existing credentials: [`deleteAllCredentials(itemTypes:accessGroup:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/deleteallcredentials(itemtypes:accessgroup:))


### Handling Keys

Similar to [`Credentials`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/credentials) instances, you can also use the [`SecureStorage`](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation/spezisecurestorage) module to interact with keys.

- Create new keys: [`createKey(_:size:storageScope:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/createkey(_:size:storagescope:))
- Retrieve existing public keys: [`retrievePublicKey(forTag:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/retrievepublickey(fortag:))
- Retrieve existing private keys: [`retrievePrivateKey(forTag:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/retrieveprivatekey(fortag:))
- Delete existing keys: [`deleteKeys(forTag:)`](https://swiftpackageindex.com/stanfordspezi/spezistorage/documentation/spezisecurestorage/securestorage/deletekeys(fortag:))

For more information, please refer to the [API documentation](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation).

Expand Down
52 changes: 46 additions & 6 deletions Sources/SpeziLocalStorage/LocalStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import SpeziSecureStorage
/// The ``LocalStorage/`` module enables the on-disk storage of data in mobile applications.
/// The module relies on the `SecureStorage` module to enable an encrypted on-disk storage as defined by the ``LocalStorageSetting`` configuration.
///
/// Use ``LocalStorage/LocalStorage/store(_:storageKey:settings:)`` to store elements on disk and define the settings using a ``LocalStorageSetting`` instance.
/// Use ``LocalStorage/store(_:storageKey:settings:)`` to store elements on disk and define the settings using a ``LocalStorageSetting`` instance.
///
/// Use ``LocalStorage/LocalStorage/read(_:storageKey:settings:)`` to read elements on disk which are decoded as define by passed in ``LocalStorageSetting`` instance.
/// Use ``LocalStorage/read(_:storageKey:settings:)`` to read elements on disk which are decoded as define by passed in ``LocalStorageSetting`` instance.
public final class LocalStorage: Module, DefaultInitializable {
private let encryptionAlgorithm: SecKeyAlgorithm = .eciesEncryptionCofactorX963SHA256AESGCM
@Dependency private var secureStorage = SecureStorage()
Expand All @@ -43,7 +43,23 @@ public final class LocalStorage: Module, DefaultInitializable {
public required init() {}


/// Use ``LocalStorage/LocalStorage/store(_:storageKey:settings:)`` to store elements on disk and define the settings using a ``LocalStorageSetting`` instance.
/// Store elements on disk and define the settings using a ``LocalStorageSetting`` instance.
///
/// ```swift
/// struct Note: Codable, Equatable {
/// let text: String
/// let date: Date
/// }
///
/// let note = Note(text: "Spezi is awesome!", date: Date())
///
/// do {
/// try await localStorage.store(note)
/// } catch {
/// // Handle storage errors ...
/// }
/// ```
///
/// - Parameters:
/// - element: The element that should be stored conforming to `Encodable`
/// - storageKey: An optional storage key to identify the file.
Expand Down Expand Up @@ -100,7 +116,17 @@ public final class LocalStorage: Module, DefaultInitializable {
}


/// Use ``LocalStorage/LocalStorage/read(_:storageKey:settings:)`` to read elements on disk which are decoded as defined by passed in ``LocalStorageSetting`` instance.
/// Read elements on disk which are decoded as defined by passed in ``LocalStorageSetting`` instance.
///
/// ```swift
/// do {
/// let storedNote: Note = try await localStorage.read()
/// // Do something with `storedNote`.
/// } catch {
/// // Handle read errors ...
/// }
/// ```
///
/// - Parameters:
/// - storageKey: An optional storage key to identify the file.
/// - settings: The ``LocalStorageSetting``s used to retrieve the file on disk.
Expand Down Expand Up @@ -131,14 +157,28 @@ public final class LocalStorage: Module, DefaultInitializable {
}


/// Use ``LocalStorage/LocalStorage/delete(storageKey:)`` to deletes a file stored on disk identified by the `storageKey`.
/// Deletes a file stored on disk identified by the `storageKey`.
///
/// ```swift
/// do {
/// try await localStorage.delete(storageKey: "MyNote")
/// } catch {
/// // Handle delete errors ...
/// }
/// ```
///
/// Use ``delete(_:)`` as an automatically define the `storageKey` if the type conforms to `Encodable`.
///
/// - Parameters:
/// - storageKey: An optional storage key to identify the file.
public func delete(storageKey: String) throws {
try delete(String.self, storageKey: storageKey)
}

/// Use ``LocalStorage/LocalStorage/delete(storageKey:)`` to deletes a file stored on disk defined by a `Decodable` type that is used to derive the storage key.
/// Deletes a file stored on disk defined by a `Decodable` type that is used to derive the storage key.
///
/// Use ``delete(storageKey:)`` to manually define the storage key.
///
/// - Parameters:
/// - type: The `Decodable` type that is used to derive the storage key from.
public func delete<C: Encodable>(_ type: C.Type = C.self) throws {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SpeziLocalStorage/LocalStorageError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//


/// An error thrown by the ``LocalStorage/LocalStorage`` module.
/// An error thrown by the ``LocalStorage`` module.
enum LocalStorageError: Error {
/// Encryption of the file was not possible, did not store the data on disk.
case encyptionNotPossible
Expand Down
2 changes: 1 addition & 1 deletion Sources/SpeziLocalStorage/LocalStorageSetting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Spezi
import SpeziSecureStorage


/// The ``LocalStorageSetting`` enables configuring how data in the ``LocalStorage/LocalStorage`` module can be stored and retrieved.
/// The ``LocalStorageSetting`` enables configuring how data in the ``LocalStorage`` module can be stored and retrieved.
public enum LocalStorageSetting {
/// Unencrypted
case unencrypted(excludedFromBackup: Bool = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,45 @@ SPDX-License-Identifier: MIT
-->

Store data on-disk.
Store data encryped on-disk.

## Overview

The ``LocalStorage`` module enables the on-disk storage of data in mobile applications. The ``LocalStorageSetting`` enables configuring how data in the ``LocalStorage`` module can be stored and retrieved.
The ``LocalStorage`` module enables the on-disk storage of data in mobile applications.

The data stored can optionally be encrypted by importing the `SecureStorage` module.
The ``LocalStorage`` module defaults to storing data encrypted supported by the [`SecureStorage`](https://swiftpackageindex.com/StanfordSpezi/SpeziStorage/documentation/spezisecurestorage) module.
The ``LocalStorageSetting`` enables configuring how data in the ``LocalStorage`` module can be stored and retrieved.


## Add the LocalStorage Module
## Setup

You can configure the ``LocalStorage/LocalStorage`` module in the `SpeziAppDelegate`.
You need to add the Spezi Storage Swift package to
[your app in Xcode](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app#) or
[Swift package](https://developer.apple.com/documentation/xcode/creating-a-standalone-swift-package-with-xcode#Add-a-dependency-on-another-Swift-package).

> Important: If your application is not yet configured to use Spezi, follow the [Spezi setup article](https://swiftpackageindex.com/stanfordspezi/spezi/documentation/spezi/setup) to set up the core Spezi infrastructure.
You can configure the ``LocalStorage`` module in the [`SpeziAppDelegate`](https://swiftpackageindex.com/stanfordspezi/spezi/documentation/spezi/speziappdelegate).

```swift
import Spezi
import LocalStorage
import SpeziLocalStorage


class ExampleDelegate: SpeziAppDelegate {
override var configuration: Configuration {
Configuration {
LocalStorage()
// ...
}
}
}
```

You can then use the ``LocalStorage/LocalStorage`` class in any SwiftUI view.
You can then use the ``LocalStorage`` class in any SwiftUI view.

```swift
struct ExampleLocalStorageView: View {
struct ExampleStorageView: View {
@EnvironmentObject var localStorage: LocalStorage


Expand All @@ -50,13 +58,17 @@ struct ExampleLocalStorageView: View {
}
```

Alternatively it is common to use the ``LocalStorage/LocalStorage`` component in other components as a dependency.
Alternatively, it is common to use the ``LocalStorage`` module in other modules as a dependency: [Spezi component dependencies](https://swiftpackageindex.com/stanfordspezi/spezi/documentation/spezi/component#Dependencies).


## Use the LocalStorage Module

### Storing data
You can use the ``LocalStorage`` module to store, update, retrieve, and delete element conforming to [`Codable`](https://developer.apple.com/documentation/swift/codable).


### Storing & Update Data

Use the ``LocalStorage/LocalStorage`` component to store data that conforms to `Encodable`.
The ``LocalStorage`` module enables the storage and update of elements conforming to [`Codable`](https://developer.apple.com/documentation/swift/codable).

```swift
struct Note: Codable, Equatable {
Expand All @@ -67,44 +79,55 @@ struct Note: Codable, Equatable {
let note = Note(text: "Spezi is awesome!", date: Date())

do {
try await localStorage.store(
note,
storageKey: "MyNote",
settings: .unencrypted()
)
try await localStorage.store(note)
} catch {
// Handle storage error here
// ...
// Handle storage errors ...
}

```

### Reading stored data
See ``LocalStorage/store(_:storageKey:settings:)`` for more details.



### Read Data

Use the ``LocalStorage/LocalStorage`` component to read previously stored data.
The ``LocalStorage`` module enables the retrieval of elements conforming to [`Codable`](https://developer.apple.com/documentation/swift/codable).

```swift
do {
let storedNote: Note = try await localStorage.read(
storageKey: "MyNote",
settings: .unencrypted()
)
let storedNote: Note = try await localStorage.read()
// Do something with `storedNote`.
} catch {
// Handle read error.
// ...
// Handle read errors ...
}
```

### Deleting stored data
See ``LocalStorage/read(_:storageKey:settings:)`` for more details.

Use the ``LocalStorage/LocalStorage`` component to delete previously stored data.

### Deleting Element

The ``LocalStorage`` module enables the deletion of a previously stored elements.

```swift
do {
try await localStorage.delete(storageKey: "MyNote")
} catch {
// Handle delete error.
// ...
// Handle delete errors ...
}
```

See ``LocalStorage/delete(_:)`` or ``LocalStorage/delete(storageKey:)`` for more details.


## Topics

### LocalStorage

- ``LocalStorage``
- ``LocalStorageSetting``
- ``LocalStorage/store(_:storageKey:settings:)``
- ``LocalStorage/read(_:storageKey:settings:)``
- ``LocalStorage/delete(storageKey:)``
- ``LocalStorage/delete(_:)``

4 changes: 2 additions & 2 deletions Sources/SpeziSecureStorage/Credentials.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//


/// Credentials that can be stored, updated, deleted, and retrieved from a ``SecureStorage/SecureStorage`` module.
/// Credentials that can be stored, updated, deleted, and retrieved from a ``SecureStorage`` module.
public struct Credentials: Equatable, Identifiable {
/// The username
public var username: String
Expand All @@ -21,7 +21,7 @@ public struct Credentials: Equatable, Identifiable {
}


/// Credentials that can be stored, updated, deleted, and retrieved from a ``SecureStorage/SecureStorage`` module.
/// Credentials that can be stored, updated, deleted, and retrieved from a ``SecureStorage`` module.
/// - Parameters:
/// - username: The username
/// - password: The password associated to the ``Credentials/username``
Expand Down
Loading

0 comments on commit 58f79a2

Please sign in to comment.