A simple CoreData query language for Swift and Objective-C.

Related tags

Core Data QueryKit
Overview

QueryKit Logo

QueryKit

QueryKit, a simple type-safe Core Data query language.

Usage

QuerySet<Person>(context, "Person")
  .orderedBy(.name, ascending: true)
  .filter(\.age >= 18)

QuerySet

A QuerySet represents a collection of objects from your Core Data Store. It may have zero, one or many filters. Filters narrow down the query results based on the given parameters.

Retrieving all objects

let queryset = QuerySet<Person>(context, "Person")

Retrieving specific objects with filters

You may filter a QuerySet using the filter and exclude methods, which accept a predicate which can be constructed using KeyPath extensions.

The filter and exclude methods return new QuerySet's including your filter.

queryset.filter(\.name == "Kyle")
queryset.exclude(\.age > 25)

You may also use standard NSPredicate if you want to construct complicated queries or do not wish to use the type-safe properties.

queryset.filter(NSPredicate(format: "name == '%@'", "Kyle"))
queryset.exclude(NSPredicate(format: "age > 25"))
Chaining filters

The result of refining a QuerySet is itself a QuerySet, so it’s possible to chain refinements together. For example:

queryset.filter(\.name == "Kyle")
       .exclude(\.age < 25)

Each time you refine a QuerySet, you get a new QuerySet instance that is in no way bound to the previous QuerySet. Each refinement creates a separate and distinct QuerySet that may be stored, used and reused.

QuerySets are lazy

A QuerySet is lazy, creating a QuerySet doesn’t involve querying Core Data. QueryKit won’t actually execute the query until the QuerySet is evaluated.

Ordering

You may order a QuerySet's results by using the orderBy function which accepts a KeyPath.

queryset.orderBy(\.name, ascending: true)

You may also pass in an NSSortDescriptor if you would rather.

queryset.orderBy(NSSortDescriptor(key: "name", ascending: true))

Slicing

Using slicing, a QuerySet's results may be limited to a specified range. For example, to get the first 5 items in our QuerySet:

queryset[0...5]

NOTE: Remember, QuerySets are lazily evaluated. Slicing doesn’t evaluate the query.

Fetching

Multiple objects

You may convert a QuerySet to an array using the array() function. For example:

for person in try! queryset.array() {
  println("Hello \(person.name).")
}
First object
let kyle = try? queryset.first()
Last object
let kyle = try? queryset.last()
Object at index
let katie = try? queryset.object(3)
Count
let numberOfPeople = try? queryset.count()
Deleting

This method immediately deletes the objects in your queryset and returns a count or an error if the operation failed.

let deleted = try? queryset.delete()
Operators

QueryKit provides KeyPath extensions providing operator functions allowing you to create predicates.

// Name is equal to Kyle
\Person.name == "Kyle"

// Name is either equal to Kyle or Katie
\.Person.name << ["Kyle", "Katie"]

// Age is equal to 27
\.Person.age == 27

// Age is more than or equal to 25
\Person.age >= 25

// Age is within the range 22 to 30.
\Person.age << (22...30)

The following types of comparisons are supported using Attribute:

Comparison Meaning
== x equals y
!= x is not equal to y
< x is less than y
<= x is less than or equal to y
> x is more than y
>= x is more than or equal to y
~= x is like y
~= x is like y
<< x IN y, where y is an array
<< x BETWEEN y, where y is a range
Predicate extensions

QueryKit provides the !, && and || operators for joining multiple predicates together.

// Persons name is Kyle or Katie
\Person.name == "Kyle" || \Person.name == "Katie"

// Persons age is more than 25 and their name is Kyle
\Person.age >= 25 && \Person.name == "Kyle"

// Persons name is not Kyle
!(\Person.name == "Kyle")

Installation

CocoaPods is the recommended way to add QueryKit to your project, you may also use Carthage.

pod 'QueryKit'

License

QueryKit is released under the BSD license. See LICENSE.

Issues
  • Pods installation error

    Pods installation error

    I add QueryKit as a pod to project pod 'QueryKit', '~> 0.11'

    When I build it I get an error Pods/QueryKit/QueryKit/QueryKit.h:10:9: Include of non-modular header inside framework module 'QueryKit.QueryKit'

    screen shot 2015-11-03 at 11 12 13

    opened by kostiakoval 14
  • Xcode 6.3 / Swift 1.2 support

    Xcode 6.3 / Swift 1.2 support

    @kylef do you have plans to get the repo compatible with Xcode 6.3 / Swift 1.2? I've made some progress in a fork and it all seems straightforward except a few things with attributes.

    opened by robertjpayne 11
  • Add new operators

    Add new operators

    Add new operators for IN, BETWEEN and LIKE.

    Also added a .gitignore file.

    opened by bastos 10
  • Predicates to compare to nil

    Predicates to compare to nil

    When I try to create a filter that excludes or includes nil values, I'm getting an error message:

    queryset.filter{ $0.configuration == nil }
    

    Type of expresion is ambiguous without more context

    If I try to create a predicate instead:

    let predicate = Widget.configuration == nil
    

    Value of type 'Attribute' can never be nil, comparison isn't allowed

    What am I doing wrong?

    opened by victor 10
  • Generic Attribute Class/Struct

    Generic Attribute Class/Struct

    Would this be useful at all? Adds some more type safety (agePredicateFailure gives an error: Could not find an overload for '==' that accepts the supplied arguments which isn't really the best).

    import CoreData
    
    @class_protocol protocol Attributable {
    }
    
    extension NSNumber: Attributable {
    }
    
    extension NSString: Attributable {
    }
    
    extension NSDate: Attributable {
    }
    
    struct Attribute<T: Attributable> {
    
        let name: String
    
        init(_ name: String) {
            self.name = name
        }
    
    }
    
    @infix func ==<T: Attributable> (left: Attribute<T>, right: T) -> NSPredicate {
        return NSPredicate(format: "%K == %@", argumentArray: [left.name, right])
    }
    
    let age = Attribute<NSNumber>("age")
    let name = Attribute<NSString>("name")
    let date = Attribute<NSDate>("date")
    
    let agePredicate = (age == 20)
    let agePredicateFailure = (age == "20")       // <-- Compile time error
    let namePredicate = (name == "Thomas")
    let datePredicate = (date == NSDate())
    
    println(agePredicate)  // age == 20
    println(namePredicate) // name == "Thomas"
    println(datePredicate) // date == CAST(426247727.711557, "NSDate")
    

    Using a @class_protocol and the objc versions of the types otherwise it complains about the argumentArray not being AnyObject[]. The compiler seems clever enough to be able to convert String and Int correctly when used this way though.

    It should work fine for the basic String, Number, Date (and possibly NSData) types but I'm not really sure about the transformable type. Biggest issue I see at the moment is that you still lose most of the safety when using numbers because you can't specify Boolean/Integer 16 etc.

    opened by tomguthrie 7
  • Add predicate creation by interpolation

    Add predicate creation by interpolation

    opened by a2 7
  • Xcode beta4 compile error

    Xcode beta4 compile error

    /QueryKit/Attribute.swift:43:62: Use of unresolved identifier 'bridgeToObjectiveC'

    bug 
    opened by hurricane009 6
  • Replace bridgeToObjectiveC() with

    Replace bridgeToObjectiveC() with "as NSObject"

    I just discovered the magic of "as NSObject". Should do what you want.

    opened by JJJayway 6
  • Update kfdata.py to support generating the interface for Attributes

    Update kfdata.py to support generating the interface for Attributes

    https://github.com/kylef/KFData.py

    Maybe rewrite in swift too?

    opened by kylef 4
  • Don't hard-code pointer size.

    Don't hard-code pointer size.

    Fixes #29

    opened by neonichu 4
  • Is there anyway i can use QueryKit to solve the problem below

    Is there anyway i can use QueryKit to solve the problem below

    i want to find locations within a range based on some fields in the location model:

    The fields below are pre-calculated before the query.

        let CUR_cos_lat = cos(currenLocation.latitude * .pi / 180)
        let CUR_sin_lat = sin(currenLocation.latitude * .pi / 180)
        let CUR_cos_lng = cos(currenLocation.longitude * .pi / 180)
        let CUR_sin_lng = sin(currenLocation.longitude * .pi / 180)
        let cos_allowed_distance = cos(2.0 / 6371)
    

    i want to write a query like the below in Swift CoreData using NSPredicate:

    SELECT * FROM position WHERE CUR_sin_lat * sin_lat + CUR_cos_lat * cos_lat * (cos_lng* 
    CUR_cos_lng + sin_lng * CUR_sin_lng) > cos_allowed_distance;
    

    The fields below in the query above are already available in the CoreData model,

    1. sin_lat
    2. cos_lat
    3. cos_lng
    4. sin_lng
    5. cos_allowed_distance

    Link to Question on Stack : https://stackoverflow.com/questions/66634089/arithmetic-calculations-with-fields-of-coredata-models-with-nspredicate

    opened by yawboafo 0
  • Crash on unwrapping `_kvcKeyPathString` in `expression<R, V>(for keyPath: KeyPath<R, V>)`

    Crash on unwrapping `_kvcKeyPathString` in `expression(for keyPath: KeyPath)`

    I am hitting this crash on line 4 in KeyPath.swift. I guess we can assume the key path is valid or it would not have compiled so this is coming out of Swift.AnyKeyPath. I know there are issues reported out there about it, but I'm not sure what the solution is. Looking into it some more.

    Links

    https://bugs.swift.org/browse/SR-5220 https://bugs.swift.org/browse/SR-6270

    opened by johnclayton 3
  • Trying to query results in

    Trying to query results in "Value of type 'NSManagedObject' has no member 'entryId'" error

    let appdel = UIApplication.shared.delegate as! AppDelegate
    var viewContext: NSManagedObjectContext!
    var querysetEvents: QuerySet<Events>!
    
    // Query for entry with this ID
            for event in try! querysetContactEvents
            .filter(\.entryId == id)
            .array() {
                print(event.date)
            }
    

    results in

    "Value of type 'NSManagedObject' has no member 'entryId'"

    although entryId most certainly exists.

    Could you assist?

    opened by d0hnj0e 0
  • Can't perform Grouped By / Distinct

    Can't perform Grouped By / Distinct

    Hi Team, Kind of stuck here. Trying to do Grouped By or Distinct, but can't find any way using QueryKit. Can you help ? Thanks for your support Yannick

    opened by Yannick-91 2
  • QueryKit fails to install as a package (swift package manager)

    QueryKit fails to install as a package (swift package manager)

    Adding as a package dependency in Xcode 11.5 fails:

    image

    opened by mphill 2
  • XCTAssertEqual fail on tests

    XCTAssertEqual fail on tests

    image

    Capture d’écran 2020-03-26 à 18 04 03

    opened by thomasmfinalcad 0
Releases(0.14.0)
Owner
QueryKit
A simple CoreData query language for Swift and Objective-C.
QueryKit
A Swift framework that wraps CoreData, hides context complexity, and helps facilitate best practices.

Cadmium is a Core Data framework for Swift that enforces best practices and raises exceptions for common Core Data pitfalls exactly where you make the

Jason Fieldman 122 Nov 27, 2021
CoreData stack and controller that will never block UI thread

HardCoreData HardCoreData is a yet another core data stack based on Marcus Zarra's multithreading approach. This smart approach uncouples the writing

Serg Krivoblotsky 208 Aug 1, 2021
CoreData/Realm sweet wrapper written in Swift

What is SugarRecord? SugarRecord is a persistence wrapper designed to make working with persistence solutions like CoreData in a much easier way. Than

Modo 2.1k Nov 14, 2021
ActiveRecord-like API for CoreData

ObjectiveRecord Objective Record is a lightweight ActiveRecord way of managing Core Data objects. If you've used Ruby on Rails before, it might sound

Marin 1.3k Nov 16, 2021
100% Swift Simple Boilerplate Free Core Data Stack. NSPersistentContainer

DATAStack helps you to alleviate the Core Data boilerplate. Now you can go to your AppDelegate remove all the Core Data related code and replace it wi

Nes 217 Nov 21, 2021
Core Data made simple.

A powerful and elegant Core Data framework for Swift. Usage Beta version. New docs soon... Simple do that: let query = persistentContainer.viewContext

null 782 Oct 28, 2021
Robust CloudKit synchronization: offline editing, relationships, shared and public databases, field-level deltas, and more.

CloudCore CloudCore is a framework that manages syncing between iCloud (CloudKit) and Core Data written on native Swift. Features Leveraging NSPersist

deeje cooley 79 Nov 24, 2021
Robust CloudKit synchronization: offline editing, relationships, shared and public databases, field-level deltas, and more.

CloudCore CloudCore is a framework that manages syncing between iCloud (CloudKit) and Core Data written on native Swift. Features Leveraging NSPersist

deeje cooley 76 Nov 15, 2021
Unleashing the real power of Core Data with the elegance and safety of Swift

Unleashing the real power of Core Data with the elegance and safety of Swift Dependency managers Contact Swift 5.4: iOS 11+ / macOS 10.13+ / watchOS 4

John Estropia 3.2k Nov 27, 2021
JSON to Core Data and back. Swift Core Data Sync.

Notice: Sync was supported from it's creation back in 2014 until March 2021 Moving forward I won't be able to support this project since I'm no longer

Nes 2.5k Nov 17, 2021
An NSPredicate DSL for iOS, OSX, tvOS, & watchOS. Inspired by SnapKit and lovingly written in Swift.

PrediKit A Swift NSPredicate DSL for iOS & OS X inspired by SnapKit, lovingly written in Swift, and created by that weird dude at KrakenDev. If you're

Hector Matos 544 Nov 8, 2021
A minimalistic, thread safe, non-boilerplate and super easy to use version of Active Record on Core Data. Simply all you need for doing Core Data. Swift flavour.

Skopelos A minimalistic, thread-safe, non-boilerplate and super easy to use version of Active Record on Core Data. Simply all you need for doing Core

Alberto De Bortoli 234 Nov 17, 2021
JustPersist is the easiest and safest way to do persistence on iOS with Core Data support out of the box. It also allows you to migrate to any other persistence framework with minimal effort.

JustPersist JustPersist is the easiest and safest way to do persistence on iOS with Core Data support out of the box. It also allows you to migrate to

Just Eat 165 Oct 19, 2021
Additions and utilities to make it concurrency easier with the Core Data framework.

CWCoreData ========== Contains convinience additions to classes in CoreData in order to lazily create a managed object model, persistent store cordin

Jayway 66 Apr 24, 2020
Write amazing, strong-typed and easy-to-read NSPredicate.

PredicateFlow Write amazing, strong-typed and easy-to-read NSPredicate. This library allows you to write flowable NSPredicate, without guessing attrib

Andrea Del Fante 99 Nov 6, 2021
Super awesome Swift minion for Core Data (iOS, macOS, tvOS)

⚠️ Since this repository is going to be archived soon, I suggest migrating to NSPersistentContainer instead (available since iOS 10). For other conven

Marko Tadić 309 Jul 30, 2021
A type-safe, fluent Swift library for working with Core Data

Core Data Query Interface (CDQI) is a type-safe, fluent, intuitive library for working with Core Data in Swift. CDQI tremendously reduces the amount o

null 31 Jun 27, 2020
🗃 Powerful and easy to use Swift Query Builder for Vapor 3.

⚠️ This lib is DEPRECATED ⚠️ please use SwifQL with Bridges Quick Intro struct PublicUser: Codable { var name: String var petName: String

iMike 145 Nov 15, 2021
A GUI for dynamically creating NSPredicates at runtime to query data in your iOS app.

PredicateEditor PredicateEditor is a visual editor for creating and using NSPredicates for querying data in your app. PredicateEditor was inspired by

Arvindh Sukumar 365 Nov 4, 2021
Localization of the application with ability to change language "on the fly" and support for plural form in any language.

L10n-swift is a simple framework that improves localization in swift app, providing cleaner syntax and in-app language switching. Overview ?? Features

Adrian Bobrowski 221 Nov 17, 2021
JSPatch bridge Objective-C and Javascript using the Objective-C runtime. You can call any Objective-C class and method in JavaScript by just including a small engine. JSPatch is generally used to hotfix iOS App.

JSPatch 中文介绍 | 文档 | JSPatch平台 请大家不要自行接入 JSPatch,统一接入 JSPatch 平台,让热修复在一个安全和可控的环境下使用。原因详见 这里 JSPatch bridges Objective-C and JavaScript using the Object

bang 11.3k Nov 17, 2021
Simple CoreData wrapper to ease operations

DataKernel What is DataKernel? DataKernel is a minimalistic wrapper around CoreData stack to ease persistence operations. It is heavily inspired by Su

Denis 14 Nov 10, 2021
Simple SwiftUI + CoreData app

Footnote Hello! Before you interact with this repository, please check out our Code of Conduct and Contributing Guidelines. Footnote is a SwiftUI + Co

Cameron Bardell 31 Oct 2, 2021
A Swift framework that wraps CoreData, hides context complexity, and helps facilitate best practices.

Cadmium is a Core Data framework for Swift that enforces best practices and raises exceptions for common Core Data pitfalls exactly where you make the

Jason Fieldman 122 Nov 27, 2021
SwiftUI sample app using Clean Architecture. Examples of working with CoreData persistence, networking, dependency injection, unit testing, and more.

Articles related to this project Clean Architecture for SwiftUI Programmatic navigation in SwiftUI project Separation of Concerns in Software Design C

Alexey Naumov 2.8k Nov 21, 2021
This repository contains a detailed sample app that implements VIPER architecture in iOS using libraries and frameworks like Alamofire, AlamofireImage, PKHUD, CoreData etc.

iOS Viper Architecture: Sample App This repository contains a detailed sample app that implements VIPER architecture using libraries and frameworks li

MindOrks 612 Nov 19, 2021
CoreData stack and controller that will never block UI thread

HardCoreData HardCoreData is a yet another core data stack based on Marcus Zarra's multithreading approach. This smart approach uncouples the writing

Serg Krivoblotsky 208 Aug 1, 2021
🗽 NY Times is an Minimal News 🗞 iOS app 📱 built to describe the use of SwiftSoup and CoreData with SwiftUI🔥

NYTimes NY Times is an Minimal News ?? iOS application built to describe the use of SwiftSoup and CoreData with SwiftUI. ⛓ Features Articles Loading B

The Code Monks 114 Nov 18, 2021
CoreData/Realm sweet wrapper written in Swift

What is SugarRecord? SugarRecord is a persistence wrapper designed to make working with persistence solutions like CoreData in a much easier way. Than

Modo 2.1k Nov 14, 2021