Skip to content

Commit 042e3ef

Browse files
authored
Merge pull request #37 from square/array-associations
Array associations
2 parents 720319b + b63c58e commit 042e3ef

22 files changed

Lines changed: 303 additions & 167 deletions

.swiftformat

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--swiftversion 5.5
2+
3+
--exclude Pods
4+
5+
--rules anyObjectProtocol
6+
7+
--rules braces
8+
9+
--rules duplicateImports
10+
--rules elseOnSameLine
11+
12+
--rules strongifiedSelf
13+
--rules andOperator
14+
15+
--rules indent
16+
--indent 4
17+
--indentcase false
18+
--indentstrings true
19+
--ifdef outdent
20+
21+
--rules leadingDelimiters
22+
--rules linebreakAtEndOfFile
23+
24+
--rules redundantGet
25+
--rules redundantInit
26+
--rules redundantParens
27+
--rules redundantVoidReturnType
28+
--rules semicolons
29+
--rules spaceAroundBraces
30+
--rules spaceAroundBrackets
31+
--rules spaceAroundGenerics
32+
33+
--rules spaceAroundOperators
34+
--rules spaceAroundParens
35+
--rules spaceInsideBraces
36+
--rules spaceInsideBrackets
37+
--rules spaceInsideComments
38+
--rules spaceInsideGenerics
39+
--rules spaceInsideParens
40+
--rules todos
41+
42+
--rules trailingCommas
43+
--rules trailingSpace
44+
--rules typeSugar
45+
--rules void
46+
47+
--rules wrapArguments
48+
--wraparguments before-first
49+
--wrapcollections before-first
50+
--wrapparameters before-first
51+
52+
--rules wrapMultilineStatementBraces

.swiftlint.yml

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,50 +9,64 @@ disabled_rules:
99
- function_body_length
1010
- line_length
1111
opt_in_rules:
12-
- sorted_first_last
12+
- capture_variable
1313
- closure_spacing
1414
- closure_end_indentation
15+
- collection_alignment
16+
- comment_spacing
1517
- conditional_returns_on_newline
1618
- contains_over_first_not_nil
19+
- contains_over_filter_count
20+
- contains_over_filter_is_empty
21+
- contains_over_range_nil_comparison
22+
- discarded_notification_center_observer
1723
- empty_count
24+
- empty_collection_literal
25+
- empty_string
26+
- empty_xctest_method
1827
- explicit_init
1928
- fatal_error_message
2029
- first_where
30+
- flatmap_over_map_reduce
31+
- identical_operands
2132
- implicitly_unwrapped_optional
33+
- joined_default_parameter
34+
- last_where
35+
- legacy_random
2236
- literal_expression_end_indentation
37+
- lower_acl_than_parent
38+
- modifier_order
2339
- multiline_arguments
2440
- multiline_parameters
41+
- multiline_arguments_brackets
42+
- multiline_literal_brackets
43+
- multiline_parameters_brackets
44+
- nslocalizedstring_key
2545
- number_separator
46+
- optional_enum_case_matching
2647
- overridden_super_call
2748
- pattern_matching_keywords
49+
- prefer_self_type_over_type_of_self
2850
- prohibited_super_call
2951
- private_outlet
52+
- private_subject
53+
- private_unit_test
54+
- reduce_into
3055
- redundant_nil_coalescing
31-
- vertical_parameter_alignment_on_call
32-
- untyped_error_in_catch
33-
- empty_string
34-
- empty_xctest_method
35-
- lower_acl_than_parent
36-
- modifier_order
56+
- redundant_objc_attribute
57+
- sorted_first_last
3758
- static_operator
38-
- collection_alignment
39-
- identical_operands
59+
- strong_iboutlet
4060
- toggle_bool
41-
- legacy_random
61+
- trailing_closure
62+
- untyped_error_in_catch
4263
- unused_import
4364
- unused_declaration
65+
- vertical_parameter_alignment_on_call
4466
- vertical_whitespace_between_cases
45-
- redundant_objc_attribute
46-
- multiline_arguments_brackets
47-
- multiline_literal_brackets
48-
- multiline_parameters_brackets
49-
- nslocalizedstring_key
50-
- last_where
5167
- vertical_whitespace_opening_braces
5268
- vertical_whitespace_closing_braces
53-
- strong_iboutlet
5469
- xct_specific_matcher
55-
- trailing_closure
5670
excluded:
5771
- Pods
5872

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
All notable changes to this project will be documented in this file.
33
`FetchRequests` adheres to [Semantic Versioning](https://semver.org/).
44

5+
## [4.0.3](https://github.com/square/FetchRequests/releases/tag/4.0.3)
6+
Released on 2022-05-XX
7+
8+
* Support array associations by an arbitrary reference instead of just by ID. This is specified via a new referenceAccessor parameter.
9+
* Updated example to use Codable model
10+
* Updated linting
11+
512
## [4.0.2](https://github.com/square/FetchRequests/releases/tag/4.0.2)
613
Released on 2021-12-14
714

8-
* Expose `hasFetchedObjects` on FetchableRequest and SectionedFetchableRequest. It has the same semantics as the a Controller.
15+
* Expose `hasFetchedObjects` on FetchableRequest and SectionedFetchableRequest. It has the same semantics as the property on the Controller.
916

1017
## [4.0.1](https://github.com/square/FetchRequests/releases/tag/4.0.1)
1118
Released on 2021-10-20

Example/iOS-Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

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

Example/iOS-Example/AppDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2121
rootViewController: ViewController()
2222
)
2323
window?.makeKeyAndVisible()
24-
24+
2525
return true
2626
}
2727
}

Example/iOS-Example/Model+Persistence.swift

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import FetchRequests
1212

1313
enum ModelError: Error {
1414
case invalidDate
15-
case cannotInflate
1615
}
1716

17+
private let encoder = JSONEncoder()
18+
private let decoder = JSONDecoder()
19+
1820
// MARK: - Event Notifications
1921

2022
extension Model {
@@ -45,24 +47,22 @@ extension Model {
4547
return UserDefaults.standard.dictionary(forKey: key) ?? [:]
4648
}
4749

48-
fileprivate class func updateStorage(_ block: (inout [String: Any]) -> Void) {
50+
fileprivate class func updateStorage(_ block: (inout [String: Any]) throws -> Void) rethrows {
4951
assert(Thread.isMainThread)
5052

5153
let defaults = UserDefaults.standard
5254
let key = NSStringFromClass(self)
5355

5456
var storage = defaults.dictionary(forKey: key) ?? [:]
55-
block(&storage)
57+
try block(&storage)
5658
defaults.set(storage, forKey: key)
5759
}
5860

5961
private class func validateCanUpdate(_ originalModel: Model) throws -> Model {
60-
var data = originalModel.data.dictionary ?? [:]
61-
data["updatedAt"] = Date().timeIntervalSince1970
62+
var data = originalModel.data
63+
data.updatedAt = Date()
6264

63-
guard let json = JSON(data), let model = self.init(data: json) else {
64-
throw ModelError.cannotInflate
65-
}
65+
let model = Model(data: data)
6666

6767
guard model.createdAt != .distantPast else {
6868
throw ModelError.invalidDate
@@ -73,8 +73,8 @@ extension Model {
7373
return model
7474
}
7575
guard existing.updatedAt <= model.updatedAt,
76-
existing.createdAt == model.createdAt else
77-
{
76+
existing.createdAt == model.createdAt
77+
else {
7878
throw ModelError.invalidDate
7979
}
8080

@@ -85,8 +85,9 @@ extension Model {
8585
class func save(_ originalModel: Model) throws {
8686
let model = try validateCanUpdate(originalModel)
8787

88-
updateStorage {
89-
$0[model.id] = model.data.object
88+
try updateStorage {
89+
let data = try encoder.encode(model.data)
90+
$0[model.id] = data
9091
}
9192

9293
NotificationCenter.default.post(
@@ -124,17 +125,21 @@ extension Model {
124125

125126
extension NSObjectProtocol where Self: Model {
126127
static func fetchAll() -> [Self] {
127-
return storage.values.lazy.compactMap {
128-
Self.RawData($0)
129-
}.compactMap {
128+
return storage.values.lazy.compactMap { value in
129+
value as? Data
130+
}.compactMap { data in
131+
try? decoder.decode(Model.RawData.self, from: data)
132+
}.map {
130133
Self(data: $0)
131134
}
132135
}
133136

134137
static func fetch(byID id: Model.ID) -> Self? {
135-
return storage[id].flatMap {
136-
Self.RawData($0)
137-
}.flatMap {
138+
return storage[id].flatMap { value in
139+
value as? Data
140+
}.flatMap { data in
141+
try? decoder.decode(Model.RawData.self, from: data)
142+
}.map {
138143
Self(data: $0)
139144
}
140145
}

0 commit comments

Comments
 (0)