Skip to content

Commit 61f97ae

Browse files
committed
Downgrade swift version requirement
1 parent 5925e1a commit 61f97ae

File tree

7 files changed

+497
-14
lines changed

7 files changed

+497
-14
lines changed

.swift-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6.0
1+
5.0

DefaultsKit.xcodeproj/project.pbxproj

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@
623623
PRODUCT_NAME = DefaultsKit;
624624
SKIP_INSTALL = YES;
625625
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
626-
SWIFT_VERSION = 6.0;
626+
SWIFT_VERSION = 5.0;
627627
TARGETED_DEVICE_FAMILY = "1,2";
628628
};
629629
name = Debug;
@@ -650,7 +650,7 @@
650650
PRODUCT_BUNDLE_IDENTIFIER = com.nmdias.DefaultsKit;
651651
PRODUCT_NAME = DefaultsKit;
652652
SKIP_INSTALL = YES;
653-
SWIFT_VERSION = 6.0;
653+
SWIFT_VERSION = 5.0;
654654
TARGETED_DEVICE_FAMILY = "1,2";
655655
};
656656
name = Release;
@@ -668,7 +668,7 @@
668668
MACOSX_DEPLOYMENT_TARGET = 11.0;
669669
PRODUCT_BUNDLE_IDENTIFIER = com.nmdias.DefaultsKitTests;
670670
PRODUCT_NAME = "$(TARGET_NAME)";
671-
SWIFT_VERSION = 6.0;
671+
SWIFT_VERSION = 5.0;
672672
TARGETED_DEVICE_FAMILY = "1,2";
673673
};
674674
name = Debug;
@@ -686,7 +686,7 @@
686686
MACOSX_DEPLOYMENT_TARGET = 11.0;
687687
PRODUCT_BUNDLE_IDENTIFIER = com.nmdias.DefaultsKitTests;
688688
PRODUCT_NAME = "$(TARGET_NAME)";
689-
SWIFT_VERSION = 6.0;
689+
SWIFT_VERSION = 5.0;
690690
TARGETED_DEVICE_FAMILY = "1,2";
691691
};
692692
name = Release;
@@ -716,7 +716,7 @@
716716
PRODUCT_NAME = DefaultsKit;
717717
SDKROOT = macosx;
718718
SKIP_INSTALL = YES;
719-
SWIFT_VERSION = 6.0;
719+
SWIFT_VERSION = 5.0;
720720
};
721721
name = Debug;
722722
};
@@ -745,7 +745,7 @@
745745
PRODUCT_NAME = DefaultsKit;
746746
SDKROOT = macosx;
747747
SKIP_INSTALL = YES;
748-
SWIFT_VERSION = 6.0;
748+
SWIFT_VERSION = 5.0;
749749
};
750750
name = Release;
751751
};
@@ -771,7 +771,7 @@
771771
PRODUCT_NAME = DefaultsKit;
772772
SDKROOT = appletvos;
773773
SKIP_INSTALL = YES;
774-
SWIFT_VERSION = 6.0;
774+
SWIFT_VERSION = 5.0;
775775
TARGETED_DEVICE_FAMILY = 3;
776776
TVOS_DEPLOYMENT_TARGET = 12.0;
777777
};
@@ -799,7 +799,7 @@
799799
PRODUCT_NAME = DefaultsKit;
800800
SDKROOT = appletvos;
801801
SKIP_INSTALL = YES;
802-
SWIFT_VERSION = 6.0;
802+
SWIFT_VERSION = 5.0;
803803
TARGETED_DEVICE_FAMILY = 3;
804804
TVOS_DEPLOYMENT_TARGET = 12.0;
805805
};
@@ -821,7 +821,7 @@
821821
PRODUCT_BUNDLE_IDENTIFIER = "com.nmdias.DefaultsKit-macOS-Tests";
822822
PRODUCT_NAME = "$(TARGET_NAME)";
823823
SDKROOT = macosx;
824-
SWIFT_VERSION = 6.0;
824+
SWIFT_VERSION = 5.0;
825825
};
826826
name = Debug;
827827
};
@@ -841,7 +841,7 @@
841841
PRODUCT_BUNDLE_IDENTIFIER = "com.nmdias.DefaultsKit-macOS-Tests";
842842
PRODUCT_NAME = "$(TARGET_NAME)";
843843
SDKROOT = macosx;
844-
SWIFT_VERSION = 6.0;
844+
SWIFT_VERSION = 5.0;
845845
};
846846
name = Release;
847847
};
@@ -859,7 +859,7 @@
859859
PRODUCT_BUNDLE_IDENTIFIER = "com.nmdias.DefaultsKit-tvOS-Tests";
860860
PRODUCT_NAME = "$(TARGET_NAME)";
861861
SDKROOT = appletvos;
862-
SWIFT_VERSION = 6.0;
862+
SWIFT_VERSION = 5.0;
863863
TARGETED_DEVICE_FAMILY = 3;
864864
TVOS_DEPLOYMENT_TARGET = 12.0;
865865
};
@@ -879,7 +879,7 @@
879879
PRODUCT_BUNDLE_IDENTIFIER = "com.nmdias.DefaultsKit-tvOS-Tests";
880880
PRODUCT_NAME = "$(TARGET_NAME)";
881881
SDKROOT = appletvos;
882-
SWIFT_VERSION = 6.0;
882+
SWIFT_VERSION = 5.0;
883883
TARGETED_DEVICE_FAMILY = 3;
884884
TVOS_DEPLOYMENT_TARGET = 12.0;
885885
};

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version: 6.0
1+
// swift-tools-version: 5.4
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription

Sources/DefaultsKit/Defaults.swift

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
//
2+
// Defaults.swift
3+
//
4+
// Copyright (c) 2017 - 204 Nuno Manuel Dias
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// of this software and associated documentation files (the "Software"), to deal
8+
// in the Software without restriction, including without limitation the rights
9+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// copies of the Software, and to permit persons to whom the Software is
11+
// furnished to do so, subject to the following conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be included in all
14+
// copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
// SOFTWARE.
23+
//
24+
25+
import Foundation
26+
27+
public protocol DefaultsKey {}
28+
29+
/// Represents a `Key` with an associated generic value type conforming to the
30+
/// `Codable` protocol.
31+
///
32+
/// static let someKey = Key<ValueType>("someKey")
33+
public struct Key<ValueType: Codable>: DefaultsKey {
34+
fileprivate let _key: String
35+
public init(_ key: String) {
36+
_key = key
37+
}
38+
}
39+
40+
/// Provides strongly typed values associated with the lifetime
41+
/// of an application. Apropriate for user preferences.
42+
/// - Warning
43+
/// These should not be used to store sensitive information that could compromise
44+
/// the application or the user's security and privacy.
45+
public struct Defaults {
46+
private var userDefaults: UserDefaults
47+
48+
/// Shared instance of `Defaults`, used for ad-hoc access to the user's
49+
/// defaults database throughout the app.
50+
public nonisolated(unsafe) static let shared = Defaults()
51+
52+
/// An instance of `Defaults` with the specified `UserDefaults` instance.
53+
///
54+
/// - Parameter userDefaults: The UserDefaults.
55+
public init(userDefaults: UserDefaults = UserDefaults.standard) {
56+
self.userDefaults = userDefaults
57+
}
58+
59+
/// Deletes the value associated with the specified key, if any.
60+
///
61+
/// - Parameter key: The key.
62+
public func clear<ValueType>(_ key: Key<ValueType>) {
63+
userDefaults.set(nil, forKey: key._key)
64+
userDefaults.synchronize()
65+
}
66+
67+
/// Checks if there is a value associated with the specified key.
68+
///
69+
/// - Parameter key: The key to look for.
70+
/// - Returns: A boolean value indicating if a value exists for the specified key.
71+
public func has<ValueType>(_ key: Key<ValueType>) -> Bool {
72+
return userDefaults.value(forKey: key._key) != nil
73+
}
74+
75+
/// Returns the value associated with the specified key.
76+
///
77+
/// - Parameter key: The key.
78+
/// - Returns: A `ValueType` or nil if the key was not found.
79+
public func get<ValueType>(for key: Key<ValueType>) -> ValueType? {
80+
if isSwiftCodableType(ValueType.self) || isFoundationCodableType(ValueType.self) {
81+
return userDefaults.value(forKey: key._key) as? ValueType
82+
}
83+
84+
guard let data = userDefaults.data(forKey: key._key) else {
85+
return nil
86+
}
87+
88+
do {
89+
let decoder = JSONDecoder()
90+
let decoded = try decoder.decode(ValueType.self, from: data)
91+
return decoded
92+
} catch {
93+
#if DEBUG
94+
print(error)
95+
#endif
96+
}
97+
98+
return nil
99+
}
100+
101+
/// Sets a value associated with the specified key.
102+
///
103+
/// - Parameters:
104+
/// - some: The value to set.
105+
/// - key: The associated `Key<ValueType>`.
106+
public func set<ValueType>(_ value: ValueType, for key: Key<ValueType>) {
107+
if isSwiftCodableType(ValueType.self) || isFoundationCodableType(ValueType.self) {
108+
userDefaults.set(value, forKey: key._key)
109+
return
110+
}
111+
112+
do {
113+
let encoder = JSONEncoder()
114+
let encoded = try encoder.encode(value)
115+
userDefaults.set(encoded, forKey: key._key)
116+
userDefaults.synchronize()
117+
} catch {
118+
#if DEBUG
119+
print(error)
120+
#endif
121+
}
122+
}
123+
124+
// MARK: - RawRepresentable
125+
126+
/// Returns the value associated with the specified key.
127+
///
128+
/// - Parameter key: The key.
129+
/// - Returns: A `ValueType` or nil if the key was not found.
130+
public func get<ValueType: RawRepresentable>(for key: Key<ValueType>) -> ValueType? where ValueType.RawValue: Codable {
131+
let convertedKey = Key<ValueType.RawValue>(key._key)
132+
if let raw = get(for: convertedKey) {
133+
return ValueType(rawValue: raw)
134+
}
135+
return nil
136+
}
137+
138+
/// Sets a value associated with the specified key.
139+
///
140+
/// - Parameters:
141+
/// - some: The value to set.
142+
/// - key: The associated `Key<ValueType>`.
143+
public func set<ValueType: RawRepresentable>(_ value: ValueType, for key: Key<ValueType>) where ValueType.RawValue: Codable {
144+
let convertedKey = Key<ValueType.RawValue>(key._key)
145+
set(value.rawValue, for: convertedKey)
146+
}
147+
148+
/// Removes given bundle's persistent domain
149+
///
150+
/// - Parameter type: Bundle.
151+
public func removeAll(bundle: Bundle = Bundle.main) {
152+
guard let name = bundle.bundleIdentifier else { return }
153+
userDefaults.removePersistentDomain(forName: name)
154+
}
155+
156+
/// Checks if the specified type is a Codable from the Swift standard library.
157+
///
158+
/// - Parameter type: The type.
159+
/// - Returns: A boolean value.
160+
private func isSwiftCodableType<ValueType>(_ type: ValueType.Type) -> Bool {
161+
switch type {
162+
case is String.Type, is Bool.Type, is Int.Type, is Float.Type, is Double.Type:
163+
return true
164+
default:
165+
return false
166+
}
167+
}
168+
169+
/// Checks if the specified type is a Codable, from the Swift's core libraries
170+
/// Foundation framework.
171+
///
172+
/// - Parameter type: The type.
173+
/// - Returns: A boolean value.
174+
private func isFoundationCodableType<ValueType>(_ type: ValueType.Type) -> Bool {
175+
switch type {
176+
case is Date.Type:
177+
return true
178+
default:
179+
return false
180+
}
181+
}
182+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// DefaultsKey + keys.swift
3+
//
4+
// Copyright (c) 2017 - 2024 Nuno Manuel Dias
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// of this software and associated documentation files (the "Software"), to deal
8+
// in the Software without restriction, including without limitation the rights
9+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// copies of the Software, and to permit persons to whom the Software is
11+
// furnished to do so, subject to the following conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be included in all
14+
// copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
// SOFTWARE.
23+
//
24+
25+
@testable import DefaultsKit
26+
import Foundation
27+
28+
extension DefaultsKey {
29+
static var integerKey: Key<Int> { Key("integerKey") }
30+
static var floatKey: Key<Float> { Key("floatKey") }
31+
static var doubleKey: Key<Double> { Key("doubleKey") }
32+
static var stringKey: Key<String> { Key("stringKey") }
33+
static var boolKey: Key<Bool> { Key("boolKey") }
34+
static var dateKey: Key<Date> { Key("dateKey") }
35+
static var enumKey: Key<EnumMock> { Key("enumKey") }
36+
static var optionSetKey: Key<OptionSetMock> { Key("optionSetKey") }
37+
static var arrayOfIntegersKey: Key<[Int]> { Key("arrayOfIntegersKey") }
38+
static var personMockKey: Key<PersonMock> { Key("personMockKey") }
39+
}

0 commit comments

Comments
 (0)