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
24 changes: 18 additions & 6 deletions OpenStack Summit/CoreSummit/CoreDataDecodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,29 @@ public extension NSManagedObjectContext {
}

@inline(__always)
func managedObjects<T: CoreDataDecodable>(_ decodableType: T.Type, predicate: NSPredicate? = nil, sortDescriptors: [NSSortDescriptor] = [], limit: Int = 0) throws -> [T] {
func managedObjects<T: CoreDataDecodable>(_ decodableType: T.Type,
predicate: NSPredicate? = nil,
sortDescriptors: [NSSortDescriptor] = [],
limit: Int = 0) throws -> [T] {

let results = try self.managedObjects(decodableType.ManagedObject.self, predicate: predicate, sortDescriptors: sortDescriptors, limit: limit)
let results = try self.managedObjects(decodableType.ManagedObject.self,
predicate: predicate,
sortDescriptors: sortDescriptors,
limit: limit)

return T.from(managedObjects: results)
}

@inline(__always)
func managedObjects<T: CoreDataDecodable>(_ decodableType: T.Type, predicate: Predicate, sortDescriptors: [NSSortDescriptor] = []) throws -> [T] {
func managedObjects<T: CoreDataDecodable>(_ decodableType: T.Type,
predicate: Predicate,
sortDescriptors: [NSSortDescriptor] = [],
limit: Int = 0) throws -> [T] {

let results = try self.managedObjects(decodableType.ManagedObject.self, predicate: predicate, sortDescriptors: sortDescriptors)
let results = try self.managedObjects(decodableType.ManagedObject.self,
predicate: predicate.toFoundation(),
sortDescriptors: sortDescriptors,
limit: limit)

return T.from(managedObjects: results)
}
Expand Down Expand Up @@ -83,7 +95,7 @@ public extension NSFetchedResultsController {
public func NSFetchedResultsController <T: CoreDataDecodable>
(_ decodable: T.Type,
delegate: NSFetchedResultsControllerDelegate? = nil,
predicate: NSPredicate? = nil,
predicate: Predicate? = nil,
sortDescriptors: [NSSortDescriptor] = [],
sectionNameKeyPath: String? = nil,
context: NSManagedObjectContext) -> NSFetchedResultsController<T.ManagedObject> {
Expand All @@ -94,7 +106,7 @@ public func NSFetchedResultsController <T: CoreDataDecodable>

let fetchRequest = NSFetchRequest<T.ManagedObject>(entityName: entity.name!)

fetchRequest.predicate = predicate
fetchRequest.predicate = predicate?.toFoundation()

fetchRequest.sortDescriptors = sortDescriptors

Expand Down
9 changes: 7 additions & 2 deletions OpenStack Summit/CoreSummit/EventManagedObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ public final class EventManagedObject: Entity {
@NSManaged public var groups: Set<GroupManagedObject>

@NSManaged public var summit: SummitManagedObject

// MARK: - Inverse Relationhips

@NSManaged public var attendees: Set<AttendeeManagedObject>
}

// MARK: - Encoding
Expand Down Expand Up @@ -178,6 +182,7 @@ public extension EventManagedObject {

//let predicate = NSPredicate(format: "name CONTAINS [c] %@ or ANY presentation.speakers.firstName CONTAINS [c] %@ or ANY presentation.speakers.lastName CONTAINS [c] %@ or presentation.level CONTAINS [c] %@ or ANY tags.name CONTAINS [c] %@ or eventType.name CONTAINS [c] %@", searchTerm, searchTerm, searchTerm, searchTerm, searchTerm, searchTerm)
let predicate: Predicate = (#keyPath(EventManagedObject.name)).compare(.contains, [.caseInsensitive], value)
|| (#keyPath(EventManagedObject.presentation.speakers.firstName)).compare(.any, .contains, [.caseInsensitive], value)
|| (#keyPath(EventManagedObject.presentation.speakers.lastName)).compare(.any, .contains, [.caseInsensitive], value)
|| (#keyPath(EventManagedObject.presentation.level)).compare(.contains, [.caseInsensitive], value)
|| (#keyPath(EventManagedObject.tags.name)).compare(.any, .contains, [.caseInsensitive], value)
Expand Down Expand Up @@ -259,7 +264,7 @@ public extension EventManagedObject {

assert(predicates.count > 1)

return try context.managedObjects(EventManagedObject.self,
return try context.managedObjects(self,
predicate: .compound(.and(predicates)),
sortDescriptors: sortDescriptors)
}
Expand All @@ -273,7 +278,7 @@ public extension EventManagedObject {
&& #keyPath(EventManagedObject.end) <= end
&& #keyPath(EventManagedObject.summit.id) == summit

return try context.managedObjects(EventManagedObject.self, predicate: predicate, sortDescriptors: sortDescriptors)
return try context.managedObjects(self, predicate: predicate, sortDescriptors: sortDescriptors)
}
}

Expand Down
67 changes: 4 additions & 63 deletions OpenStack Summit/CoreSummit/SpeakerManagedObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,70 +82,11 @@ extension Speaker: CoreDataEncodable {

public extension SpeakerManagedObject {

public enum Property: String {

case id, firstName, lastName, addressBookSectionName, title, pictureURL, twitter, irc, biography, member
}

static var sortDescriptors: [NSSortDescriptor] {

return [NSSortDescriptor(key: Property.addressBookSectionName.rawValue, ascending: true),
NSSortDescriptor(key: Property.firstName.rawValue, ascending: true),
NSSortDescriptor(key: Property.lastName.rawValue, ascending: true),
NSSortDescriptor(key: Property.id.rawValue, ascending: true)]
}
}

public extension Speaker {

static func filter(_ searchTerm: String = "",
page: Int, objectsPerPage: Int,
summit: Identifier? = nil,
context: NSManagedObjectContext) throws -> [Speaker] {

var predicates = [NSPredicate]()

if searchTerm.isEmpty == false {

let searchPredicate = NSPredicate(format: "firstName CONTAINS[c] %@ OR lastName CONTAINS[c] %@", searchTerm, searchTerm)

predicates.append(searchPredicate)
}

if let summitID = summit,
let summit = try SummitManagedObject.find(summitID, context: context) {

let summitPredicate = NSPredicate(format: "%@ IN summits", summit)

predicates.append(summitPredicate)
}

let predicate: NSPredicate?

if predicates.count > 1 {

predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)

} else {

predicate = predicates.first
}

let results = try context.managedObjects(ManagedObject.self, predicate: predicate, sortDescriptors: ManagedObject.sortDescriptors)

var speakers = [ManagedObject]()

let startRecord = (page - 1) * objectsPerPage

let endRecord = (startRecord + (objectsPerPage - 1)) <= results.count ? startRecord + (objectsPerPage - 1) : results.count - 1

if (startRecord <= endRecord) {

for index in (startRecord...endRecord) {
speakers.append(results[index])
}
}

return Speaker.from(managedObjects: speakers)
return [NSSortDescriptor(key: #keyPath(addressBookSectionName), ascending: true),
NSSortDescriptor(key:#keyPath(SpeakerManagedObject.firstName), ascending: true),
NSSortDescriptor(key:#keyPath(SpeakerManagedObject.lastName), ascending: true),
NSSortDescriptor(key:#keyPath(SpeakerManagedObject.id), ascending: true)]
}
}
8 changes: 4 additions & 4 deletions OpenStack Summit/CoreSummit/TagManagedObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import Foundation
import CoreData
import Predicate

public final class TagManagedObject: Entity {

Expand Down Expand Up @@ -53,10 +54,9 @@ public extension Tag {

static func search(_ searchTerm: String, context: NSManagedObjectContext) throws -> [Tag] {

let predicate = NSPredicate(format: "name CONTAINS[c] %@", searchTerm)
//let predicate = NSPredicate(format: "name CONTAINS[c] %@", searchTerm)
let predicate: Predicate = (#keyPath(TagManagedObject.name)).compare(.contains, [.caseInsensitive], .value(.string(searchTerm)))

let managedObjects = try context.managedObjects(ManagedObject.self, predicate: predicate, sortDescriptors: ManagedObject.sortDescriptors)

return Tag.from(managedObjects: managedObjects)
return try context.managedObjects(self, predicate: predicate, sortDescriptors: ManagedObject.sortDescriptors)
}
}
19 changes: 9 additions & 10 deletions OpenStack Summit/CoreSummit/TrackGroupManagedObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import Foundation
import CoreData
import Predicate

public final class TrackGroupManagedObject: Entity {

Expand All @@ -18,6 +19,10 @@ public final class TrackGroupManagedObject: Entity {
@NSManaged public var color: String

@NSManaged public var tracks: Set<TrackManagedObject>

// Inverse Relationships

@NSManaged public var summits: Set<SummitManagedObject>
}

// MARK: - Encoding
Expand Down Expand Up @@ -57,7 +62,7 @@ public extension TrackGroupManagedObject {

static var sortDescriptors: [NSSortDescriptor] {

return [NSSortDescriptor(key: "name", ascending: true)]
return [NSSortDescriptor(key: #keyPath(TrackGroupManagedObject.name), ascending: true)]
}
}

Expand All @@ -66,15 +71,9 @@ public extension TrackGroup {
/// Fetch all track groups that have some event associated with them.
static func scheduled(for summit: Identifier, context: NSManagedObjectContext) throws -> [TrackGroup] {

guard let summitManagedObject = try SummitManagedObject.find(summit, context: context)
else { return [] }

let events = try context.managedObjects(EventManagedObject.self, predicate: NSPredicate(format: "track != nil AND summit == %@", summitManagedObject))

var groups = events.reduce([TrackGroupManagedObject](), { $0.0 + Array($0.1.track!.groups) })

groups = (Set(groups) as NSSet).sortedArray(using: ManagedObject.sortDescriptors) as! [TrackGroupManagedObject]
let predicate: Predicate = #keyPath(TrackGroupManagedObject.tracks.events) + ".@count" > 0
&& (#keyPath(TrackGroupManagedObject.summits)).compare(.contains, .value(.int64(summit)))

return TrackGroup.from(managedObjects: groups)
return try context.managedObjects(self, predicate: predicate, sortDescriptors: ManagedObject.sortDescriptors)
}
}
33 changes: 18 additions & 15 deletions OpenStack Summit/CoreSummit/TrackManagedObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import Foundation
import CoreData
import Predicate

public final class TrackManagedObject: Entity {

Expand All @@ -17,7 +18,9 @@ public final class TrackManagedObject: Entity {

// Inverse Relationships

@NSManaged public var presentations: Set<PresentationManagedObject>
@NSManaged public var events: Set<EventManagedObject>

@NSManaged public var summits: Set<SummitManagedObject>
}

// MARK: - Encoding
Expand Down Expand Up @@ -68,43 +71,43 @@ public extension TrackManagedObject {

static var sortDescriptors: [NSSortDescriptor] {

return [NSSortDescriptor(key: "name", ascending: true)]
return [NSSortDescriptor(key: #keyPath(TrackManagedObject.name), ascending: true)]
}
}

public extension Track {

static func search(_ searchTerm: String, context: NSManagedObjectContext) throws -> [Track] {

let predicate = NSPredicate(format: "name CONTAINS[c] %@", searchTerm)

let managedObjects = try context.managedObjects(TrackManagedObject.self, predicate: predicate, sortDescriptors: TrackManagedObject.sortDescriptors)
let predicate: Predicate = (#keyPath(TrackManagedObject.name)).compare(.contains, [.caseInsensitive], .value(.string(searchTerm)))

return Track.from(managedObjects: managedObjects)
return try Track.filter(predicate,
sort: ManagedObject.sortDescriptors,
context: context)
}

/// Get scheduled tracks that belong to track groups.
static func `for`(groups trackGroups: [Identifier], context: NSManagedObjectContext) throws -> [Track] {
static func `for`(groups trackGroups: [Identifier] = [], context: NSManagedObjectContext) throws -> [Track] {

let predicate: NSPredicate
let predicate: Predicate

let scheduledTracksPredicate = NSPredicate(format: "events.@count > 0")
// let scheduledTracksPredicate = Predicate(format: "events.@count > 0")
let scheduledTracks: Predicate = #keyPath(TrackManagedObject.events) + ".@count" > 0

// optionally filter for track groups
if trackGroups.isEmpty == false {

let trackGroupIdentifiers = trackGroups.map { NSNumber(value: Int64($0) as Int64) }

let trackGroupsPredicate = NSPredicate(format: "ANY groups.id IN %@", [trackGroupIdentifiers])
//let trackGroupsPredicate = NSPredicate(format: "ANY groups.id IN %@", [trackGroups])
let trackGroupsPredicate: Predicate = (#keyPath(TrackManagedObject.groups.id)).in(trackGroups)

predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [scheduledTracksPredicate, trackGroupsPredicate])
predicate = .compound(.and([scheduledTracks, trackGroupsPredicate]))

} else {

predicate = scheduledTracksPredicate
predicate = scheduledTracks
}

return try context.managedObjects(Track.self, predicate: predicate, sortDescriptors: ManagedObject.sortDescriptors)
return try context.managedObjects(self, predicate: predicate, sortDescriptors: ManagedObject.sortDescriptors)
}
}

6 changes: 4 additions & 2 deletions OpenStack Summit/OpenStack Summit/Filter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,14 @@ struct ScheduleFilter: Equatable {

// fetch data
let trackGroups = try! TrackGroup.scheduled(for: summitID, context: context)
let levels = try! Set(context.managedObjects(PresentationManagedObject.self, predicate: "event.summit.id" == summitID)
let levels = try! Set(context.managedObjects(PresentationManagedObject.self, predicate: #keyPath(PresentationManagedObject.event.summit.id) == summitID)
.flatMap { $0.level })
.flatMap { Level(rawValue: $0) }
.sorted()

let venues = try! context.managedObjects(Venue.self, predicate: NSPredicate(format: "summit == %@", summit), sortDescriptors: VenueManagedObject.sortDescriptors)
let venues = try! context.managedObjects(Venue.self,
predicate: #keyPath(VenueManagedObject.summit.id) == summitID,
sortDescriptors: VenueManagedObject.sortDescriptors)

// populate filter categories

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import UIKit
import Foundation
import CoreSummit
import Predicate

final class GeneralScheduleFilterViewController: UITableViewController {

Expand Down Expand Up @@ -113,9 +114,10 @@ final class GeneralScheduleFilterViewController: UITableViewController {
if let trackGroupsSection = scheduleFilter.allFilters[.trackGroup] {

// fetch from CoreData because it caches fetch request results and is more efficient
let identifiers = trackGroupsSection.map { NSNumber(value: Int64(identifier(for: $0))) }
let identifiers = trackGroupsSection.map { identifier(for: $0) }

let predicate = NSPredicate(format: "id IN %@", identifiers)
//let predicate = NSPredicate(format: "id IN %@", identifiers)
let predicate: Predicate = (#keyPath(TrackGroupManagedObject.id)).in(identifiers)

let trackGroups = try! context.managedObjects(TrackGroup.self, predicate: predicate, sortDescriptors: TrackGroup.ManagedObject.sortDescriptors)

Expand All @@ -134,9 +136,10 @@ final class GeneralScheduleFilterViewController: UITableViewController {
if let venuesSection = scheduleFilter.allFilters[.venue] {

// fetch from CoreData because it caches fetch request results and is more efficient
let identifiers = venuesSection.map { NSNumber(value: Int64(identifier(for: $0))) }
let identifiers = venuesSection.map { identifier(for: $0) }

let predicate = NSPredicate(format: "id IN %@", identifiers)
//let predicate = NSPredicate(format: "id IN %@", identifiers)
let predicate: Predicate = (#keyPath(VenueManagedObject.id)).in(identifiers)

let venues = try! context.managedObjects(Venue.self, predicate: predicate, sortDescriptors: Venue.ManagedObject.sortDescriptors)

Expand Down
Loading