Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thread handling #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
33 changes: 27 additions & 6 deletions Classes/CoreData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,35 @@ public class CoreData {

// MARK: Basic methods

private var _privateManagedContext: NSManagedObjectContext?
private var _managedContext: NSManagedObjectContext?

/// Private managed object context for this instance
public lazy var privateManagedContext: NSManagedObjectContext = {
guard let privateManagedContext = _privateManagedContext else {
// Create a background managed context as root context so the
// main thread should not be blocked on more expensive opersations
let privateManagedContext = persistentContainer.newBackgroundContext()
_privateManagedContext = privateManagedContext
return privateManagedContext
}
return privateManagedContext
}()

/// Managed context for this instance
public var managedContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
public lazy var managedContext: NSManagedObjectContext = {
guard let managedContext = _managedContext else {
let managedContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedContext.parent = privateManagedContext
_managedContext = managedContext
return managedContext
}
return managedContext
}()

/// Default managed context
public static var managedContext: NSManagedObjectContext {
return CoreData.default.persistentContainer.viewContext
return CoreData.default.managedContext
}

/// Create new entry on the default context
Expand Down Expand Up @@ -78,12 +99,12 @@ public class CoreData {

/// Save managed context if it has changes
public func saveContext() throws {
try CoreData.save(context: managedContext)
try CoreData.save(context: privateManagedContext)
}

/// Save default managed context if it has changes
public static func saveContext() throws {
try CoreData.save(context: managedContext)
try CoreData.default.saveContext()
}

// MARK: Private interface
Expand Down
55 changes: 55 additions & 0 deletions Classes/Extensions/QueryExecutable+ManagedObject.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// QueryExecutable+ManagedObject.swift
// Reloaded
//
// Created by Ondrej Rafaj on 10/05/2018.
// Copyright © 2018 LiveUI. All rights reserved.
//

import Foundation
import CoreData


extension QueryExecutable where EntityType: NSManagedObject {

/// Return all data based on your query
public func all(on context: NSManagedObjectContext?) throws -> [EntityType] {
let context = context ?? CoreData.managedContext
guard let data = try context.fetch(fetchRequest()) as? [EntityType] else {
return []
}
return data
}

/// Delete all data captured by your query
public func delete(on context: NSManagedObjectContext?) throws {
let context = context ?? CoreData.managedContext
for object in try all(on: context) {
try object.delete(on: context)
}
try context.save()

// TODO: Fix the following batch request!
// let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest())
// do {
// let batchDeleteResult = try context.execute(deleteRequest) as! NSBatchDeleteResult
// print("The batch delete request has deleted \(batchDeleteResult.result!) records.")
// } catch {
// let updateError = error as NSError
// print("\(updateError), \(updateError.userInfo)")
// }
}

/// Count the number of items in your query
public func count(on context: NSManagedObjectContext?) throws -> Int {
let context = context ?? CoreData.managedContext
return try context.count(for: fetchRequest())
}

/// Get first result of your query
public func first(on context: NSManagedObjectContext?) throws -> EntityType? {
let context = context ?? CoreData.managedContext
return try context.fetch(fetchRequest()).first as? EntityType
}

}
41 changes: 41 additions & 0 deletions Classes/Extensions/QueryExecutable+Threading.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// QueryExecutable+Threading.swift
// Reloaded
//
// Created by Ondrej Rafaj on 10/05/2018.
// Copyright © 2018 LiveUI. All rights reserved.
//

import Foundation
import CoreData


extension QueryExecutable where EntityType: NSManagedObject {

/// Return all data based on your query
public func all(on queue: DispatchQueue = .main) -> CoreDataPromise<[EntityType]> {
// Create or get the right context for the desired queue
// Execute query on the thread for the context
// Fulfill promise
// Dispose of the context if no-one is using it anymore
fatalError()
}

/// Delete all data captured by your query
public func delete(on queue: DispatchQueue = .main) -> CoreDataPromise<Void> {
// All above +
// Update all contexts
fatalError()
}

/// Count the number of items in your query
public func count(on queue: DispatchQueue = .main) -> CoreDataPromise<Int>{
fatalError()
}

/// Get first result of your query
public func first(on queue: DispatchQueue = .main) -> CoreDataPromise<EntityType?> {
fatalError()
}

}
49 changes: 49 additions & 0 deletions Classes/Libs/CoreDataPromise.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// CoreDataPromise.swift
// Reloaded
//
// Created by Ondrej Rafaj on 10/05/2018.
// Copyright © 2018 LiveUI. All rights reserved.
//

import Foundation


public class CoreDataPromise<Expectation> {

public internal(set) var expectation: Expectation? {
didSet {
if let expectation = expectation {
thenPromiseClosure?(expectation)
mapPromise?.expectation = mapPromiseClosure?(expectation)
}
}
}

/// Then closure type
public typealias ThenPromise = ((Expectation) -> Void)

/// Map closure type
public typealias MapPromise<T> = ((Expectation) -> T)

var thenPromiseClosure: ThenPromise?

/// Executes when operation is finished
public func then(_ promise: @escaping ThenPromise) -> Self {
thenPromiseClosure = promise
return self
}

var mapPromiseClosure: MapPromise<Any>?
var mapPromise: CoreDataPromise<Any>?

// /// Executes when operation is finished to transform result to another type
// public func map<T>(to: T.Type = T.self, _ promise: @escaping MapPromise<T>) -> CoreDataPromise<T> {
// mapPromiseClosure = promise
//
// let mapPromise = CoreDataPromise<T>()
//
// return mapPromise
// }

}
1 change: 0 additions & 1 deletion Classes/Protocols/Entity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ extension Entity where Self: NSManagedObject {

/// Create new query
public static var query: Query<Self> {
print(self)
return Query(self)
}

Expand Down
35 changes: 0 additions & 35 deletions Classes/Protocols/QueryExecutable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,38 +40,3 @@ extension QueryExecutable {
}

}

extension QueryExecutable where EntityType: NSManagedObject {

public func all(on context: NSManagedObjectContext = CoreData.managedContext) throws -> [EntityType] {
guard let data = try context.fetch(fetchRequest()) as? [EntityType] else {
return []
}
return data
}

public func delete(on context: NSManagedObjectContext = CoreData.managedContext) throws {
for object in try all(on: context) {
try object.delete(on: context)
}
try context.save()

// let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest())
// do {
// let batchDeleteResult = try context.execute(deleteRequest) as! NSBatchDeleteResult
// print("The batch delete request has deleted \(batchDeleteResult.result!) records.")
// } catch {
// let updateError = error as NSError
// print("\(updateError), \(updateError.userInfo)")
// }
}

public func count(on context: NSManagedObjectContext = CoreData.managedContext) throws -> Int {
return try context.count(for: fetchRequest())
}

public func first(on context: NSManagedObjectContext = CoreData.managedContext) throws -> EntityType? {
return try context.fetch(fetchRequest()).first as? EntityType
}

}
3 changes: 3 additions & 0 deletions Demo-iOS/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class ViewController: UIViewController {
}

let all = try! Locomotive.query.filter("hasChimney" == true).filter(.or, "color" == "green", "color" == "black").sort(by: "color", direction: .orderedAscending).all()
all.forEach { (<#Collection.Element#>) in
<#code#>
}
all.forEach { loco in
print("Color: \(loco.color ?? "Unknown"); Chimney: \(Bool(loco.hasChimney))")
}
Expand Down
2 changes: 1 addition & 1 deletion Reloaded.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Pod::Spec.new do |s|
s.name = 'Reloaded'
s.version = '1.0.1'
s.version = '1.1.0'
s.summary = 'Reloaded! Swift "ORM like" abstraction layer for CoreData'
s.swift_version = '4.0'

Expand Down
Loading