Skip to content

Commit

Permalink
Initial release of iCloudStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
0xWDG committed Jan 24, 2025
1 parent 23a7662 commit 3eeb312
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .spi.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 1
builder:
configs:
- documentation_targets: [spm-template]
- documentation_targets: [iCloudStorage]
32 changes: 32 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// swift-tools-version: 5.8.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "iCloudStorage",
platforms: [
.iOS(.v15),
.macOS(.v12),
.watchOS(.v8),
.tvOS(.v15),
.visionOs(.v1)
],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
name: "iCloudStorage",
targets: ["iCloudStorage"]
)
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "iCloudStorage"),
.testTarget(
name: "iCloudStorageTests",
dependencies: ["iCloudStorage"]
)
]
)
32 changes: 21 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# spm-template
# iCloudStorage

spm-template is a Swift Package for ...
iCloudStorage is a property wrapper around NSUbiquitousKeyValueStore to easily access your shared UserDefaults.

[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2F0xWDG%2Fspm-template%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/0xWDG/spm-template)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2F0xWDG%2Fspm-template%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/0xWDG/spm-template)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2F0xWDG%2FiCloudStorage%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/0xWDG/iCloudStorage)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2F0xWDG%2FiCloudStorage%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/0xWDG/iCloudStorage)
[![Swift Package Manager](https://img.shields.io/badge/SPM-compatible-brightgreen.svg)](https://swift.org/package-manager)
![License](https://img.shields.io/github/license/0xWDG/spm-template)
![License](https://img.shields.io/github/license/0xWDG/iCloudStorage)

## Requirements

Expand All @@ -16,31 +16,41 @@ spm-template is a Swift Package for ...

```swift
dependencies: [
.package(url: "https://github.com/0xWDG/spm-template.git", branch: "main"),
.package(url: "https://github.com/0xWDG/iCloudStorage.git", branch: "main"),
],
targets: [
.target(name: "MyTarget", dependencies: [
.product(name: "spm-template", package: "spm-template"),
.product(name: "iCloudStorage", package: "iCloudStorage"),
]),
]
```

## Installation (Xcode)

1. In Xcode, open your project and navigate to **File****Swift Packages****Add Package Dependency...**
2. Paste the repository URL (`https://github.com/0xWDG/spm-template`) and click **Next**.
2. Paste the repository URL (`https://github.com/0xWDG/iCloudStorage`) and click **Next**.
3. Click **Finish**.

## Usage

```swift
import SwiftUI
import spm-template
import iCloudStorage

struct ContentView: View {
@iCloudStorage("key")
var value: String = "default"

var body: some View {
VStack {
/// ...
Text(value)

Button("Change value") {
value = "Hello there at \(Date())"
}
}
.task {
value = "Hello there"
}
.padding()
}
Expand All @@ -56,4 +66,4 @@ struct ContentView: View {
🌐 [wesleydegroot.nl](https://wesleydegroot.nl)
🤖 [Discord](https://discordapp.com/users/918438083861573692)

Interested learning more about Swift? [Check out my blog](https://wesleydegroot.nl/blog/).
Interested learning more about Swift? [Check out my blog](https://wesleydegroot.nl/blog/).
60 changes: 60 additions & 0 deletions Sources/iCloudStorage/iCloudStorage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// iCloudStorage.swift
// iCloudStorage
//
// Created by Wesley de Groot on 2025-01-24.
// https://wesleydegroot.nl
//
// https://github.com/0xWDG/iCloudStorage
// MIT License
//

#if canImport(SwiftUI)
import Foundation
import SwiftUI

/// A property wrapper that reads and writes to iCloud.
///
/// Example:
/// ```
/// @iCloudStorage("key") var value: String = "default"
/// ```
@propertyWrapper
public struct iCloudStorage<T>: DynamicProperty {
// swiftlint:disable:previous type_name
/// The key to read and write to.
let key: String

/// The default value to use if the value is not set yet.
let defaultValue: T

/// Creates an `iCloudStorage` property.
///
/// - Parameter wrappedValue: The default value.
/// - Parameter key: The key to read and write to.
public init(wrappedValue: T, _ key: String) {
self.key = key
self.defaultValue = wrappedValue
}

/// The value of the key in iCloud.
public var wrappedValue: T {
get {
return NSUbiquitousKeyValueStore.default.object(forKey: key) as? T ?? defaultValue
}
// This needs to be nonmutating because we're setting a property on a struct.
nonmutating set {
NSUbiquitousKeyValueStore.default.set(newValue, forKey: key)
}
}

/// A binding to the value of the key in iCloud.
public var projectedValue: Binding<T> {
Binding {
return self.wrappedValue
} set: { newValue in
self.wrappedValue = newValue
}
}
}
#endif
16 changes: 16 additions & 0 deletions Tests/iCloudStorageTests/iCloudStorageTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// iCloudStorageTests.swift
// iCloudStorage
//
// Created by Wesley de Groot on 2025-01-24.
// https://wesleydegroot.nl
//
// https://github.com/0xWDG/iCloudStorage
// MIT License
//
import Testing
@testable import iCloudStorage

@Test func example() async throws {
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
}

0 comments on commit 3eeb312

Please sign in to comment.