Skip to content

Commit 7aacbea

Browse files
committed
Release 1.0.0
1 parent a209c43 commit 7aacbea

8 files changed

Lines changed: 599 additions & 63 deletions

File tree

.gitignore

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,8 @@
1-
# Xcode
2-
#
3-
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4-
5-
## User settings
1+
.DS_Store
2+
/.build
3+
/Packages
64
xcuserdata/
7-
8-
## Obj-C/Swift specific
9-
*.hmap
10-
11-
## App packaging
12-
*.ipa
13-
*.dSYM.zip
14-
*.dSYM
15-
16-
## Playgrounds
17-
timeline.xctimeline
18-
playground.xcworkspace
19-
20-
# Swift Package Manager
21-
#
22-
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
23-
# Packages/
24-
# Package.pins
25-
# Package.resolved
26-
# *.xcodeproj
27-
#
28-
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
29-
# hence it is not needed unless you have added a package configuration file to your project
30-
# .swiftpm
31-
32-
.build/
33-
34-
# CocoaPods
35-
#
36-
# We recommend against adding the Pods directory to your .gitignore. However
37-
# you should judge for yourself, the pros and cons are mentioned at:
38-
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
39-
#
40-
# Pods/
41-
#
42-
# Add this line if you want to avoid checking in source code from the Xcode workspace
43-
# *.xcworkspace
44-
45-
# Carthage
46-
#
47-
# Add this line if you want to avoid checking in source code from Carthage dependencies.
48-
# Carthage/Checkouts
49-
50-
Carthage/Build/
51-
52-
# fastlane
53-
#
54-
# It is recommended to not store the screenshots in the git repo.
55-
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
56-
# For more information about the recommended setup visit:
57-
# https://docs.fastlane.tools/best-practices/source-control/#source-control
58-
59-
fastlane/report.xml
60-
fastlane/Preview.html
61-
fastlane/screenshots/**/*.png
62-
fastlane/test_output
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc

Package.resolved

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// swift-tools-version: 6.0
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "SwiftyCache",
8+
platforms: [
9+
.iOS(.v13),
10+
.macOS(.v10_15),
11+
.tvOS(.v13),
12+
.watchOS(.v6),
13+
.visionOS(.v1),
14+
.macCatalyst(.v13)
15+
],
16+
products: [
17+
// Products define the executables and libraries a package produces, making them visible to other packages.
18+
.library(
19+
name: "SwiftyCache",
20+
targets: ["SwiftyCache"]
21+
)
22+
],
23+
dependencies: [
24+
.package(url: "https://github.com/apple/swift-collections.git", from: "1.1.4")
25+
],
26+
targets: [
27+
// Targets are the basic building blocks of a package, defining a module or a test suite.
28+
// Targets can depend on other targets in this package and products from dependencies.
29+
.target(
30+
name: "SwiftyCache",
31+
dependencies: [
32+
.product(name: "OrderedCollections", package: "swift-collections")
33+
],
34+
resources: [.copy("Resources/PrivacyInfo.xcprivacy")],
35+
),
36+
.testTarget(
37+
name: "SwiftyCacheTests",
38+
dependencies: ["SwiftyCache"]
39+
)
40+
],
41+
swiftLanguageModes: [.v6]
42+
)

Package@swift-5.9.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// swift-tools-version: 5.9
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "SwiftyCache",
8+
platforms: [
9+
.iOS(.v13),
10+
.macOS(.v10_15),
11+
.tvOS(.v13),
12+
.watchOS(.v6),
13+
.visionOS(.v1),
14+
.macCatalyst(.v13)
15+
],
16+
products: [
17+
// Products define the executables and libraries a package produces, making them visible to other packages.
18+
.library(
19+
name: "SwiftyCache",
20+
targets: ["SwiftyCache"]
21+
)
22+
],
23+
dependencies: [
24+
.package(url: "https://github.com/apple/swift-collections.git", from: "1.1.4")
25+
],
26+
targets: [
27+
// Targets are the basic building blocks of a package, defining a module or a test suite.
28+
// Targets can depend on other targets in this package and products from dependencies.
29+
.target(
30+
name: "SwiftyCache",
31+
dependencies: [
32+
.product(name: "OrderedCollections", package: "swift-collections")
33+
],
34+
resources: [.copy("Resources/PrivacyInfo.xcprivacy")],
35+
),
36+
.testTarget(
37+
name: "SwiftyCacheTests",
38+
dependencies: ["SwiftyCache"]
39+
)
40+
],
41+
swiftLanguageVersions: [.v5]
42+
)

README.md

Lines changed: 150 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,150 @@
1-
# SwiftyCache
2-
A lightweight, elegant, and performant in-memory cache written purely in Swift
1+
# 🧠 SwiftyCache
2+
3+
[![Swift Package Manager](https://img.shields.io/badge/SPM-Compatible-orange.svg?style=flat)](https://swift.org/package-manager/)
4+
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
5+
[![Platform](https://img.shields.io/badge/platform-iOS%20%7C%20macOS%20%7C%20tvOS%20%7C%20watchOS-lightgrey.svg)](#)
6+
[![Contact](https://img.shields.io/badge/contact-codingiran%40gmail.com-blue.svg)](mailto:codingiran@gmail.com)
7+
8+
**SwiftyCache** is a lightweight, elegant, and performant in-memory cache written purely in Swift.
9+
It supports Least-Recently-Used (LRU) eviction logic using Swift Collections’ [`OrderedDictionary`](https://github.com/apple/swift-collections), with optional cost-based cleanup and memory warning handling for Apple platforms.
10+
11+
> Simple. Fast. Swifty.
12+
13+
---
14+
15+
## 🚀 Features
16+
17+
- ✅ LRU (Least-Recently-Used) eviction strategy
18+
- ✅ Cost-based cleanup (`totalCostLimit`)
19+
- ✅ Count-based cleanup (`countLimit`)
20+
-`MemoryWarning` cleanup
21+
- ✅ Thread-safe design ready
22+
- ✅ No Objective-C / Foundation subclassing
23+
- ✅ 100% Swift + SPM support
24+
- ✅ Clean and minimal API
25+
26+
---
27+
28+
## 📦 Installation
29+
30+
### Swift Package Manager
31+
32+
```swift
33+
dependencies: [
34+
.package(url: "https://github.com/codingiran/SwiftyCache.git", from: "1.0.0")
35+
]
36+
```
37+
38+
Then import where needed:
39+
40+
```swift
41+
import SwiftyCache
42+
```
43+
44+
---
45+
46+
## 🧩 Usage
47+
48+
### Create a cache
49+
50+
```swift
51+
let cache = SwiftyCache<String, Data>(
52+
totalCostLimit: 10_000, // Optional
53+
countLimit: 100 // Optional
54+
)
55+
```
56+
57+
### Store & retrieve values
58+
59+
```swift
60+
cache.setValue(imageData, forKey: "avatar", cost: imageData.count)
61+
62+
let cachedData = cache.value(forKey: "avatar")
63+
```
64+
65+
### Eviction
66+
67+
- Least Recently Used items are automatically evicted when:
68+
- `countLimit` is exceeded
69+
- `totalCostLimit` is exceeded
70+
- Memory warning([DispatchSourceMemoryPressure](https://developer.apple.com/documentation/dispatch/dispatchsourcememorypressure)) is received
71+
72+
### Remove items
73+
74+
```swift
75+
cache.removeValue(forKey: "avatar")
76+
cache.removeAllValues()
77+
```
78+
79+
---
80+
81+
## 🧪 LRU Example
82+
83+
```swift
84+
let cache = SwiftyCache<String, Int>(countLimit: 3)
85+
86+
cache.setValue(1, forKey: "A")
87+
cache.setValue(2, forKey: "B")
88+
cache.setValue(3, forKey: "C")
89+
90+
_ = cache.value(forKey: "A") // A is now most recently used
91+
92+
cache.setValue(4, forKey: "D") // B is evicted (least recently used)
93+
94+
print(cache.allKeys) // ["C", "A", "D"]
95+
```
96+
97+
---
98+
99+
## 🧱 Implementation Highlights
100+
101+
- Using Swift actor for thread safety
102+
- Implements `NSCache`-like API for easy integration
103+
- Built atop [`OrderedDictionary`](https://github.com/apple/swift-collections) to avoid managing doubly-linked list manually
104+
- Reorders keys internally on access to preserve LRU order
105+
- Minimal dependencies, cleanly integrated with `DispatchSourceMemoryPressure` for memory warnings
106+
107+
---
108+
109+
## 📁 Project Structure
110+
111+
```swift
112+
SwiftyCache/
113+
├── Sources/
114+
└── SwiftyCache.swift
115+
├── Package.swift
116+
└── README.md You are here
117+
```
118+
119+
---
120+
121+
## 📄 License
122+
123+
This project is licensed under the MIT License.
124+
See [LICENSE](./LICENSE) for more information.
125+
126+
---
127+
128+
## 🤝 Contributing
129+
130+
Pull requests are welcome!
131+
If you'd like to add a feature, fix a bug, or improve documentation:
132+
133+
- Fork the repo
134+
- Create your feature branch: `git checkout -b feature/your-feature`
135+
- Commit your changes: `git commit -m "Add some feature"`
136+
- Push to the branch: `git push origin feature/your-feature`
137+
- Open a Pull Request
138+
139+
---
140+
141+
## 📬 Contact
142+
143+
Feel free to reach out:
144+
145+
**📧 Email**: [codingiran@gmail.com](mailto:codingiran@gmail.com)
146+
**📦 GitHub**: [github.com/codingiran/SwiftyCache](https://github.com/codingiran/SwiftyCache.git)
147+
148+
---
149+
150+
> Made with ❤️ by @codingiran
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>NSPrivacyAccessedAPITypes</key>
6+
<array>
7+
<dict>
8+
<key>NSPrivacyAccessedAPIType</key>
9+
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
10+
<key>NSPrivacyAccessedAPITypeReasons</key>
11+
<array>
12+
<string>CA92.1</string>
13+
</array>
14+
</dict>
15+
</array>
16+
<key>NSPrivacyCollectedDataTypes</key>
17+
<array/>
18+
<key>NSPrivacyTrackingDomains</key>
19+
<array/>
20+
<key>NSPrivacyTracking</key>
21+
<false/>
22+
</dict>
23+
</plist>

0 commit comments

Comments
 (0)