Skip to content
This repository was archived by the owner on Aug 26, 2022. It is now read-only.

Commit 0f14367

Browse files
authored
Fix a bug in save objects (#40)
Fix a bug where saving an array of objects with an invalid object will cause the store to have an invalid count
1 parent 78b01d5 commit 0f14367

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+8934
-397
lines changed

.codebeatignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
docs/**

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
os: osx
22
language: swift
3-
osx_image: xcode10.2
3+
osx_image: xcode11.2
44

55
env:
66
- ACTION=test PLATFORM=Mac DESTINATION='platform=OS X'
7-
- ACTION=test PLATFORM=iOS DESTINATION='platform=iOS Simulator,name=iPhone X'
8-
- ACTION=build PLATFORM=watchOS DESTINATION='platform=watchOS Simulator,name=Apple Watch - 42mm'
7+
- ACTION=test PLATFORM=iOS DESTINATION='platform=iOS Simulator,name=iPhone 11'
8+
- ACTION=build PLATFORM=watchOS DESTINATION='platform=watchOS Simulator,name=Apple Watch Series 5 - 40mm'
99
- ACTION=test PLATFORM=tvOS DESTINATION='platform=tvOS Simulator,name=Apple TV 4K (at 1080p)'
1010

1111
before_install:

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
22

33
gem 'xcpretty'
44
gem 'xcpretty-json-formatter'
5+
gem 'cocoapods'
6+
gem 'jazzy'

Gemfile.lock

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
GEM
2+
remote: https://rubygems.org/
3+
specs:
4+
CFPropertyList (3.0.1)
5+
activesupport (4.2.11.1)
6+
i18n (~> 0.7)
7+
minitest (~> 5.1)
8+
thread_safe (~> 0.3, >= 0.3.4)
9+
tzinfo (~> 1.1)
10+
algoliasearch (1.27.1)
11+
httpclient (~> 2.8, >= 2.8.3)
12+
json (>= 1.5.1)
13+
atomos (0.1.3)
14+
claide (1.0.3)
15+
cocoapods (1.8.4)
16+
activesupport (>= 4.0.2, < 5)
17+
claide (>= 1.0.2, < 2.0)
18+
cocoapods-core (= 1.8.4)
19+
cocoapods-deintegrate (>= 1.0.3, < 2.0)
20+
cocoapods-downloader (>= 1.2.2, < 2.0)
21+
cocoapods-plugins (>= 1.0.0, < 2.0)
22+
cocoapods-search (>= 1.0.0, < 2.0)
23+
cocoapods-stats (>= 1.0.0, < 2.0)
24+
cocoapods-trunk (>= 1.4.0, < 2.0)
25+
cocoapods-try (>= 1.1.0, < 2.0)
26+
colored2 (~> 3.1)
27+
escape (~> 0.0.4)
28+
fourflusher (>= 2.3.0, < 3.0)
29+
gh_inspector (~> 1.0)
30+
molinillo (~> 0.6.6)
31+
nap (~> 1.0)
32+
ruby-macho (~> 1.4)
33+
xcodeproj (>= 1.11.1, < 2.0)
34+
cocoapods-core (1.8.4)
35+
activesupport (>= 4.0.2, < 6)
36+
algoliasearch (~> 1.0)
37+
concurrent-ruby (~> 1.1)
38+
fuzzy_match (~> 2.0.4)
39+
nap (~> 1.0)
40+
cocoapods-deintegrate (1.0.4)
41+
cocoapods-downloader (1.3.0)
42+
cocoapods-plugins (1.0.0)
43+
nap
44+
cocoapods-search (1.0.0)
45+
cocoapods-stats (1.1.0)
46+
cocoapods-trunk (1.4.1)
47+
nap (>= 0.8, < 2.0)
48+
netrc (~> 0.11)
49+
cocoapods-try (1.1.0)
50+
colored2 (3.1.2)
51+
concurrent-ruby (1.1.5)
52+
escape (0.0.4)
53+
ffi (1.11.2)
54+
fourflusher (2.3.1)
55+
fuzzy_match (2.0.4)
56+
gh_inspector (1.1.3)
57+
httpclient (2.8.3)
58+
i18n (0.9.5)
59+
concurrent-ruby (~> 1.0)
60+
jazzy (0.12.0)
61+
cocoapods (~> 1.5)
62+
mustache (~> 1.1)
63+
open4
64+
redcarpet (~> 3.4)
65+
rouge (>= 2.0.6, < 4.0)
66+
sassc (~> 2.1)
67+
sqlite3 (~> 1.3)
68+
xcinvoke (~> 0.3.0)
69+
json (2.2.0)
70+
liferaft (0.0.6)
71+
minitest (5.13.0)
72+
molinillo (0.6.6)
73+
mustache (1.1.0)
74+
nanaimo (0.2.6)
75+
nap (1.1.0)
76+
netrc (0.11.0)
77+
open4 (1.3.4)
78+
redcarpet (3.5.0)
79+
rouge (2.0.7)
80+
ruby-macho (1.4.0)
81+
sassc (2.2.1)
82+
ffi (~> 1.9)
83+
sqlite3 (1.4.1)
84+
thread_safe (0.3.6)
85+
tzinfo (1.2.5)
86+
thread_safe (~> 0.1)
87+
xcinvoke (0.3.0)
88+
liferaft (~> 0.0.6)
89+
xcodeproj (1.13.0)
90+
CFPropertyList (>= 2.3.3, < 4.0)
91+
atomos (~> 0.1.3)
92+
claide (>= 1.0.2, < 2.0)
93+
colored2 (~> 3.1)
94+
nanaimo (~> 0.2.6)
95+
xcpretty (0.3.0)
96+
rouge (~> 2.0.7)
97+
xcpretty-json-formatter (0.1.1)
98+
xcpretty (~> 0.2, >= 0.0.7)
99+
100+
PLATFORMS
101+
ruby
102+
103+
DEPENDENCIES
104+
cocoapods
105+
jazzy
106+
xcpretty
107+
xcpretty-json-formatter
108+
109+
BUNDLED WITH
110+
2.0.2

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
<a href="https://github.com/omaralbeik/UserDefaultsStore/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-red.svg" alt="MIT"></a>
1616
</p>
1717

18-
> A Turkish version of this document can be found [here](https://github.com/omaralbeik/UserDefaultsStore/blob/master/README_TR.md).
19-
2018
# tl;dr
2119
You love Swift's `Codable` protocol and use it everywhere, who doesn't! Here is an easy and very light way to store and retrieve -**reasonable amount 😅**- of `Codable` objects, in a couple lines of code!
2220

@@ -35,7 +33,7 @@ You love Swift's `Codable` protocol and use it everywhere, who doesn't! Here is
3533
</br>
3634
<p>To integrate UserDefaultsStore into your Xcode project using <a href="https://github.com/Carthage/Carthage">Carthage</a>, specify it in your <code>Cartfile</code>:</p>
3735

38-
<pre><code class="ogdl language-ogdl">github "omaralbeik/UserDefaultsStore" ~&gt; 1.0
36+
<pre><code class="ogdl language-ogdl">github "omaralbeik/UserDefaultsStore" ~&gt; 1.4.3
3937
</code></pre>
4038
</details>
4139

@@ -50,7 +48,7 @@ let package = Package(
5048
name: "YOUR_PROJECT_NAME",
5149
targets: [],
5250
dependencies: [
53-
.package(url: "https://github.com/omaralbeik/UserDefaultsStore.git", from: "1.4.2")
51+
.package(url: "https://github.com/omaralbeik/UserDefaultsStore.git", from: "1.4.3")
5452
]
5553
)
5654
</code></pre>

README_TR.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Swift'in `Codable` protokolüne bayılıyorsun ve her yerde kullanıyorsun, kim
3838
</br>
3939
<p>UserDefaultsStore'u <a href="https://github.com/Carthage/Carthage">Carthage</a>'u kullanarak Xcode projenize entegre etmek için, bunu <code>Cartfile</code>'da belirtin:
4040

41-
<pre><code class="ogdl language-ogdl">github "omaralbeik/UserDefaultsStore" ~&gt; 1.0
41+
<pre><code class="ogdl language-ogdl">github "omaralbeik/UserDefaultsStore" ~&gt; 1.4.3
4242
</code></pre>
4343
</details>
4444

@@ -52,7 +52,7 @@ Swift'in `Codable` protokolüne bayılıyorsun ve her yerde kullanıyorsun, kim
5252

5353
<pre><code class="swift language-swift">import PackageDescription
5454
dependencies: [
55-
.package(url: "https://github.com/omaralbeik/UserDefaultsStore.git", from: "1.0.2")
55+
.package(url: "https://github.com/omaralbeik/UserDefaultsStore.git", from: "1.4.3")
5656
]
5757
</code></pre>
5858
</details>

Sources/Identifiable.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,13 @@
2121
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2222
// THE SOFTWARE.
2323

24-
import Foundation
25-
2624
/// Conform to `Identifiable` protocol in uniquely identified objects you want to store in a `UserDefaultsStore`.
2725
public protocol Identifiable {
2826

29-
/// ID type.
30-
associatedtype ID
27+
/// ID type.
28+
associatedtype ID
3129

32-
/// Id Key.
33-
static var idKey: WritableKeyPath<Self, ID> { get }
30+
/// Id Key.
31+
static var idKey: WritableKeyPath<Self, ID> { get }
3432

3533
}

Sources/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>CFBundlePackageType</key>
1616
<string>FMWK</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>1.4.2</string>
18+
<string>$(MARKETING_VERSION)</string>
1919
<key>CFBundleSignature</key>
2020
<string>????</string>
2121
<key>CFBundleVersion</key>

Sources/SingleUserDefaultsStore.swift

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -26,77 +26,77 @@ import Foundation
2626
/// `SingleUserDefaultsStore` offers a convenient way to store a single `Codable` object in `UserDefaults`.
2727
open class SingleUserDefaultsStore<T: Codable> {
2828

29-
/// Store's unique identifier.
30-
///
31-
/// **Warning**: Never use the same identifier for two -or more- different stores.
32-
public let uniqueIdentifier: String
33-
34-
/// JSON encoder. _default is `JSONEncoder()`_
35-
open var encoder = JSONEncoder()
36-
37-
/// JSON decoder. _default is `JSONDecoder()`_
38-
open var decoder = JSONDecoder()
39-
40-
/// UserDefaults store.
41-
private var store: UserDefaults
42-
43-
/// Initialize store with given identifier.
44-
///
45-
/// **Warning**: Never use the same identifier for two -or more- different stores.
46-
///
47-
/// - Parameter uniqueIdentifier: store's unique identifier.
48-
required public init?(uniqueIdentifier: String) {
49-
guard let store = UserDefaults(suiteName: uniqueIdentifier) else { return nil }
50-
self.uniqueIdentifier = uniqueIdentifier
51-
self.store = store
52-
}
53-
54-
/// Save object to store. _O(1)_
55-
///
56-
/// - Parameter object: object to save.
57-
/// - Throws: JSON encoding error.
58-
public func save(_ object: T) throws {
59-
let data = try encoder.encode(generateDict(for: object))
60-
store.set(data, forKey: key)
61-
}
62-
63-
/// Get object from store. _O(1)_
64-
public var object: T? {
65-
guard let data = store.data(forKey: key) else { return nil }
66-
guard let dict = try? decoder.decode([String: T].self, from: data) else { return nil }
67-
return extractObject(from: dict)
68-
}
69-
70-
/// Delete object from store. _O(1)_
71-
public func delete() {
72-
store.set(nil, forKey: key)
73-
store.removeSuite(named: uniqueIdentifier)
74-
}
29+
/// Store's unique identifier.
30+
///
31+
/// **Warning**: Never use the same identifier for two -or more- different stores.
32+
public let uniqueIdentifier: String
33+
34+
/// JSON encoder. _default is `JSONEncoder()`_
35+
open var encoder = JSONEncoder()
36+
37+
/// JSON decoder. _default is `JSONDecoder()`_
38+
open var decoder = JSONDecoder()
39+
40+
/// UserDefaults store.
41+
private var store: UserDefaults
42+
43+
/// Initialize store with given identifier.
44+
///
45+
/// **Warning**: Never use the same identifier for two -or more- different stores.
46+
///
47+
/// - Parameter uniqueIdentifier: store's unique identifier.
48+
required public init?(uniqueIdentifier: String) {
49+
guard let store = UserDefaults(suiteName: uniqueIdentifier) else { return nil }
50+
self.uniqueIdentifier = uniqueIdentifier
51+
self.store = store
52+
}
53+
54+
/// Save object to store. _O(1)_
55+
///
56+
/// - Parameter object: object to save.
57+
/// - Throws: JSON encoding error.
58+
public func save(_ object: T) throws {
59+
let data = try encoder.encode(generateDict(for: object))
60+
store.set(data, forKey: key)
61+
}
62+
63+
/// Get object from store. _O(1)_
64+
public var object: T? {
65+
guard let data = store.data(forKey: key) else { return nil }
66+
guard let dict = try? decoder.decode([String: T].self, from: data) else { return nil }
67+
return extractObject(from: dict)
68+
}
69+
70+
/// Delete object from store. _O(1)_
71+
public func delete() {
72+
store.set(nil, forKey: key)
73+
store.removeSuite(named: uniqueIdentifier)
74+
}
7575

7676
}
7777

7878
// MARK: - Helpers
7979
private extension SingleUserDefaultsStore {
8080

81-
/// Enclose the object in a dictionary to enable single object storing.
82-
///
83-
/// - Parameter object: object.
84-
/// - Returns: dictionary enclosing object.
85-
func generateDict(for object: T) -> [String: T] {
86-
return ["object": object]
87-
}
88-
89-
/// Extract object from dictionary.
90-
///
91-
/// - Parameter dict: dictionary.
92-
/// - Returns: object.
93-
func extractObject(from dict: [String: T]) -> T? {
94-
return dict["object"]
95-
}
96-
97-
/// Store key for object.
98-
var key: String {
99-
return "\(uniqueIdentifier)-single-object"
100-
}
81+
/// Enclose the object in a dictionary to enable single object storing.
82+
///
83+
/// - Parameter object: object.
84+
/// - Returns: dictionary enclosing object.
85+
func generateDict(for object: T) -> [String: T] {
86+
return ["object": object]
87+
}
88+
89+
/// Extract object from dictionary.
90+
///
91+
/// - Parameter dict: dictionary.
92+
/// - Returns: object.
93+
func extractObject(from dict: [String: T]) -> T? {
94+
return dict["object"]
95+
}
96+
97+
/// Store key for object.
98+
var key: String {
99+
return "\(uniqueIdentifier)-single-object"
100+
}
101101

102102
}

Sources/UserDefaultsStore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@
2424
#import <Foundation/Foundation.h>
2525

2626
FOUNDATION_EXPORT double UserDefaultsStoreVersionNumber;
27-
FOUNDATION_EXPORT const unsigned char UserDefaultsStoreVersionString[];
27+
FOUNDATION_EXPORT const unsigned char UserDefaultsStoreVersionString[];

0 commit comments

Comments
 (0)