Skip to content
Merged
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
7 changes: 7 additions & 0 deletions .swiftformat
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@

--rules blankLineAfterImports
--rules braces
--rules conditionalAssignment
--rules duplicateImports
--rules elseOnSameLine
--rules genericExtensions

--rules hoistAwait
--rules hoistTry

--rules indent
--indent 4
--indentcase false
Expand All @@ -20,11 +24,14 @@
--rules leadingDelimiters
--rules linebreakAtEndOfFile

--rules redundantClosure
--rules redundantFileprivate
--rules redundantGet
--rules redundantInit
--rules redundantOptionalBinding
--rules redundantParens
--rules redundantPattern
--rules redundantReturn
--rules redundantVoidReturnType
--rules semicolons

Expand Down
20 changes: 13 additions & 7 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ disabled_rules:
- opening_brace
- unused_closure_parameter
- unused_optional_binding
# Nice to haves
- cyclomatic_complexity
- function_body_length
- line_length
opt_in_rules:
analyzer_rules:
- capture_variable
- unused_declaration
- unused_import
opt_in_rules:
- balanced_xctest_lifecycle
- closure_spacing
- closure_end_indentation
- collection_alignment
Expand Down Expand Up @@ -55,14 +60,15 @@ opt_in_rules:
- redundant_nil_coalescing
- redundant_objc_attribute
- self_binding
- single_test_class
- shorthand_optional_binding
- sorted_first_last
- static_operator
- strong_iboutlet
- test_case_accessibility
- toggle_bool
- trailing_closure
- untyped_error_in_catch
- unused_import
- unused_declaration
- vertical_parameter_alignment_on_call
- vertical_whitespace_between_cases
- vertical_whitespace_opening_braces
Expand Down Expand Up @@ -94,7 +100,7 @@ large_tuple:
warning: 3
error: 4
deployment_target:
iOS_deployment_target: 13
tvOS_deployment_target: 13
watchOS_deployment_target: 6
macOS_deployment_target: 10.15
iOS_deployment_target: 14
tvOS_deployment_target: 14
watchOS_deployment_target: 7
macOS_deployment_target: 11
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@
All notable changes to this project will be documented in this file.
`FetchRequests` adheres to [Semantic Versioning](https://semver.org/).

## [6.0](https://github.com/square/FetchRequests/releases/tag/5.0.0)
Released on 2023-04-05

* Requires Swift 5.8
* FetchableEntityID's async methods are now marked as @MainActor
* Association Request completion handlers are now marked as @MainActor
* Previously the handler would immediately bounce to the main thread if needed
* Bump deployment targets:
* iOS, tvOS, Catalyst: v14
* watchOS v7
* macOS v11

## [5.0](https://github.com/square/FetchRequests/releases/tag/5.0.0)
Released on 2022-10-25

Expand Down
4 changes: 2 additions & 2 deletions Example/iOS-Example/Atomic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ struct Atomic<Value> {

var wrappedValue: Value {
get {
return queue.sync { storage }
queue.sync { storage }
}
set {
queue.sync(flags: .barrier) { storage = newValue }
}
}

mutating func mutate(_ mutation: (inout Value) throws -> Void) rethrows {
return try queue.sync(flags: .barrier) {
try queue.sync(flags: .barrier) {
try mutation(&storage)
}
}
Expand Down
12 changes: 6 additions & 6 deletions Example/iOS-Example/Model+Persistence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ private let decoder = JSONDecoder()

extension Model {
func rawObjectEventUpdated() -> Notification.Name {
return Notification.Name("\(NSStringFromClass(type(of: self))).rawObjectEventUpdated.\(id)")
Notification.Name("\(NSStringFromClass(type(of: self))).rawObjectEventUpdated.\(id)")
}

class func objectWasCreated() -> Notification.Name {
return Notification.Name("\(NSStringFromClass(self)).objectWasCreated")
Notification.Name("\(NSStringFromClass(self)).objectWasCreated")
}

class func objectWasDeleted() -> Notification.Name {
return Notification.Name("\(NSStringFromClass(self)).objectWasDeleted")
Notification.Name("\(NSStringFromClass(self)).objectWasDeleted")
}

class func dataWasCleared() -> Notification.Name {
return Notification.Name("\(NSStringFromClass(self)).dataWasCleared")
Notification.Name("\(NSStringFromClass(self)).dataWasCleared")
}
}

Expand Down Expand Up @@ -125,7 +125,7 @@ extension Model {

extension NSObjectProtocol where Self: Model {
static func fetchAll() -> [Self] {
return storage.values.lazy.compactMap { value in
storage.values.lazy.compactMap { value in
value as? Data
}.compactMap { data in
try? decoder.decode(Model.RawData.self, from: data)
Expand All @@ -135,7 +135,7 @@ extension NSObjectProtocol where Self: Model {
}

static func fetch(byID id: Model.ID) -> Self? {
return storage[id].flatMap { value in
storage[id].flatMap { value in
value as? Data
}.flatMap { data in
try? decoder.decode(Model.RawData.self, from: data)
Expand Down
8 changes: 4 additions & 4 deletions Example/iOS-Example/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class Model: NSObject {

extension Model: Identifiable {
var id: ID {
return data.id
data.id
}
}

Expand All @@ -110,13 +110,13 @@ extension Model {

extension Model: FetchableObjectProtocol {
func observeDataChanges(_ handler: @escaping @MainActor () -> Void) -> InvalidatableToken {
return _data.observeChanges { change in
_data.observeChanges { change in
handler()
}
}

func observeIsDeletedChanges(_ handler: @escaping @MainActor () -> Void) -> InvalidatableToken {
return self.observe(\.isDeleted, options: [.old, .new]) { @MainActor(unsafe) object, change in
self.observe(\.isDeleted, options: [.old, .new]) { @MainActor(unsafe) object, change in
guard let old = change.oldValue, let new = change.newValue, old != new else {
return
}
Expand All @@ -125,7 +125,7 @@ extension Model: FetchableObjectProtocol {
}

static func entityID(from data: RawData) -> Model.ID? {
return data.id
data.id
}

func listenForUpdates() {
Expand Down
2 changes: 1 addition & 1 deletion Example/iOS-Example/Observable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Observable<Value> {

extension Observable where Value: Equatable {
func observeChanges(handler: @escaping Handler) -> InvalidatableToken {
return observe { change in
observe { change in
guard change.oldValue != change.newValue else {
return
}
Expand Down
6 changes: 3 additions & 3 deletions Example/iOS-Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ViewController: UITableViewController {
}

class var reuseIdentifier: String {
return NSStringFromClass(self)
NSStringFromClass(self)
}
}
}
Expand Down Expand Up @@ -69,11 +69,11 @@ extension ViewController {

extension ViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return controller.sections.count
controller.sections.count
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return controller.sections[section].numberOfObjects
controller.sections[section].numberOfObjects
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
Expand Down
10 changes: 5 additions & 5 deletions FetchRequests.podspec
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
Pod::Spec.new do |s|
s.name = 'FetchRequests'
s.version = '5.0.0'
s.version = '6.0.0'
s.license = 'MIT'
s.summary = 'NSFetchedResultsController inspired eventing'
s.homepage = 'https://github.com/square/FetchRequests'
s.authors = 'Square'
s.source = { :git => 'https://github.com/square/FetchRequests.git', :tag => s.version }

ios_deployment_target = '13.0'
tvos_deployment_target = '13.0'
watchos_deployment_target = '6.0'
macos_deployment_target = '10.15'
ios_deployment_target = '14.0'
tvos_deployment_target = '14.0'
watchos_deployment_target = '7.0'
macos_deployment_target = '11'

s.ios.deployment_target = ios_deployment_target
s.tvos.deployment_target = tvos_deployment_target
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class AssociatedValueReference: NSObject {
fileprivate var changeHandler: ChangeHandler?

var canObserveCreation: Bool {
return creationObserver != nil
creationObserver != nil
}

init(
Expand Down
24 changes: 12 additions & 12 deletions FetchRequests/Sources/Associations/FetchRequestAssociation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ public enum AssociationReplacement<T> {
/// Map an associated value's key to object
public class FetchRequestAssociation<FetchedObject: FetchableObject> {
/// Fetch associated values given a list of parent objects
public typealias AssocationRequestByParent<AssociatedEntity> = @MainActor (_ objects: [FetchedObject], _ completion: @escaping ([FetchedObject.ID: AssociatedEntity]) -> Void) -> Void
public typealias AssocationRequestByParent<AssociatedEntity> = @MainActor (_ objects: [FetchedObject], _ completion: @escaping @MainActor ([FetchedObject.ID: AssociatedEntity]) -> Void) -> Void
/// Fetch associated values given a list of associated IDs
public typealias AssocationRequestByID<AssociatedEntityID: Hashable, AssociatedEntity> = @MainActor (_ objects: [AssociatedEntityID], _ completion: @escaping ([AssociatedEntity]) -> Void) -> Void
public typealias AssocationRequestByID<AssociatedEntityID: Hashable, AssociatedEntity> = @MainActor (_ objects: [AssociatedEntityID], _ completion: @escaping @MainActor ([AssociatedEntity]) -> Void) -> Void
/// Event that represents the creation of an associated value object
public typealias CreationObserved<Value, Comparison> = (Value?, Comparison) -> AssociationReplacement<Value>
/// Start observing a source object
Expand Down Expand Up @@ -93,7 +93,7 @@ public extension FetchRequestAssociation {
},
referenceGenerator: { _ in AssociatedValueReference() },
observeKeyPath: { object, changeHandler in
return object.observe(keyPath, options: [.old, .new]) { object, change in
object.observe(keyPath, options: [.old, .new]) { object, change in
guard change.oldValue != change.newValue else {
return
}
Expand All @@ -117,7 +117,7 @@ public extension FetchRequestAssociation {
},
referenceGenerator: { _ in AssociatedValueReference() },
observeKeyPath: { object, changeHandler in
return object.observe(keyPath, options: [.old, .new]) { object, change in
object.observe(keyPath, options: [.old, .new]) { object, change in
guard change.oldValue != change.newValue else {
return
}
Expand Down Expand Up @@ -184,7 +184,7 @@ public extension FetchRequestAssociation {
},
referenceGenerator: referenceGenerator,
observeKeyPath: { object, changeHandler in
return object.observe(keyPath, options: [.old, .new]) { object, change in
object.observe(keyPath, options: [.old, .new]) { object, change in
guard change.oldValue != change.newValue else {
return
}
Expand Down Expand Up @@ -247,7 +247,7 @@ public extension FetchRequestAssociation {
},
referenceGenerator: referenceGenerator,
observeKeyPath: { object, changeHandler in
return object.observe(keyPath, options: [.old, .new]) { object, change in
object.observe(keyPath, options: [.old, .new]) { object, change in
guard change.oldValue != change.newValue else {
return
}
Expand Down Expand Up @@ -387,7 +387,7 @@ public extension FetchRequestAssociation {
request: rawRequest,
referenceGenerator: referenceGenerator,
observeKeyPath: { object, changeHandler in
return object.observe(keyPath, options: [.old, .new]) { object, change in
object.observe(keyPath, options: [.old, .new]) { object, change in
guard change.oldValue != change.newValue else {
return
}
Expand Down Expand Up @@ -479,7 +479,7 @@ public extension FetchRequestAssociation {
request: rawRequest,
referenceGenerator: referenceGenerator,
observeKeyPath: { object, changeHandler in
return object.observe(keyPath, options: [.old, .new]) { object, change in
object.observe(keyPath, options: [.old, .new]) { object, change in
guard change.oldValue != change.newValue else {
return
}
Expand Down Expand Up @@ -607,7 +607,7 @@ public extension FetchRequestAssociation {
request: rawRequest,
referenceGenerator: referenceGenerator,
observeKeyPath: { object, changeHandler in
return object.observe(keyPath, options: [.old, .new]) { object, change in
object.observe(keyPath, options: [.old, .new]) { object, change in
guard change.oldValue != change.newValue else {
return
}
Expand Down Expand Up @@ -731,7 +731,7 @@ public extension FetchRequestAssociation {
request: rawRequest,
referenceGenerator: referenceGenerator,
observeKeyPath: { object, changeHandler in
return object.observe(keyPath, options: [.old, .new]) { object, change in
object.observe(keyPath, options: [.old, .new]) { object, change in
guard change.oldValue != change.newValue else {
return
}
Expand Down Expand Up @@ -898,7 +898,7 @@ public extension FetchRequestAssociation {

private extension Sequence {
func associated<Key: Hashable>(by keySelector: (Element) throws -> Key) rethrows -> [Key: Element] {
return try reduce(into: [:]) { memo, element in
try reduce(into: [:]) { memo, element in
let key = try keySelector(element)
memo[key] = element
}
Expand All @@ -907,6 +907,6 @@ private extension Sequence {

private extension Sequence where Element: FetchableObjectProtocol {
func createLookupTable() -> [Element.ID: Element] {
return self.associated(by: \.id)
self.associated(by: \.id)
}
}
17 changes: 13 additions & 4 deletions FetchRequests/Sources/Associations/FetchableEntityID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,25 @@ public protocol FetchableEntityID<FetchableEntity>: Hashable {
static func fetch(byID objectID: Self) -> FetchableEntity?
static func fetch(byIDs objectIDs: [Self]) -> [FetchableEntity]

static func fetch(byID objectID: Self, completion: @escaping (FetchableEntity?) -> Void)
static func fetch(byIDs objectIDs: [Self], completion: @escaping ([FetchableEntity]) -> Void)
static func fetch(
byID objectID: Self,
completion: @escaping @MainActor (FetchableEntity?) -> Void
)
static func fetch(
byIDs objectIDs: [Self],
completion: @escaping @MainActor ([FetchableEntity]) -> Void
)
}

extension FetchableEntityID {
static func fetch(byID objectID: Self) -> FetchableEntity? {
return self.fetch(byIDs: [objectID]).first
self.fetch(byIDs: [objectID]).first
}

static func fetch(byID objectID: Self, completion: @escaping (FetchableEntity?) -> Void) {
static func fetch(
byID objectID: Self,
completion: @escaping @MainActor (FetchableEntity?) -> Void
) {
self.fetch(byIDs: [objectID]) { objects in
completion(objects.first)
}
Expand Down
2 changes: 1 addition & 1 deletion FetchRequests/Sources/Associations/ObservableToken.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ internal class FetchRequestObservableToken<Parameter>: ObservableToken {
private let _invalidate: () -> Void

var isObserving: Bool {
return synchronized(self) {
synchronized(self) {
unsafeIsObserving
}
}
Expand Down
Loading