Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/docc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Set up Swift
uses: swift-actions/setup-swift@v2
with:
swift-version: '6.1.0'
swift-version: '6.2.0'

- name: Build and Export DocC
run: |
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/macOS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ jobs:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16.0
- uses: swift-actions/setup-swift@v2
with:
swift-version: '6.2.0'
- uses: actions/checkout@v3
- name: Build
run: swift build -v
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: Set up Swift
uses: swift-actions/setup-swift@v2
with:
swift-version: '6.1.0'
swift-version: '6.2.0'
- uses: actions/checkout@v3
- name: Build for release
run: swift build -v -c release
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ jobs:
- uses: actions/checkout@v4

# ① Install Swift for Windows
- name: Set up Swift 6.1
- name: Set up Swift 6.2
uses: compnerd/gha-setup-swift@main
with:
branch: swift-6.1-release # release branch
tag: 6.1-RELEASE # exact toolchain tag
branch: swift-6.2-release # release branch
tag: 6.2-RELEASE # exact toolchain tag

# ② Build & test
- run: swift --version # sanity-check
Expand Down
12 changes: 6 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// swift-tools-version: 6.0
// swift-tools-version: 6.2
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "Cache",
platforms: [
.macOS(.v10_15),
.iOS(.v13),
.watchOS(.v6),
.tvOS(.v13),
.visionOS(.v1)
.macOS(.v15),
.iOS(.v18),
.watchOS(.v11),
.tvOS(.v18),
.visionOS(.v2)
],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
Expand Down
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,19 @@

*A simple, lightweight caching library for Swift.*

Requires **Swift 6.0** or later.
Requires **Swift 6.2** or later.

### Platform Requirements

| Platform | Minimum Version |
|----------|-----------------|
| macOS | 15.0+ |
| iOS | 18.0+ |
| watchOS | 11.0+ |
| tvOS | 18.0+ |
| visionOS | 2.0+ |

> **Note:** For older platform support (macOS 10.15+, iOS 13+, etc.), use version 2.x.x.

## What is Cache?

Expand All @@ -13,7 +25,7 @@ Cache is a Swift library for caching arbitrary data types in memory. It provides
- Generic value type
- Supports JSON serialization and deserialization
- Flexible caching, allowing for multiple Cache objects with different configurations
- Thread-safe implementation
- Thread-safe implementation using Swift's `Mutex` from the Synchronization framework
- Property Wrappers

## Installation
Expand All @@ -22,6 +34,14 @@ Cache is a Swift library for caching arbitrary data types in memory. It provides

Add the following line to your `Package.swift` file in the dependencies array:

```swift
dependencies: [
.package(url: "https://github.com/0xLeif/Cache.git", from: "3.0.0")
]
```

For older platforms, use version 2.x:

```swift
dependencies: [
.package(url: "https://github.com/0xLeif/Cache.git", from: "2.0.0")
Expand Down
76 changes: 39 additions & 37 deletions Sources/Cache/Cache/AnyCacheable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public class AnyCacheable: Cacheable, @unchecked Sendable {
public typealias Key = AnyHashable
public typealias Value = Any

private let lock = NSRecursiveLock()
private let lock = CacheLock()
private var cache: any Cacheable

private var cacheGet: ((AnyHashable) -> Any?)!
Expand Down Expand Up @@ -95,68 +95,70 @@ public class AnyCacheable: Cacheable, @unchecked Sendable {
_ key: AnyHashable,
as: Output.Type = Output.self
) -> Output? {
lock.lock(); defer { lock.unlock() }
guard let value = cacheGet(key) else {
return nil
lock.withLock {
guard let value = cacheGet(key) else {
return nil
}
guard let output = value as? Output else {
return nil
}
return output
}

guard let output = value as? Output else {
return nil
}

return output
}

public func resolve<Output>(
_ key: AnyHashable,
as: Output.Type = Output.self
) throws -> Output {
lock.lock(); defer { lock.unlock() }
let resolvedValue = try cacheResolve(key)

guard let output = resolvedValue as? Output else {
throw InvalidTypeError(
expectedType: Output.self,
actualType: type(of: get(key, as: Any.self))
)
try lock.withLock {
let resolvedValue = try cacheResolve(key)
guard let output = resolvedValue as? Output else {
throw InvalidTypeError(
expectedType: Output.self,
actualType: Value.self
)
}
return output
}

return output
}

public func set(value: Value, forKey key: AnyHashable) {
lock.lock(); defer { lock.unlock() }
cacheSet(value, key)
lock.withLock {
cacheSet(value, key)
}
}

public func remove(_ key: AnyHashable) {
lock.lock(); defer { lock.unlock() }
cacheRemove(key)
lock.withLock {
cacheRemove(key)
}
}

public func contains(_ key: AnyHashable) -> Bool {
lock.lock(); defer { lock.unlock() }
return cacheContains(key)
lock.withLock {
cacheContains(key)
}
}

public func require(keys: Set<AnyHashable>) throws -> Self {
lock.lock(); defer { lock.unlock() }
try cacheRequireKeys(keys)

return self
try lock.withLock {
try cacheRequireKeys(keys)
return self
}
}

public func require(_ key: AnyHashable) throws -> Self {
lock.lock(); defer { lock.unlock() }
try cacheRequireKey(key)

return self
try lock.withLock {
try cacheRequireKey(key)
return self
}
}

public func values<Output>(ofType: Output.Type) -> [AnyHashable: Output] {
lock.lock(); defer { lock.unlock() }
return cacheValues().compactMapValues { value in
value as? Output
lock.withLock {
cacheValues().compactMapValues { value in
value as? Output
}
}
}
}
Expand Down
Loading
Loading