FetchRequests 4.0.0

FetchRequests 4.0.0

Maintained by Adam Lickel.



  • By
  • Square

FetchRequests

FetchRequests is an eventing library inspired by NSFetchedResultsController and written in Swift.

Build Status codecov CocoaPods Compatible Carthage Compatible Platform Pod License

Features

  • Sort and section a list of items
  • Listen for live updates
  • Animate underlying data changes
  • Fetch associated values in batch
  • Support paginated requests
  • SwiftUI Integration
  • Comprehensive Unit Test Coverage

Usage

FetchRequests can be used for any combination of networking, database, and file queries. It is best when backed by something like a WebSocket where you're expecting your data to live update.

To get started, you create a FetchRequest which explains your data access patterns. The FetchedResultsController is the interface to access the your data. Objects are sorted with the following heuristic:

  • Section Name ascending (if present)
  • Passed in sort descriptors
  • Insertion order of the entity ascending

You can associate related values to your fetched entities. It will automatically cache these associated values for the lifetime of that controller. If a memory pressure event occurs, it will release its hold on those objects, allowing them to be de-inited.

The example app has an UserDefaults-backed storage mechanism. The unit tests have in-memory objects, with NotificationCenter eventing.

Today, it is heavily dependent on the Obj-C runtime, as well as Key-Value Observation. It should be possible to further remove those restrictions, and some effort has been made to remove them.

SwiftUI

There are two SwiftUI Property Wrappers available for use, FetchableRequest and SectionedFetchableRequest. These are analagous to CoreData's property wrappers.

The controller will perform a fetch once and only once upon the first view render. After that point, it is dependent upon live update events.

Examples:

struct AllUsersView: View {
    @FetchableRequest(
        definition: FetchDefinition(request: User.fetchAll),
        sortDescriptors: [
            NSSortDescriptor(
                key: #keyPath(User.name),
                ascending: true,
                selector: #selector(NSString.localizedStandardCompare)
            ),
        ]
    )
    private var members: FetchableResults<User>

    // ...
}

For more complicated use cases, you probably will need to write initializers for your view, for example:

struct MembersView: View {
    private let fromID: EntityID

    @FetchableRequest
    private var members: FetchableResults<Membership>

    func init(fromID: EntityID) {
        self.fromID = fromID
        _members = FetchableRequest(
            definition: Membership.fetchDefinition(from: fromID, toEntityType: .user)
        )
    }

    // ...
}

Requirements

  • iOS 13+ / macOS 10.15+ / tvOS 13+ / watchOS 6+
  • Xcode 12+
  • Swift 5+

Communication

  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

Installation

CocoaPods

Install with CocoaPods by specifying the following in your Podfile:

pod 'FetchRequests', '~> 4.0'

Carthage

Install with Carthage by specify the following in your Cartfile:

github "square/FetchRequests" ~> 4.0

Swift Package Manager

Install with Swift Package Manager by adding it to the dependencies value of your Package.swift:

dependencies: [
    .package(url: "https://github.com/square/FetchRequests.git", from: "4.0.0")
]

Contributing

If you would like to contribute code to FetchRequests you can do so through GitHub by forking the repository and sending a pull request.

When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible.

Before your code can be accepted into the project you must also sign the Individual Contributor License Agreement (CLA).

License

FetchRequests is released under the MIT license. See LICENSE for details.