Initial commit

This commit is contained in:
Ivan Vavilov 2017-06-13 14:06:20 +03:00
commit 6f7258a589
58 changed files with 3901 additions and 0 deletions

37
.gitignore vendored Normal file
View File

@ -0,0 +1,37 @@
# OS X
.DS_Store
# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa
# Bundler
.bundle
Carthage
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
# Note: if you ignore the Pods directory, make sure to uncomment
# `pod install` in .travis.yml
#
Pods/
Source/.idea
Example/pod_install.command
Example/pod_update.command

22
DAO.podspec Normal file
View File

@ -0,0 +1,22 @@
Pod::Spec.new do |s|
s.name = 'DAO'
s.version = '1.0.0'
s.summary = 'DAO Library'
s.description = 'Library provides easy way to cache entities.'
s.homepage = 'https://github.com/RedMadRobot/DAO'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'vani2' => 'iv@redmadrobot.com' }
s.source = { :git => 'git@github.com:RedMadRobot/DAO.git' }
s.platform = :ios, '9.0'
s.source_files = 'DAO/Classes/Core/**/*'
s.subspec 'Realm' do |r|
r.source_files = "DAO/Classes/RealmDAO/**/*"
r.dependency "RealmSwift"
end
s.subspec 'CoreData' do |cd|
cd.source_files = "DAO/Classes/CoreData/**/*"
end
end

0
DAO/Classes/.gitkeep Normal file
View File

105
DAO/Classes/Core/DAO.swift Normal file
View File

@ -0,0 +1,105 @@
//
// DAO.swift
// DAO
//
// Created by Igor Bulyga on 04.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import Foundation
/// Parent class for DAO pattern implemetation (aka interface).
open class DAO<Model: Entity> {
// MARK: - Insert/update
/// Saving new entity or update existing.
///
/// - Parameter entity: entity should be saved.
/// - Throws: error if entity can not be saved.
open func persist(_ entity: Model) throws {
preconditionFailure()
}
/// Saving new entities or update existing.
///
/// - Parameter entities: entities should be saved.
/// - Throws: error if any entity can not be saved.
open func persist(_ entities: [Model]) throws {
preconditionFailure()
}
// MARK: - Read
/// Read entity from database of `Model` type.
///
/// - Parameter entityId: entity identifier.
/// - Returns: instance of existant entity or nil.
open func read(_ entityId: String) -> Model? {
preconditionFailure()
}
/// Read all entities from database of `Model` type.
///
/// - Returns: array of entities.
open func read() -> [Model] {
preconditionFailure()
}
/// Read all entities from database of `Model` type filtered by predicate.
///
/// - Parameter predicate: predicate to filter entities.
/// - Returns: filtered array of entities.
open func read(predicatedBy predicate: NSPredicate?) -> [Model] {
preconditionFailure()
}
/// Read all entities from database of `Model` type ordered by field.
///
/// - Parameters:
/// - field: ordering field.
/// - ascending: ascending flag (descending otherwise).
/// - Returns: ordered array of entities.
open func read(orderedBy field: String?, ascending: Bool) -> [Model] {
preconditionFailure()
}
/// Read all entities from database of `Model` type filtered by predicate and ordered by field.
///
/// - Parameters:
/// - predicate: predicate to filter entities.
/// - field: ordering field.
/// - ascending: ascending flag (descending otherwise).
/// - Returns: filtered and ordered array of entities.
open func read(predicatedBy predicate: NSPredicate?, orderedBy field: String?,
ascending: Bool) -> [Model] {
preconditionFailure()
}
// MARK: - Delete
/// Delete all entities of `Model` type.
///
/// - Throws: error if any entity can not be deleted.
open func erase() throws {
preconditionFailure()
}
/// Delete entity of `Model` type by identifier.
///
/// - Throws: error if any entity can not be deleted.
open func erase(_ entityId: String) throws {
preconditionFailure()
}
}

View File

@ -0,0 +1,57 @@
//
// Entity.swift
// DAO
//
// Created by Igor Bulyga on 05.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import Foundation
/// Parent class for all entities.
open class Entity: Hashable {
/// Hash value for compare entities.
open var hashValue: Int {
get {
return self.entityId.hashValue
}
}
/// Unique entity identifer.
open var entityId: String = ""
required public init() {}
/// Creates an instance with identifier.
///
/// - Parameter entityId: unique entity identifier.
public init(entityId: String) {
self.entityId = entityId
}
/// Function to redefine it in children for proper equality.
///
/// - Parameter other: entity compare with.
/// - Returns: result of comparison.
open func equals<T>(_ other: T) -> Bool where T: Entity {
return self.entityId == other.entityId
}
}
/// Custom operator `==` for `Entity` and subclasses.
///
/// - Parameters:
/// - lhs: left entity to compare.
/// - rhs: right entity to compare.
/// - Returns: result of comparison.
public func ==<T>(lhs: T, rhs: T) -> Bool where T: Entity {
return lhs.equals(rhs)
}

View File

@ -0,0 +1,45 @@
//
// CoreDataConfiguration.swift
// DAO
//
// Created by Ivan Vavilov on 12/05/2017.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import Foundation
import CoreData
/// `CoreData DAO` configuration.
/// Incapsulates basic settings.
/// Used to initialize `CoreData DAO`.
public struct CoreDataConfiguration {
/// Name of container also is filename for `*.xcdatamodelid` file.
public let containerName: String
/// Store type like in `CoreData`. `NSInMemoryStoreType`, for instance.
public let storeType: String
/// Options for persistence store
public let options: [String: NSObject]
/// Create an instance with specified `containerName`, `storeType`, `options`.
///
/// - Parameters:
/// - containerName: name. See above.
/// - storeType: store type. See above.
/// - options: persistence store options.
public init(
containerName: String,
storeType: String = NSSQLiteStoreType,
options: [String : NSObject] =
[NSMigratePersistentStoresAutomaticallyOption: true as NSObject,
NSInferMappingModelAutomaticallyOption: true as NSObject]) {
self.containerName = containerName
self.storeType = storeType
self.options = options
}
}

View File

@ -0,0 +1,342 @@
//
// CoreDataDAO.swift
// DAO
//
// Created by Ivan Vavilov on 2/4/16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import CoreData
/// `DAO` pattern implementation for `CoreData`.
open class CoreDataDAO<CDModel: NSManagedObject, Model: Entity> : DAO<Model> {
// MARK: - Private
/// Translator for current `CDModel` and `Model` types.
private var translator: CoreDataTranslator<CDModel, Model>
/// Persistent store cooridnator. Can be configured by `CoreDataConfiguration`.
private let persistentStoreCoordinator: NSPersistentStoreCoordinator
/// Managed object context. Context is created every transaction due to current queue
/// main or background.
private var context: NSManagedObjectContext {
let context = Thread.isMainThread ?
NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) :
NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.persistentStoreCoordinator = persistentStoreCoordinator
context.shouldDeleteInaccessibleFaults = true
if #available(iOS 10.0, *) {
context.automaticallyMergesChangesFromParent = true
}
return context
}
//MARK: - Public
/// Creates an instance with specified `translator` and `configuration`.
///
/// - Parameters:
/// - translator: translator for current `CDModel` and `Model` types.
/// - configuration: configuration. See also `CoreDataConfiguration`.
/// - Throws: error if loading or adding persistence store is failed.
public init(_ translator: CoreDataTranslator<CDModel, Model>,
configuration: CoreDataConfiguration) throws {
self.translator = translator
if #available(iOS 10, *) {
let persistentContainer = NSPersistentContainer(name: configuration.containerName)
persistentContainer.persistentStoreDescriptions
.forEach { description in
configuration.options
.forEach {
description.setOption($0.value, forKey: $0.key)
}
description.type = configuration.storeType
}
var error: Error?
persistentContainer.loadPersistentStores { _, e in
error = e
}
if let error = error { throw error }
persistentStoreCoordinator = persistentContainer.persistentStoreCoordinator
} else {
let url = Bundle(for: CDModel.self).url(
forResource: configuration.containerName,
withExtension: "momd")!
persistentStoreCoordinator = NSPersistentStoreCoordinator(
managedObjectModel: NSManagedObjectModel(contentsOf: url)!)
try persistentStoreCoordinator.addPersistentStore(
ofType: configuration.storeType,
configurationName: nil,
at: CoreDataDAO.url(storeName: "\(configuration.containerName).db"),
options: configuration.options)
}
super.init()
}
//MARK: - DAO
override open func persist(_ entity: Model) throws {
var error: Error?
let context = self.context
context.performAndWait { [weak self] in
guard let `self` = self else { return }
do {
if self.isEntryExist(entity.entityId, inContext: context) {
try self.update(entity, inContext: context)
} else {
try self.create(entity, inContext: context)
}
} catch let e {
error = e
}
}
if let error = error { throw error }
}
open override func persist(_ entities: [Model]) throws {
var error: Error?
let context = self.context
context.performAndWait { [weak self] in
guard let `self` = self else { return }
entities.forEach{ entity in
if self.isEntryExist(entity.entityId, inContext: context) {
let existingEntries = self.fetchEntries(entity.entityId, inContext: context)
existingEntries.forEach {
self.translator.fill($0, fromEntity: entity, in: context)
}
} else if let entry = NSEntityDescription.insertNewObject(
forEntityName: self.translator.entryClassName,
into: context) as? CDModel {
self.translator.fill(entry, fromEntity: entity, in: context)
}
}
do {
try context.save()
} catch let e {
error = e
context.rollback()
}
}
if let error = error { throw error }
}
open override func read(_ entityId: String) -> Model? {
guard let entries = try? context.fetch(request(entityId)),
!entries.isEmpty,
let entry = entries.first
else {
return nil
}
let entity = Model()
translator.fill(entity, fromEntry: entry)
return entity
}
open override func read() -> [Model] {
return read(predicatedBy: nil)
}
open override func read(predicatedBy predicate: NSPredicate?) -> [Model] {
return read(predicatedBy: predicate, orderedBy: nil, ascending: false)
}
open override func read(
predicatedBy predicate: NSPredicate?,
orderedBy field: String?,
ascending: Bool) -> [Model] {
let sortDescriptors = field != nil ? [NSSortDescriptor(key: field, ascending: ascending)] : []
return fetchEntries(predicate, sortDescriptors: sortDescriptors, inContext: context)
.flatMap {
let entity = Model()
self.translator.fill(entity, fromEntry: $0)
return entity
}
}
open override func read(orderedBy field: String?, ascending: Bool) -> [Model] {
return read(predicatedBy: nil, orderedBy: field, ascending: ascending)
}
override open func erase() throws {
var error: Error?
let context = self.context
context.performAndWait { [weak self] in
guard let `self` = self else { return }
self.fetchEntries(inContext: context)
.forEach {
context.delete($0)
}
do {
try context.save()
} catch let e {
error = e
context.rollback()
}
}
if let error = error { throw error }
}
override open func erase(_ entityId: String) throws {
var error: Error?
let context = self.context
context.performAndWait { [weak self] in
guard let `self` = self else { return }
self.fetchEntries(entityId, inContext: context)
.forEach {
context.delete($0)
}
do {
try context.save()
} catch let e {
error = e
context.rollback()
}
}
if let error = error { throw error }
}
//MARK: - Private
private func fetchEntries(
_ entryId: String,
inContext context: NSManagedObjectContext) -> [CDModel] {
if let entries = try? context.fetch(request(entryId)) {
return entries
} else {
return [CDModel]()
}
}
private func fetchEntries(
_ predicate: NSPredicate? = nil,
sortDescriptors: [NSSortDescriptor] = [],
inContext context: NSManagedObjectContext) -> [CDModel] {
if let entries = try? context.fetch(request(predicate, sortDescriptors: sortDescriptors)) {
return entries
} else {
return [CDModel]()
}
}
private func request(_ entryId: String) -> NSFetchRequest<CDModel> {
let request = NSFetchRequest<CDModel>(entityName: translator.entryClassName)
request.predicate = NSPredicate(format: "entryId == %@", argumentArray: [entryId])
return request
}
private func request(_ predicate: NSPredicate?,
sortDescriptors: [NSSortDescriptor]) -> NSFetchRequest<CDModel> {
let request = NSFetchRequest<CDModel>(entityName: translator.entryClassName)
request.predicate = predicate
request.sortDescriptors = sortDescriptors
return request
}
//MARK: - Transactions
private func isEntryExist(
_ entryId: String,
inContext context: NSManagedObjectContext) -> Bool {
let existingEntries = fetchEntries(entryId, inContext: context)
return existingEntries.count > 0
}
private func update(_ entity: Model, inContext context: NSManagedObjectContext) throws {
let existingEntries = fetchEntries(entity.entityId, inContext: context)
existingEntries.forEach {
translator.fill($0, fromEntity: entity, in: context)
}
try context.save()
}
private func create(_ entity: Model, inContext context: NSManagedObjectContext) throws {
guard let entry = NSEntityDescription.insertNewObject(
forEntityName: translator.entryClassName,
into: context) as? CDModel
else {
return
}
translator.fill(entry, fromEntity: entity, in: context)
try context.save()
}
// MARK: - Helper
private class func url(storeName: String) -> URL {
var url: URL! = nil
if let documentsDirectory = NSSearchPathForDirectoriesInDomains(
.documentDirectory,
.userDomainMask, true).first {
let storeAbsolutePath = (documentsDirectory as NSString).appendingPathComponent(storeName)
url = URL(fileURLWithPath: storeAbsolutePath) as URL!
}
return url
}
}

View File

@ -0,0 +1,93 @@
//
// RealmTranslator.swift
// DAO
//
// Created by Ivan Vavilov on 06.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import Foundation
import CoreData
/// Parent class for `CoreData` translators.
/// Translators fill properties of new/existant entities from entries and other way.
open class CoreDataTranslator<CDModel: NSManagedObject, Model: Entity> {
/// Helper property for `CoreDataDAO`.
open var entryClassName: String {
return NSStringFromClass(CDModel.self).components(separatedBy: ".").last!
}
/// Creates an instance of class.
required public init() { }
/// All properties of entity will be overridden by entry properties.
///
/// - Parameters:
/// - entity: instance of `Model` type.
/// - fromEntry: instance of `CDModel` type.
open func fill(_ entity: Model, fromEntry: CDModel) {
fatalError("Abstact method")
}
/// All properties of entry will be overridden by entity properties.
///
/// - Parameters:
/// - entry: instance of `CDModel` type.
/// - fromEntity: instance of `Model` type.
/// - context: managed object context for current transaction.
open func fill(_ entry: CDModel, fromEntity: Model, in context: NSManagedObjectContext) {
fatalError("Abstact method")
}
/// All properties of entities will be overridden by entries properties.
/// For simplicity create new entries w/o changing existent.
///
/// - Parameters:
/// - entries: array of instances of `CDModel` type.
/// - fromEntities: array of instances of `Model` type.
/// - context: managed object context for current transaction.
open func fill(
_ entries: inout Set<CDModel>,
fromEntities: [Model],
in context: NSManagedObjectContext) {
fromEntities
.flatMap { entity -> (CDModel, Model)? in
if let entry = NSEntityDescription.insertNewObject(
forEntityName: self.entryClassName,
into: context) as? CDModel {
entries.insert(entry)
return (entry, entity)
} else {
return nil
}
}
.forEach {
self.fill($0.0, fromEntity: $0.1, in: context)
}
}
/// All properties of entries will be overridden by entities properties.
///
/// - Parameters:
/// - entities: array of instances of `CDModel` type.
/// - fromEntries: array of instances of `CDModel` type.
open func fill(_ entities: inout [Model], fromEntries: Set<CDModel>?) {
entities.removeAll()
fromEntries?.forEach {
let model = Model()
entities.append(model)
self.fill(model, fromEntry: $0)
}
}
}

View File

@ -0,0 +1,40 @@
//
// Created by Ivan Vavilov on 5/22/17.
// Copyright (c) 2017 RedMadRobot LLC. All rights reserved.
//
import Foundation
import RealmSwift
/// `Realm DAO` configuration.
/// Incapsulates basic settings.
/// Used to initialize `Realm DAO`.
public struct RealmConfiguration {
/// Name of database file name.
public let databaseFileName: String
/// Version of database.
public let databaseVersion: UInt64
/// Migration block for manual migration.
public let migrationBlock: MigrationBlock?
/// Create an instance with specified `databaseFileName`, `databaseVersion`, `migrationBlock`.
///
/// - Parameters:
/// - databaseFileName: name. See above.
/// - databaseVersion: version. See above.
/// - migrationBlock: migration block. See above.
public init(
databaseFileName: String = "Database.realm",
databaseVersion: UInt64 = 1,
migrationBlock: MigrationBlock? = nil) {
self.databaseFileName = databaseFileName
self.databaseVersion = databaseVersion
self.migrationBlock = migrationBlock
}
}

View File

@ -0,0 +1,261 @@
//
// RealmDAO.swift
// DAO
//
// Created by Igor Bulyga on 04.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import Foundation
import Realm
import RealmSwift
/// `DAO` pattern implementation for `Realm`.
open class RealmDAO<Model: Entity, RealmModel: RLMEntry>: DAO<Model> {
// MARK: - Private
/// Translator for current `RLMEntry` and `RealmModel` types.
private let translator: RealmTranslator<Model, RealmModel>
// MARK: - Public
/// Creates an instance with specified `translator` and `configuration`.
///
/// - Parameters:
/// - translator: translator for current `Model` and `RealmModel` types.
/// - configuration: configuration. See also `RealmConfiguration`.
public init(_ translator: RealmTranslator<Model, RealmModel>,
configuration: RealmConfiguration) {
self.translator = translator
super.init()
loadDefaultRealm(configuration: configuration)
}
/// Creates an instance with specified `translator` and default configuration.
///
/// - Parameters:
/// - translator: translator for current `Model` and `RealmModel` types.
public convenience init(_ translator: RealmTranslator<Model, RealmModel>) {
self.init(translator,
configuration: RealmConfiguration())
}
//MARK: - DAO
override open func persist(_ entity: Model) throws {
if let entry = readFromRealm(entity.entityId) {
try autoreleasepool {
realm().beginWrite()
translator.fill(entry, fromEntity: entity)
try realm().commitWrite()
}
} else {
let entry = RealmModel()
translator.fill(entry, fromEntity: entity)
try write(entry)
}
}
open override func persist(_ entities: [Model]) throws {
let entries = List<RealmModel>(entities.map {
self.readFromRealm($0.entityId) ?? RealmModel()
})
translator.fill(entries, fromEntities: entities)
try write(entries)
}
override open func read(_ entityId: String) -> Model? {
guard let entry = readFromRealm(entityId) else {
return nil
}
let entity = Model()
translator.fill(entity, fromEntry: entry)
return entity
}
open override func read() -> [Model] {
return readFromRealm().map {
let entity = Model()
self.translator.fill(entity, fromEntry: $0)
return entity
}
}
open override func read(predicatedBy predicate: NSPredicate?) -> [Model] {
return read(predicatedBy: predicate, orderedBy: nil)
}
open override func read(orderedBy field: String?,
ascending: Bool) -> [Model] {
return read(predicatedBy: nil, orderedBy: field, ascending: ascending)
}
open override func read(predicatedBy predicate: NSPredicate?,
orderedBy field: String?,
ascending: Bool = true) -> [Model] {
var entries = readFromRealm(predicate)
if let field = field {
entries = entries.sorted(byKeyPath: field, ascending: ascending)
}
return entries.map {
let entity = Model()
self.translator.fill(entity, fromEntry: $0)
return entity
}
}
override open func erase() throws {
let results = readFromRealm()
let entries: List<RealmModel> = List<RealmModel>()
entries.append(objectsIn: results.map {
$0 as RealmModel
})
try self.delete(entries)
}
override open func erase(_ entityId: String) throws {
guard let entry = readFromRealm(entityId) else {
return
}
try delete(entry)
}
// MARK: - Private
private func write(_ entry: RealmModel) throws {
try self.realm().write {
self.realm().create(RealmModel.self, value: entry, update: true)
}
}
private func write(_ entries: List<RealmModel>) throws {
try self.realm().write {
entries.forEach { (e: RealmModel) -> () in
self.realm().create(RealmModel.self, value: e, update: true)
}
}
}
private func readFromRealm(_ entryId: String) -> RealmModel? {
return self.realm().object(ofType: RealmModel.self, forPrimaryKey: entryId)
}
private func readFromRealm(_ predicate: NSPredicate? = nil) -> Results<RealmModel> {
let results: Results<RealmModel> = self.realm().objects(RealmModel.self)
guard let predicate = predicate else {
return results
}
return results.filter(predicate)
}
private func delete(_ entry: RealmModel) throws {
try self.realm().write {
cascadeDelete(entry)
}
}
private func delete(_ entries: List<RealmModel>) throws {
try self.realm().write {
cascadeDelete(entries)
}
}
private func cascadeDelete(_ object: AnyObject?) {
if let deletable = object as? CascadeDeletionProtocol {
deletable.objectsToDelete.forEach { child in
cascadeDelete(child)
}
}
if let realmArray = object as? ListBase {
for i in 0..<realmArray.count {
let object = realmArray._rlmArray[UInt(i)]
cascadeDelete(object)
}
}
if let realmObject = object as? Object {
self.realm().delete(realmObject)
}
}
private func realm() -> Realm {
return try! Realm()
}
private func defaultRealmPathIsEqualToPath(_ path: URL?) -> Bool {
guard let path = path else {
return false
}
return Realm.Configuration.defaultConfiguration.fileURL == path
}
private func loadDefaultRealm(configuration: RealmConfiguration) {
guard let path = self.pathForFileName(configuration.databaseFileName) else {
fatalError("Cant find path for DB with filename: \(configuration.databaseFileName)" +
" v.\(configuration.databaseVersion)")
}
if defaultRealmPathIsEqualToPath(path) {
return
}
assignDefaultRealmPath(path)
migrateDefaultRealmToCurrentVersion(configuration: configuration)
}
private func pathForFileName(_ fileName: String) -> URL? {
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first as NSString?
guard let realmPath = documentDirectory?.appendingPathComponent(fileName) else {
return nil
}
return URL(string: realmPath)
}
private func assignDefaultRealmPath(_ path: URL) {
var configuration = Realm.Configuration.defaultConfiguration
configuration.fileURL = path
Realm.Configuration.defaultConfiguration = configuration
}
private func migrateDefaultRealmToCurrentVersion(configuration: RealmConfiguration) {
var config = Realm.Configuration.defaultConfiguration
config.schemaVersion = configuration.databaseVersion
config.migrationBlock = configuration.migrationBlock
Realm.Configuration.defaultConfiguration = config
}
}

View File

@ -0,0 +1,19 @@
//
// CascadeDeletionProtocol.swift
// DAO
//
// Created by Igor Bulyga on 24.06.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import Foundation
import RealmSwift
/// Protocol to implement cascade deletion of related entities
public protocol CascadeDeletionProtocol {
var objectsToDelete: [Object] { get }
}

View File

@ -0,0 +1,63 @@
//
// RLMEntry.swift
// DAO
//
// Created by Igor Bulyga on 04.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import Foundation
import RealmSwift
import Realm
/// Parent class for `Realm` entries.
open class RLMEntry: Object {
/// Entry identifier. Must be unique.
dynamic open var entryId: String
/// Creates an instance with specified `entryId`.
///
/// - Parameter entryId: entry identifier.
public init(entryId: String) {
self.entryId = entryId
super.init()
}
/// Creates an instance with emppty `entryId`.
public required init() {
self.entryId = ""
super.init()
}
/// Creates an instance with specified `realm` and `schema`.
///
/// - Parameters:
/// - realm: instance of RLMRealm.
/// - schema: instance of RLMObjectSchema.
required public init(realm: RLMRealm, schema: RLMObjectSchema) {
self.entryId = ""
super.init(realm: realm, schema: schema)
}
/// Creates an instance with specified `value` and `schema`.
///
/// - Parameters:
/// - value: value.
/// - schema: instance of `RLMSchema`.
required public init(value: Any, schema: RLMSchema) {
fatalError("init(value:schema:) has not been implemented")
}
override open class func primaryKey() -> String? {
return "entryId"
}
}

View File

@ -0,0 +1,157 @@
//
// RLMTypes.swift
// DAO
//
// Created by Ivan Vavilov on 5/17/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import UIKit
import RealmSwift
import Realm
/// Protocol for implement wrappers for standard types that Realm can't save now.
/// Use it if you want to save collection of standard type in Realm.
public protocol RLMPrimitiveType: class {
associatedtype A
var value: A { get set }
init(val: A)
}
/// String wrapper
open class RLMString: Object, RLMPrimitiveType {
public required init(val: String) {
value = val
super.init()
}
public required init(value: Any, schema: RLMSchema) {
fatalError("init(value:schema:) has not been implemented")
}
public required init(realm: RLMRealm, schema: RLMObjectSchema) {
super.init(realm: realm, schema: schema)
}
required public init() {
super.init()
}
public typealias A = String
public dynamic var value: String = ""
}
/// Integer wrapper
open class RLMInteger: Object, RLMPrimitiveType {
public required init(val: Int) {
value = val
super.init()
}
public required init(value: Any, schema: RLMSchema) {
fatalError("init(value:schema:) has not been implemented")
}
public required init(realm: RLMRealm, schema: RLMObjectSchema) {
super.init(realm: realm, schema: schema)
}
required public init() {
super.init()
}
public typealias A = Int
public dynamic var value: Int = 0
}
/// Double wrapper
open class RLMDouble: Object, RLMPrimitiveType {
public required init(val: Double) {
value = val
super.init()
}
public required init(value: Any, schema: RLMSchema) {
fatalError("init(value:schema:) has not been implemented")
}
public required init(realm: RLMRealm, schema: RLMObjectSchema) {
super.init(realm: realm, schema: schema)
}
required public init() {
super.init()
}
public typealias A = Double
public dynamic var value: Double = 0.0
}
/// Date wrapper
open class RLMDate: Object, RLMPrimitiveType {
public required init(val: Date) {
super.init()
}
public required init(value: Any, schema: RLMSchema) {
fatalError("init(value:schema:) has not been implemented")
}
public required init(realm: RLMRealm, schema: RLMObjectSchema) {
super.init(realm: realm, schema: schema)
}
required public init() {
super.init()
}
public typealias A = Date
public dynamic var value: Date = Date()
}
/// Data wrapper
open class RLMData: Object, RLMPrimitiveType {
public required init(val: Data) {
value = val
super.init()
}
public required init(value: Any, schema: RLMSchema) {
fatalError("init(value:schema:) has not been implemented")
}
public required init(realm: RLMRealm, schema: RLMObjectSchema) {
super.init(realm: realm, schema: schema)
}
required public init() {
super.init()
}
public typealias A = Data
public dynamic var value: Data = Data()
}

View File

@ -0,0 +1,73 @@
//
// RealmTranslator.swift
// DAO
//
// Created by Igor Bulyga on 04.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import Foundation
import RealmSwift
open class RealmTranslator<Model: Entity, RealmModel: RLMEntry> {
public required init() {}
open func fill(_ entry: RealmModel, fromEntity: Model) {
fatalError("Abstract method")
}
open func fill(_ entity: Model, fromEntry: RealmModel) {
fatalError("Abstract method")
}
/// All properties of entities will be overridden by entries properties.
/// If entry doesn't exist, it'll be created.
///
/// - Parameters:
/// - entries: list of instances of `RealmModel` type.
/// - fromEntities: array of instances of `Model` type.
open func fill(_ entries: List<RealmModel>, fromEntities: [Model]) {
let oldEntries = entries.map { $0 }
fromEntities
.map { entity -> (RealmModel, Model) in
let entry = oldEntries
.filter { $0.entryId == entity.entityId }
.first
if let entry = entry {
return (entry, entity)
} else {
let entry = RealmModel()
entries.append(entry)
return (entry, entity)
}
}
.forEach {
self.fill($0.0, fromEntity: $0.1)
}
}
/// All properties of entries will be overridden by entities properties.
///
/// - Parameters:
/// - entities: array of instances of `Model` type.
/// - fromEntries: list of instances of `RealmModel` type.
open func fill( _ entities: inout [Model], fromEntries: List<RealmModel>) {
entities.removeAll()
fromEntries.forEach {
let model = Model()
entities.append(model)
self.fill(model, fromEntry: $0)
}
}
}

View File

@ -0,0 +1,168 @@
//
// CoreDataDAOEntityTests.swift
// DAO
//
// Created by Ivan Vavilov on 4/25/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import XCTest
import DAO
import CoreData
@testable import DAO_Example
final class CoreDataDAOEntityTests: XCTestCase {
let dao = try! CoreDataDAO(
CDEntityTranslator(),
configuration: CoreDataConfiguration(
containerName: "Model",
storeType: NSInMemoryStoreType))
func testReadById() {
let entity = Entity(entityId: "2")
do {
try dao.persist(entity)
} catch _ {
XCTFail("Read by id is failed")
}
if let savedEntity = dao.read("2") {
XCTAssertEqual(savedEntity.entityId, entity.entityId)
} else {
XCTFail("Read by id is failed")
}
}
func testAsyncReadById() {
let entity = Entity(entityId: "2_back")
let exp = expectation(description: "")
DispatchQueue.global().async {
do {
try self.dao.persist(entity)
} catch _ {
XCTFail("Async read by id is failed")
}
DispatchQueue.main.async {
if let savedEntity = self.dao.read("2_back") {
XCTAssertEqual(savedEntity.entityId, entity.entityId)
} else {
XCTFail("Async read by id is failed")
}
exp.fulfill()
}
}
waitForExpectations(timeout: 5) { error in
if error != nil {
XCTFail("Async read by id is failed")
}
XCTAssert(true)
}
}
func testPersist() {
let entity = Entity(entityId: "1")
do {
try dao.persist(entity)
} catch _ {
XCTFail("Persist is failed")
}
XCTAssert(true)
}
func testPersistAll() {
let firstEntity = Entity(entityId: "2")
let secondEntity = Entity(entityId: "3")
do {
try dao.persist([firstEntity, secondEntity])
} catch _ {
XCTFail("Persist All is failed")
}
XCTAssert(true)
}
func testAsyncPersist() {
let exp = expectation(description: "")
DispatchQueue.global().async {
let entity = Entity(entityId: "1_back")
do {
try self.dao.persist(entity)
} catch _ {
XCTFail("Saving entity in background is failed")
}
exp.fulfill()
}
waitForExpectations(timeout: 5) { error in
if error != nil {
XCTFail("Saving entity in background is failed")
}
XCTAssert(true)
}
}
func testEraseById() {
let entity = Entity(entityId: "3")
do {
try dao.persist(entity)
try dao.erase("3")
} catch _ {
XCTFail("Erase is failed")
}
XCTAssert(true)
}
func testAsyncEraseById() {
let entity = Entity(entityId: "2_back")
do {
try dao.persist(entity)
} catch _ {
XCTFail("Async erase by id is failed")
}
let exp = expectation(description: "")
DispatchQueue.global().async {
do {
try self.dao.erase("2_back")
} catch _ {
XCTFail("Async erase by id is failed")
}
exp.fulfill()
}
waitForExpectations(timeout: 5) { error in
if error != nil {
XCTFail("Async erase by id is failed")
}
XCTAssert(true)
}
}
}

View File

@ -0,0 +1,43 @@
//
// CoreDataDAOFoldersTests.swift
// DAO
//
// Created by Ivan Vavilov on 5/23/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import XCTest
import DAO
import CoreData
@testable import DAO_Example
final class CoreDataDAOFoldersTests: XCTestCase {
let dao = try! CoreDataDAO(
CDFolderTranslator(),
configuration: CoreDataConfiguration(
containerName: "Model",
storeType: NSInMemoryStoreType))
func testPersistMessages() {
let message1 = Message(entityId: "abc", text: "text1")
let message2 = Message(entityId: "bcc", text: "text2")
let folder = Folder(entityId: "fld", name: "Home", messages: [message1, message2])
do {
try dao.persist(folder)
} catch _ {
XCTFail("Persist folder is failed")
}
if let savedFolder = dao.read(folder.entityId) {
XCTAssertEqual(folder.messages.count, savedFolder.messages.count)
} else {
XCTFail("Persist folder is failed")
}
}
}

View File

@ -0,0 +1,45 @@
//
// CoreDataDAOManyDAOTests.swift
// DAO
//
// Created by Ivan Vavilov on 5/22/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import XCTest
import DAO
import CoreData
@testable import DAO_Example
final class CoreDataDAOManyDAOTests: XCTestCase {
let messagesDAO = try! CoreDataDAO(
CDMessageTranslator(),
configuration: CoreDataConfiguration(
containerName: "Model",
storeType: NSInMemoryStoreType))
let folderDAO = try! CoreDataDAO(
CDFolderTranslator(),
configuration: CoreDataConfiguration(
containerName: "Model",
storeType: NSInMemoryStoreType))
func testPersistMessage() {
let message = Message(entityId: "abc", text: "text")
let folder = Folder(entityId: "fld", name: "folder", messages: [])
do {
try messagesDAO.persist(message)
try folderDAO.persist(folder)
} catch _ {
XCTFail("Persist message is failed")
}
XCTAssertEqual(message, messagesDAO.read(message.entityId))
XCTAssertEqual(folder, folderDAO.read(folder.entityId))
}
}

View File

@ -0,0 +1,65 @@
//
// CoreDataDAOMessagesTests.swift
// DAO
//
// Created by Ivan Vavilov on 5/2/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import XCTest
import DAO
import CoreData
@testable import DAO_Example
final class CoreDataDAOMessagesTests: XCTestCase {
let dao = try! CoreDataDAO(
CDMessageTranslator(),
configuration: CoreDataConfiguration(
containerName: "Model",
storeType: NSInMemoryStoreType))
func testPersistMessage() {
let message = Message(entityId: "abc", text: "text")
do {
try dao.persist(message)
} catch _ {
XCTFail("Persist message is failed")
}
XCTAssertEqual(message, dao.read(message.entityId))
}
func testReadMessage() {
let message = Message(entityId: "def", text: "text 2")
do {
try dao.persist(message)
} catch _ {
XCTFail("Read message is failed")
}
XCTAssertEqual(message, dao.read("def"))
}
func testEraseMessage() {
let message = Message(entityId: "ghi", text: "text 2")
do {
try dao.persist(message)
try dao.erase("ghi")
} catch _ {
XCTFail("Erase message is failed")
}
XCTAssertNil(dao.read("ghi"))
}
}

View File

@ -0,0 +1,4 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -0,0 +1,957 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
63EBBC5B24D75059B9ADA532 /* Pods_RealmDAOTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0DCA2A834AEC013372828BE4 /* Pods_RealmDAOTests.framework */; };
78A211B7C1B6D6AF282EBB71 /* Pods_DAO_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A944DFD46BDAF9137BA01D6 /* Pods_DAO_Example.framework */; };
AA10ECB91EEFE058001228A1 /* RealmDAOBookTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA10ECB51EEFE058001228A1 /* RealmDAOBookTests.swift */; };
AA10ECBA1EEFE058001228A1 /* RealmDAOEntityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA10ECB61EEFE058001228A1 /* RealmDAOEntityTests.swift */; };
AA10ECBB1EEFE058001228A1 /* RealmDAOFolderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA10ECB71EEFE058001228A1 /* RealmDAOFolderTests.swift */; };
AA10ECBC1EEFE058001228A1 /* RealmDAOMessagesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA10ECB81EEFE058001228A1 /* RealmDAOMessagesTests.swift */; };
AA35256B1EEFDBE2009C4375 /* CDEntityTranslator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525531EEFDBE2009C4375 /* CDEntityTranslator.swift */; };
AA35256C1EEFDBE2009C4375 /* CDFolderTranslator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525541EEFDBE2009C4375 /* CDFolderTranslator.swift */; };
AA35256D1EEFDBE2009C4375 /* CDMessageTranslator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525551EEFDBE2009C4375 /* CDMessageTranslator.swift */; };
AA35256E1EEFDBE2009C4375 /* RLMBookTranslator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525571EEFDBE2009C4375 /* RLMBookTranslator.swift */; };
AA35256F1EEFDBE2009C4375 /* RLMEntityTranslator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525581EEFDBE2009C4375 /* RLMEntityTranslator.swift */; };
AA3525701EEFDBE2009C4375 /* RLMFolderTranslator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525591EEFDBE2009C4375 /* RLMFolderTranslator.swift */; };
AA3525711EEFDBE2009C4375 /* RLMMessageTranslator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA35255A1EEFDBE2009C4375 /* RLMMessageTranslator.swift */; };
AA3525721EEFDBE2009C4375 /* Book.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA35255C1EEFDBE2009C4375 /* Book.swift */; };
AA3525731EEFDBE2009C4375 /* CDEntity+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA35255E1EEFDBE2009C4375 /* CDEntity+CoreDataProperties.swift */; };
AA3525741EEFDBE2009C4375 /* CDEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA35255F1EEFDBE2009C4375 /* CDEntity.swift */; };
AA3525751EEFDBE2009C4375 /* CDFolder+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525601EEFDBE2009C4375 /* CDFolder+CoreDataProperties.swift */; };
AA3525761EEFDBE2009C4375 /* CDFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525611EEFDBE2009C4375 /* CDFolder.swift */; };
AA3525771EEFDBE2009C4375 /* CDMessage+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525621EEFDBE2009C4375 /* CDMessage+CoreDataProperties.swift */; };
AA3525781EEFDBE2009C4375 /* CDMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525631EEFDBE2009C4375 /* CDMessage.swift */; };
AA3525791EEFDBE2009C4375 /* Folder.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525641EEFDBE2009C4375 /* Folder.swift */; };
AA35257A1EEFDBE2009C4375 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525651EEFDBE2009C4375 /* Message.swift */; };
AA35257B1EEFDBE2009C4375 /* DBBook.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525671EEFDBE2009C4375 /* DBBook.swift */; };
AA35257C1EEFDBE2009C4375 /* DBEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525681EEFDBE2009C4375 /* DBEntity.swift */; };
AA35257D1EEFDBE2009C4375 /* DBFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525691EEFDBE2009C4375 /* DBFolder.swift */; };
AA35257E1EEFDBE2009C4375 /* DBMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA35256A1EEFDBE2009C4375 /* DBMessage.swift */; };
AA3525821EEFDC24009C4375 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = AA3525801EEFDC24009C4375 /* Model.xcdatamodeld */; };
AA3525961EEFDD13009C4375 /* CoreDataDAOEntityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525921EEFDD13009C4375 /* CoreDataDAOEntityTests.swift */; };
AA3525971EEFDD13009C4375 /* CoreDataDAOFoldersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525931EEFDD13009C4375 /* CoreDataDAOFoldersTests.swift */; };
AA3525981EEFDD13009C4375 /* CoreDataDAOManyDAOTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525941EEFDD13009C4375 /* CoreDataDAOManyDAOTests.swift */; };
AA3525991EEFDD13009C4375 /* CoreDataDAOMessagesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3525951EEFDD13009C4375 /* CoreDataDAOMessagesTests.swift */; };
E6862F802F1820084726DEB8 /* Pods_CoreDataDAOTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F42144986137E1707B5FAC0 /* Pods_CoreDataDAOTests.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
AA10ECAF1EEFE039001228A1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 607FACC81AFB9204008FA782 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 607FACCF1AFB9204008FA782;
remoteInfo = DAO_Example;
};
AA35258C1EEFDCE6009C4375 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 607FACC81AFB9204008FA782 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 607FACCF1AFB9204008FA782;
remoteInfo = DAO_Example;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
048D2FC052C450E7600E2FA9 /* Pods-RealmDAOTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RealmDAOTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RealmDAOTests/Pods-RealmDAOTests.release.xcconfig"; sourceTree = "<group>"; };
0DCA2A834AEC013372828BE4 /* Pods_RealmDAOTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RealmDAOTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1DD31E834DFA3BE6198A94A4 /* Pods-CoreDataDAOTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreDataDAOTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreDataDAOTests/Pods-CoreDataDAOTests.release.xcconfig"; sourceTree = "<group>"; };
2A944DFD46BDAF9137BA01D6 /* Pods_DAO_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DAO_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
33B58A69D9690C75477DB06B /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
607FACD01AFB9204008FA782 /* DAO_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DAO_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
6B14B1EA7DC79FC4DC1DE526 /* Pods-DAO_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DAO_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-DAO_Example/Pods-DAO_Example.release.xcconfig"; sourceTree = "<group>"; };
6F42144986137E1707B5FAC0 /* Pods_CoreDataDAOTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CoreDataDAOTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7AA81098C68FE90BF55455CC /* DAO.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = DAO.podspec; path = ../DAO.podspec; sourceTree = "<group>"; };
8FB85F7F7AE5E16EDA09AF5A /* Pods-RealmDAOTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RealmDAOTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RealmDAOTests/Pods-RealmDAOTests.debug.xcconfig"; sourceTree = "<group>"; };
9096125064B44D5035341130 /* Pods-DAO_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DAO_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DAO_Example/Pods-DAO_Example.debug.xcconfig"; sourceTree = "<group>"; };
A0C0C1D67BC9E557747CBD93 /* Pods-DAO_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DAO_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DAO_Tests/Pods-DAO_Tests.debug.xcconfig"; sourceTree = "<group>"; };
AA10ECAA1EEFE039001228A1 /* RealmDAOTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RealmDAOTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
AA10ECAE1EEFE039001228A1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AA10ECB41EEFE058001228A1 /* RealmDAOTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RealmDAOTests-Bridging-Header.h"; sourceTree = "<group>"; };
AA10ECB51EEFE058001228A1 /* RealmDAOBookTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmDAOBookTests.swift; sourceTree = "<group>"; };
AA10ECB61EEFE058001228A1 /* RealmDAOEntityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmDAOEntityTests.swift; sourceTree = "<group>"; };
AA10ECB71EEFE058001228A1 /* RealmDAOFolderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmDAOFolderTests.swift; sourceTree = "<group>"; };
AA10ECB81EEFE058001228A1 /* RealmDAOMessagesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmDAOMessagesTests.swift; sourceTree = "<group>"; };
AA3525531EEFDBE2009C4375 /* CDEntityTranslator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CDEntityTranslator.swift; sourceTree = "<group>"; };
AA3525541EEFDBE2009C4375 /* CDFolderTranslator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CDFolderTranslator.swift; sourceTree = "<group>"; };
AA3525551EEFDBE2009C4375 /* CDMessageTranslator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CDMessageTranslator.swift; sourceTree = "<group>"; };
AA3525571EEFDBE2009C4375 /* RLMBookTranslator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RLMBookTranslator.swift; sourceTree = "<group>"; };
AA3525581EEFDBE2009C4375 /* RLMEntityTranslator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RLMEntityTranslator.swift; sourceTree = "<group>"; };
AA3525591EEFDBE2009C4375 /* RLMFolderTranslator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RLMFolderTranslator.swift; sourceTree = "<group>"; };
AA35255A1EEFDBE2009C4375 /* RLMMessageTranslator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RLMMessageTranslator.swift; sourceTree = "<group>"; };
AA35255C1EEFDBE2009C4375 /* Book.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Book.swift; sourceTree = "<group>"; };
AA35255E1EEFDBE2009C4375 /* CDEntity+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CDEntity+CoreDataProperties.swift"; sourceTree = "<group>"; };
AA35255F1EEFDBE2009C4375 /* CDEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CDEntity.swift; sourceTree = "<group>"; };
AA3525601EEFDBE2009C4375 /* CDFolder+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CDFolder+CoreDataProperties.swift"; sourceTree = "<group>"; };
AA3525611EEFDBE2009C4375 /* CDFolder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CDFolder.swift; sourceTree = "<group>"; };
AA3525621EEFDBE2009C4375 /* CDMessage+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CDMessage+CoreDataProperties.swift"; sourceTree = "<group>"; };
AA3525631EEFDBE2009C4375 /* CDMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CDMessage.swift; sourceTree = "<group>"; };
AA3525641EEFDBE2009C4375 /* Folder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Folder.swift; sourceTree = "<group>"; };
AA3525651EEFDBE2009C4375 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = "<group>"; };
AA3525671EEFDBE2009C4375 /* DBBook.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DBBook.swift; sourceTree = "<group>"; };
AA3525681EEFDBE2009C4375 /* DBEntity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DBEntity.swift; sourceTree = "<group>"; };
AA3525691EEFDBE2009C4375 /* DBFolder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DBFolder.swift; sourceTree = "<group>"; };
AA35256A1EEFDBE2009C4375 /* DBMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DBMessage.swift; sourceTree = "<group>"; };
AA3525811EEFDC24009C4375 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
AA3525871EEFDCE6009C4375 /* CoreDataDAOTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreDataDAOTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
AA35258B1EEFDCE6009C4375 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AA3525911EEFDD13009C4375 /* CoreDataDAOTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CoreDataDAOTests-Bridging-Header.h"; sourceTree = "<group>"; };
AA3525921EEFDD13009C4375 /* CoreDataDAOEntityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataDAOEntityTests.swift; sourceTree = "<group>"; };
AA3525931EEFDD13009C4375 /* CoreDataDAOFoldersTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataDAOFoldersTests.swift; sourceTree = "<group>"; };
AA3525941EEFDD13009C4375 /* CoreDataDAOManyDAOTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataDAOManyDAOTests.swift; sourceTree = "<group>"; };
AA3525951EEFDD13009C4375 /* CoreDataDAOMessagesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataDAOMessagesTests.swift; sourceTree = "<group>"; };
B3F6075B730F33239A8C0C16 /* Pods-DAO_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DAO_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DAO_Tests/Pods-DAO_Tests.release.xcconfig"; sourceTree = "<group>"; };
B83929C10B53857ABAEBA293 /* Pods-CoreDataDAOTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreDataDAOTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreDataDAOTests/Pods-CoreDataDAOTests.debug.xcconfig"; sourceTree = "<group>"; };
BF445E2FB5382CAF4125954E /* Pods_DAO_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DAO_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F8C399142A0F0FA7C064D093 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
607FACCD1AFB9204008FA782 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
78A211B7C1B6D6AF282EBB71 /* Pods_DAO_Example.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
AA10ECA71EEFE039001228A1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
63EBBC5B24D75059B9ADA532 /* Pods_RealmDAOTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
AA3525841EEFDCE6009C4375 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E6862F802F1820084726DEB8 /* Pods_CoreDataDAOTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
607FACC71AFB9204008FA782 = {
isa = PBXGroup;
children = (
607FACD21AFB9204008FA782 /* Example for DAO */,
AA3525881EEFDCE6009C4375 /* CoreDataDAOTests */,
AA10ECAB1EEFE039001228A1 /* RealmDAOTests */,
CB0F3F47EAF7977E58A370FB /* Frameworks */,
EF4D865297EF284754A73C8C /* Pods */,
607FACF51AFB993E008FA782 /* Podspec Metadata */,
607FACD11AFB9204008FA782 /* Products */,
);
sourceTree = "<group>";
};
607FACD11AFB9204008FA782 /* Products */ = {
isa = PBXGroup;
children = (
607FACD01AFB9204008FA782 /* DAO_Example.app */,
AA3525871EEFDCE6009C4375 /* CoreDataDAOTests.xctest */,
AA10ECAA1EEFE039001228A1 /* RealmDAOTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
607FACD21AFB9204008FA782 /* Example for DAO */ = {
isa = PBXGroup;
children = (
607FACD51AFB9204008FA782 /* AppDelegate.swift */,
AA35254E1EEFDBE2009C4375 /* Classes */,
AA35257F1EEFDC24009C4375 /* Resources */,
607FACD31AFB9204008FA782 /* Supporting Files */,
);
name = "Example for DAO";
path = DAO;
sourceTree = "<group>";
};
607FACD31AFB9204008FA782 /* Supporting Files */ = {
isa = PBXGroup;
children = (
607FACD41AFB9204008FA782 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
607FACF51AFB993E008FA782 /* Podspec Metadata */ = {
isa = PBXGroup;
children = (
7AA81098C68FE90BF55455CC /* DAO.podspec */,
33B58A69D9690C75477DB06B /* README.md */,
F8C399142A0F0FA7C064D093 /* LICENSE */,
);
name = "Podspec Metadata";
sourceTree = "<group>";
};
AA10ECAB1EEFE039001228A1 /* RealmDAOTests */ = {
isa = PBXGroup;
children = (
AA10ECAE1EEFE039001228A1 /* Info.plist */,
AA10ECB51EEFE058001228A1 /* RealmDAOBookTests.swift */,
AA10ECB61EEFE058001228A1 /* RealmDAOEntityTests.swift */,
AA10ECB71EEFE058001228A1 /* RealmDAOFolderTests.swift */,
AA10ECB81EEFE058001228A1 /* RealmDAOMessagesTests.swift */,
AA10ECB41EEFE058001228A1 /* RealmDAOTests-Bridging-Header.h */,
);
path = RealmDAOTests;
sourceTree = "<group>";
};
AA35254E1EEFDBE2009C4375 /* Classes */ = {
isa = PBXGroup;
children = (
AA35254F1EEFDBE2009C4375 /* Business Logic */,
AA35255B1EEFDBE2009C4375 /* Model */,
);
path = Classes;
sourceTree = "<group>";
};
AA35254F1EEFDBE2009C4375 /* Business Logic */ = {
isa = PBXGroup;
children = (
AA3525501EEFDBE2009C4375 /* Helper */,
);
path = "Business Logic";
sourceTree = "<group>";
};
AA3525501EEFDBE2009C4375 /* Helper */ = {
isa = PBXGroup;
children = (
AA3525511EEFDBE2009C4375 /* DAO */,
);
path = Helper;
sourceTree = "<group>";
};
AA3525511EEFDBE2009C4375 /* DAO */ = {
isa = PBXGroup;
children = (
AA3525521EEFDBE2009C4375 /* CoreDataTranslator */,
AA3525561EEFDBE2009C4375 /* RealmTranslator */,
);
path = DAO;
sourceTree = "<group>";
};
AA3525521EEFDBE2009C4375 /* CoreDataTranslator */ = {
isa = PBXGroup;
children = (
AA3525531EEFDBE2009C4375 /* CDEntityTranslator.swift */,
AA3525541EEFDBE2009C4375 /* CDFolderTranslator.swift */,
AA3525551EEFDBE2009C4375 /* CDMessageTranslator.swift */,
);
path = CoreDataTranslator;
sourceTree = "<group>";
};
AA3525561EEFDBE2009C4375 /* RealmTranslator */ = {
isa = PBXGroup;
children = (
AA3525571EEFDBE2009C4375 /* RLMBookTranslator.swift */,
AA3525581EEFDBE2009C4375 /* RLMEntityTranslator.swift */,
AA3525591EEFDBE2009C4375 /* RLMFolderTranslator.swift */,
AA35255A1EEFDBE2009C4375 /* RLMMessageTranslator.swift */,
);
path = RealmTranslator;
sourceTree = "<group>";
};
AA35255B1EEFDBE2009C4375 /* Model */ = {
isa = PBXGroup;
children = (
AA35255C1EEFDBE2009C4375 /* Book.swift */,
AA35255D1EEFDBE2009C4375 /* CoreDataDatabase */,
AA3525641EEFDBE2009C4375 /* Folder.swift */,
AA3525651EEFDBE2009C4375 /* Message.swift */,
AA3525661EEFDBE2009C4375 /* RealmDatabase */,
);
path = Model;
sourceTree = "<group>";
};
AA35255D1EEFDBE2009C4375 /* CoreDataDatabase */ = {
isa = PBXGroup;
children = (
AA35255F1EEFDBE2009C4375 /* CDEntity.swift */,
AA35255E1EEFDBE2009C4375 /* CDEntity+CoreDataProperties.swift */,
AA3525611EEFDBE2009C4375 /* CDFolder.swift */,
AA3525601EEFDBE2009C4375 /* CDFolder+CoreDataProperties.swift */,
AA3525631EEFDBE2009C4375 /* CDMessage.swift */,
AA3525621EEFDBE2009C4375 /* CDMessage+CoreDataProperties.swift */,
);
path = CoreDataDatabase;
sourceTree = "<group>";
};
AA3525661EEFDBE2009C4375 /* RealmDatabase */ = {
isa = PBXGroup;
children = (
AA3525671EEFDBE2009C4375 /* DBBook.swift */,
AA3525681EEFDBE2009C4375 /* DBEntity.swift */,
AA3525691EEFDBE2009C4375 /* DBFolder.swift */,
AA35256A1EEFDBE2009C4375 /* DBMessage.swift */,
);
path = RealmDatabase;
sourceTree = "<group>";
};
AA35257F1EEFDC24009C4375 /* Resources */ = {
isa = PBXGroup;
children = (
AA3525801EEFDC24009C4375 /* Model.xcdatamodeld */,
);
path = Resources;
sourceTree = "<group>";
};
AA3525881EEFDCE6009C4375 /* CoreDataDAOTests */ = {
isa = PBXGroup;
children = (
AA3525921EEFDD13009C4375 /* CoreDataDAOEntityTests.swift */,
AA3525931EEFDD13009C4375 /* CoreDataDAOFoldersTests.swift */,
AA3525941EEFDD13009C4375 /* CoreDataDAOManyDAOTests.swift */,
AA3525951EEFDD13009C4375 /* CoreDataDAOMessagesTests.swift */,
AA3525911EEFDD13009C4375 /* CoreDataDAOTests-Bridging-Header.h */,
AA35258B1EEFDCE6009C4375 /* Info.plist */,
);
path = CoreDataDAOTests;
sourceTree = "<group>";
};
CB0F3F47EAF7977E58A370FB /* Frameworks */ = {
isa = PBXGroup;
children = (
2A944DFD46BDAF9137BA01D6 /* Pods_DAO_Example.framework */,
BF445E2FB5382CAF4125954E /* Pods_DAO_Tests.framework */,
6F42144986137E1707B5FAC0 /* Pods_CoreDataDAOTests.framework */,
0DCA2A834AEC013372828BE4 /* Pods_RealmDAOTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
EF4D865297EF284754A73C8C /* Pods */ = {
isa = PBXGroup;
children = (
9096125064B44D5035341130 /* Pods-DAO_Example.debug.xcconfig */,
6B14B1EA7DC79FC4DC1DE526 /* Pods-DAO_Example.release.xcconfig */,
A0C0C1D67BC9E557747CBD93 /* Pods-DAO_Tests.debug.xcconfig */,
B3F6075B730F33239A8C0C16 /* Pods-DAO_Tests.release.xcconfig */,
B83929C10B53857ABAEBA293 /* Pods-CoreDataDAOTests.debug.xcconfig */,
1DD31E834DFA3BE6198A94A4 /* Pods-CoreDataDAOTests.release.xcconfig */,
8FB85F7F7AE5E16EDA09AF5A /* Pods-RealmDAOTests.debug.xcconfig */,
048D2FC052C450E7600E2FA9 /* Pods-RealmDAOTests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
607FACCF1AFB9204008FA782 /* DAO_Example */ = {
isa = PBXNativeTarget;
buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DAO_Example" */;
buildPhases = (
396DD212B4355BA1D08DC7E7 /* [CP] Check Pods Manifest.lock */,
607FACCC1AFB9204008FA782 /* Sources */,
607FACCD1AFB9204008FA782 /* Frameworks */,
607FACCE1AFB9204008FA782 /* Resources */,
A3C342A12354181FB1CDC888 /* [CP] Embed Pods Frameworks */,
FBB72B6CB6EF1FFF9E33FE93 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = DAO_Example;
productName = DAO;
productReference = 607FACD01AFB9204008FA782 /* DAO_Example.app */;
productType = "com.apple.product-type.application";
};
AA10ECA91EEFE039001228A1 /* RealmDAOTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = AA10ECB11EEFE039001228A1 /* Build configuration list for PBXNativeTarget "RealmDAOTests" */;
buildPhases = (
847A3AC11FE1C324C80B4DFC /* [CP] Check Pods Manifest.lock */,
AA10ECA61EEFE039001228A1 /* Sources */,
AA10ECA71EEFE039001228A1 /* Frameworks */,
AA10ECA81EEFE039001228A1 /* Resources */,
C31918995F93713C33A15BCA /* [CP] Embed Pods Frameworks */,
525D7AFD3BD0F596CBD437B0 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
AA10ECB01EEFE039001228A1 /* PBXTargetDependency */,
);
name = RealmDAOTests;
productName = RealmDAOTests;
productReference = AA10ECAA1EEFE039001228A1 /* RealmDAOTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
AA3525861EEFDCE6009C4375 /* CoreDataDAOTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = AA35258E1EEFDCE6009C4375 /* Build configuration list for PBXNativeTarget "CoreDataDAOTests" */;
buildPhases = (
EC8476E3A4C369B6B36446A1 /* [CP] Check Pods Manifest.lock */,
AA3525831EEFDCE6009C4375 /* Sources */,
AA3525841EEFDCE6009C4375 /* Frameworks */,
AA3525851EEFDCE6009C4375 /* Resources */,
6E99BAE18868857CA3143787 /* [CP] Embed Pods Frameworks */,
E809FAD87FAC0879AF2B934A /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
AA35258D1EEFDCE6009C4375 /* PBXTargetDependency */,
);
name = CoreDataDAOTests;
productName = CoreDataDAOTests;
productReference = AA3525871EEFDCE6009C4375 /* CoreDataDAOTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
607FACC81AFB9204008FA782 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0830;
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = CocoaPods;
TargetAttributes = {
607FACCF1AFB9204008FA782 = {
CreatedOnToolsVersion = 6.3.1;
LastSwiftMigration = 0820;
};
AA10ECA91EEFE039001228A1 = {
CreatedOnToolsVersion = 8.3.2;
DevelopmentTeam = 42LRQS6X44;
LastSwiftMigration = 0830;
ProvisioningStyle = Automatic;
TestTargetID = 607FACCF1AFB9204008FA782;
};
AA3525861EEFDCE6009C4375 = {
CreatedOnToolsVersion = 8.3.2;
DevelopmentTeam = 42LRQS6X44;
LastSwiftMigration = 0830;
ProvisioningStyle = Automatic;
TestTargetID = 607FACCF1AFB9204008FA782;
};
};
};
buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "DAO" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 607FACC71AFB9204008FA782;
productRefGroup = 607FACD11AFB9204008FA782 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
607FACCF1AFB9204008FA782 /* DAO_Example */,
AA3525861EEFDCE6009C4375 /* CoreDataDAOTests */,
AA10ECA91EEFE039001228A1 /* RealmDAOTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
607FACCE1AFB9204008FA782 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
AA10ECA81EEFE039001228A1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
AA3525851EEFDCE6009C4375 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
396DD212B4355BA1D08DC7E7 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
525D7AFD3BD0F596CBD437B0 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RealmDAOTests/Pods-RealmDAOTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
6E99BAE18868857CA3143787 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreDataDAOTests/Pods-CoreDataDAOTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
847A3AC11FE1C324C80B4DFC /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
A3C342A12354181FB1CDC888 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DAO_Example/Pods-DAO_Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
C31918995F93713C33A15BCA /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RealmDAOTests/Pods-RealmDAOTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
E809FAD87FAC0879AF2B934A /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreDataDAOTests/Pods-CoreDataDAOTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
EC8476E3A4C369B6B36446A1 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
FBB72B6CB6EF1FFF9E33FE93 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DAO_Example/Pods-DAO_Example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
607FACCC1AFB9204008FA782 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AA35256E1EEFDBE2009C4375 /* RLMBookTranslator.swift in Sources */,
AA3525731EEFDBE2009C4375 /* CDEntity+CoreDataProperties.swift in Sources */,
AA3525771EEFDBE2009C4375 /* CDMessage+CoreDataProperties.swift in Sources */,
AA35257D1EEFDBE2009C4375 /* DBFolder.swift in Sources */,
AA35257C1EEFDBE2009C4375 /* DBEntity.swift in Sources */,
AA35257A1EEFDBE2009C4375 /* Message.swift in Sources */,
AA3525791EEFDBE2009C4375 /* Folder.swift in Sources */,
AA3525741EEFDBE2009C4375 /* CDEntity.swift in Sources */,
AA3525781EEFDBE2009C4375 /* CDMessage.swift in Sources */,
AA3525821EEFDC24009C4375 /* Model.xcdatamodeld in Sources */,
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
AA35257B1EEFDBE2009C4375 /* DBBook.swift in Sources */,
AA3525701EEFDBE2009C4375 /* RLMFolderTranslator.swift in Sources */,
AA35257E1EEFDBE2009C4375 /* DBMessage.swift in Sources */,
AA35256F1EEFDBE2009C4375 /* RLMEntityTranslator.swift in Sources */,
AA3525761EEFDBE2009C4375 /* CDFolder.swift in Sources */,
AA35256C1EEFDBE2009C4375 /* CDFolderTranslator.swift in Sources */,
AA3525721EEFDBE2009C4375 /* Book.swift in Sources */,
AA35256D1EEFDBE2009C4375 /* CDMessageTranslator.swift in Sources */,
AA35256B1EEFDBE2009C4375 /* CDEntityTranslator.swift in Sources */,
AA3525751EEFDBE2009C4375 /* CDFolder+CoreDataProperties.swift in Sources */,
AA3525711EEFDBE2009C4375 /* RLMMessageTranslator.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
AA10ECA61EEFE039001228A1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AA10ECB91EEFE058001228A1 /* RealmDAOBookTests.swift in Sources */,
AA10ECBA1EEFE058001228A1 /* RealmDAOEntityTests.swift in Sources */,
AA10ECBC1EEFE058001228A1 /* RealmDAOMessagesTests.swift in Sources */,
AA10ECBB1EEFE058001228A1 /* RealmDAOFolderTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
AA3525831EEFDCE6009C4375 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AA3525961EEFDD13009C4375 /* CoreDataDAOEntityTests.swift in Sources */,
AA3525981EEFDD13009C4375 /* CoreDataDAOManyDAOTests.swift in Sources */,
AA3525971EEFDD13009C4375 /* CoreDataDAOFoldersTests.swift in Sources */,
AA3525991EEFDD13009C4375 /* CoreDataDAOMessagesTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
AA10ECB01EEFE039001228A1 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 607FACCF1AFB9204008FA782 /* DAO_Example */;
targetProxy = AA10ECAF1EEFE039001228A1 /* PBXContainerItemProxy */;
};
AA35258D1EEFDCE6009C4375 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 607FACCF1AFB9204008FA782 /* DAO_Example */;
targetProxy = AA35258C1EEFDCE6009C4375 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
607FACED1AFB9204008FA782 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
607FACEE1AFB9204008FA782 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
607FACF01AFB9204008FA782 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9096125064B44D5035341130 /* Pods-DAO_Example.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = DAO/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
607FACF11AFB9204008FA782 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6B14B1EA7DC79FC4DC1DE526 /* Pods-DAO_Example.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = DAO/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
AA10ECB21EEFE039001228A1 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8FB85F7F7AE5E16EDA09AF5A /* Pods-RealmDAOTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 42LRQS6X44;
INFOPLIST_FILE = RealmDAOTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.redmadrobot.RealmDAOTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OBJC_BRIDGING_HEADER = "RealmDAOTests/RealmDAOTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DAO_Example.app/DAO_Example";
};
name = Debug;
};
AA10ECB31EEFE039001228A1 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 048D2FC052C450E7600E2FA9 /* Pods-RealmDAOTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
DEVELOPMENT_TEAM = 42LRQS6X44;
INFOPLIST_FILE = RealmDAOTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.redmadrobot.RealmDAOTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "RealmDAOTests/RealmDAOTests-Bridging-Header.h";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DAO_Example.app/DAO_Example";
};
name = Release;
};
AA35258F1EEFDCE6009C4375 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B83929C10B53857ABAEBA293 /* Pods-CoreDataDAOTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 42LRQS6X44;
INFOPLIST_FILE = CoreDataDAOTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.redmadrobot.CoreDataDAOTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OBJC_BRIDGING_HEADER = "CoreDataDAOTests/CoreDataDAOTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DAO_Example.app/DAO_Example";
};
name = Debug;
};
AA3525901EEFDCE6009C4375 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 1DD31E834DFA3BE6198A94A4 /* Pods-CoreDataDAOTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
DEVELOPMENT_TEAM = 42LRQS6X44;
INFOPLIST_FILE = CoreDataDAOTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.redmadrobot.CoreDataDAOTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "CoreDataDAOTests/CoreDataDAOTests-Bridging-Header.h";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DAO_Example.app/DAO_Example";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "DAO" */ = {
isa = XCConfigurationList;
buildConfigurations = (
607FACED1AFB9204008FA782 /* Debug */,
607FACEE1AFB9204008FA782 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DAO_Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
607FACF01AFB9204008FA782 /* Debug */,
607FACF11AFB9204008FA782 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
AA10ECB11EEFE039001228A1 /* Build configuration list for PBXNativeTarget "RealmDAOTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
AA10ECB21EEFE039001228A1 /* Debug */,
AA10ECB31EEFE039001228A1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
AA35258E1EEFDCE6009C4375 /* Build configuration list for PBXNativeTarget "CoreDataDAOTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
AA35258F1EEFDCE6009C4375 /* Debug */,
AA3525901EEFDCE6009C4375 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCVersionGroup section */
AA3525801EEFDC24009C4375 /* Model.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
AA3525811EEFDC24009C4375 /* Model.xcdatamodel */,
);
currentVersion = AA3525811EEFDC24009C4375 /* Model.xcdatamodel */;
path = Model.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
};
rootObject = 607FACC81AFB9204008FA782 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:DAO.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
BuildableName = "DAO_Example.app"
BlueprintName = "DAO_Example"
ReferencedContainer = "container:DAO.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACE41AFB9204008FA782"
BuildableName = "DAO_Tests.xctest"
BlueprintName = "DAO_Tests"
ReferencedContainer = "container:DAO.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACE41AFB9204008FA782"
BuildableName = "DAO_Tests.xctest"
BlueprintName = "DAO_Tests"
ReferencedContainer = "container:DAO.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AA3525861EEFDCE6009C4375"
BuildableName = "CoreDataDAOTests.xctest"
BlueprintName = "CoreDataDAOTests"
ReferencedContainer = "container:DAO.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AA10ECA91EEFE039001228A1"
BuildableName = "RealmDAOTests.xctest"
BlueprintName = "RealmDAOTests"
ReferencedContainer = "container:DAO.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
BuildableName = "DAO_Example.app"
BlueprintName = "DAO_Example"
ReferencedContainer = "container:DAO.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
BuildableName = "DAO_Example.app"
BlueprintName = "DAO_Example"
ReferencedContainer = "container:DAO.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
BuildableName = "DAO_Example.app"
BlueprintName = "DAO_Example"
ReferencedContainer = "container:DAO.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:DAO.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,19 @@
//
// AppDelegate.swift
// DAO
//
// Created by Ivan Vavilov on 06/13/2017.
// Copyright (c) 2017 RedMadRobot. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
return true
}
}

View File

@ -0,0 +1,28 @@
//
// CDEntityTranslator.swift
// DAO
//
// Created by Ivan Vavilov on 2/9/16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import DAO
import CoreData
class CDEntityTranslator: CoreDataTranslator<CDEntity, Entity> {
override func fill(_ entity: Entity, fromEntry: CDEntity) {
entity.entityId = fromEntry.entryId
}
required init() {
}
override func fill(
_ entry: CDEntity,
fromEntity entity: Entity,
in context: NSManagedObjectContext) {
entry.entryId = entity.entityId
}
}

View File

@ -0,0 +1,43 @@
//
// CDFolderTranslator.swift
// DAO
//
// Created by Ivan Vavilov on 5/2/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import DAO
import CoreData
class CDFolderTranslator: CoreDataTranslator<CDFolder, Folder> {
required init() {}
override func fill(_ entity: Folder, fromEntry entry: CDFolder) {
entity.entityId = entry.entryId
entity.name = entry.name
CDMessageTranslator().fill(&entity.messages, fromEntries: entry.messages as? Set<CDMessage>)
}
override func fill(
_ entry: CDFolder,
fromEntity entity: Folder,
in context: NSManagedObjectContext) {
entry.entryId = entity.entityId
entry.name = entity.name
var messages = Set<CDMessage>()
CDMessageTranslator().fill(&messages, fromEntities: entity.messages, in: context)
if let m = entry.messages {
entry.removeFromMessages(m)
}
entry.addToMessages(messages as NSSet)
}
}

View File

@ -0,0 +1,32 @@
//
// CDMessageTranslator.swift
// DAO
//
// Created by Ivan Vavilov on 5/2/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import DAO
import CoreData
class CDMessageTranslator: CoreDataTranslator<CDMessage, Message> {
override func fill(_ entity: Message?, fromEntry entry: CDMessage) {
entity?.entityId = entry.entryId
entity?.text = entry.text
}
required init() {}
override func fill(
_ entry: CDMessage,
fromEntity entity: Message,
in context: NSManagedObjectContext) {
entry.entryId = entity.entityId
entry.text = entity.text
}
}

View File

@ -0,0 +1,50 @@
//
// RLMBookTranslator.swift
// DAO
//
// Created by Ivan Vavilov on 5/17/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import UIKit
import DAO
class RLMBookTranslator: RealmTranslator<Book, DBBook> {
required init() {}
override func fill(_ entity: Book, fromEntry: DBBook) {
entity.entityId = fromEntry.entryId
entity.name = fromEntry.name
entity.authors = fromEntry.authors.map { $0.value }
entity.dates = fromEntry.dates.map { $0.value }
entity.pages = fromEntry.pages.map { $0.value }
entity.attachments = fromEntry.attachments.map { $0.value }
}
override func fill(_ entry: DBBook, fromEntity: Book) {
if entry.entryId != fromEntity.entityId {
entry.entryId = fromEntity.entityId
}
entry.name = fromEntity.name
entry.authors.removeAll()
entry.dates.removeAll()
entry.pages.removeAll()
entry.attachments.removeAll()
let authors = fromEntity.authors.map { RLMString(val: $0) }
let dates = fromEntity.dates.map { RLMDate(val: $0) }
let pages = fromEntity.pages.map { RLMInteger(val: $0) }
let attachments = fromEntity.attachments.map { RLMData(val: $0) }
entry.authors.append(objectsIn: authors)
entry.dates.append(objectsIn: dates)
entry.pages.append(objectsIn: pages)
entry.attachments.append(objectsIn: attachments)
}
}

View File

@ -0,0 +1,30 @@
//
// RealmTranslator.swift
// DAO
//
// Created by Igor Bulyga on 05.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import DAO
class RLMEntityTranslator: RealmTranslator<Entity, DBEntity> {
required init() {
}
override func fill(_ entity: Entity, fromEntry: DBEntity) {
entity.entityId = fromEntry.entryId
}
override func fill(_ entry: DBEntity, fromEntity: Entity) {
if entry.entryId != fromEntity.entityId {
entry.entryId = fromEntity.entityId
}
}
}

View File

@ -0,0 +1,34 @@
//
// RLMFolderTranslator.swift
// DAO
//
// Created by Igor Bulyga on 09.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import DAO
import RealmSwift
class RLMFolderTranslator: RealmTranslator<Folder, DBFolder> {
required init() {}
override func fill(_ entity: Folder, fromEntry: DBFolder) {
entity.entityId = fromEntry.entryId
entity.name = fromEntry.name
RLMMessageTranslator().fill(&entity.messages, fromEntries: fromEntry.messages)
}
override func fill(_ entry: DBFolder, fromEntity: Folder) {
if entry.entryId != fromEntity.entityId {
entry.entryId = fromEntity.entityId
}
entry.name = fromEntity.name
RLMMessageTranslator().fill(entry.messages, fromEntities: fromEntity.messages)
}
}

View File

@ -0,0 +1,30 @@
//
// RLMMessageTranslator.swift
// DAO
//
// Created by Igor Bulyga on 09.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import DAO
class RLMMessageTranslator: RealmTranslator<Message, DBMessage> {
required init() {
}
override func fill(_ entity: Message, fromEntry: DBMessage) {
entity.entityId = fromEntry.entryId
entity.text = fromEntry.text
}
override func fill(_ entry: DBMessage, fromEntity: Message) {
if entry.entryId != fromEntity.entityId {
entry.entryId = fromEntity.entityId
}
entry.text = fromEntity.text
}
}

View File

@ -0,0 +1,47 @@
//
// Book.swift
// DAO
//
// Created by Ivan Vavilov on 5/17/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import UIKit
import DAO
class Book: Entity {
var name: String
var authors: [String]
var dates: [Date]
var pages: [Int]
var attachments: [Data]
init(entityId: String, name: String, authors: [String], dates: [Date], pages: [Int], attachments: [Data]) {
self.name = name
self.authors = authors
self.dates = dates
self.pages = pages
self.attachments = attachments
super.init(entityId: entityId)
}
required init() {
self.name = ""
self.authors = []
self.dates = []
self.pages = []
self.attachments = []
super.init()
}
}

View File

@ -0,0 +1,20 @@
//
// CDEntity+CoreDataProperties.swift
// DAO
//
// Created by Ivan Vavilov on 09/02/16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
// Choose "Create NSManagedObject Subclass" from the Core Data editor menu
// to delete and recreate this implementation file for your updated model.
//
import Foundation
import CoreData
extension CDEntity {
@NSManaged var entryId: String
}

View File

@ -0,0 +1,18 @@
//
// CDEntity.swift
// DAO
//
// Created by Ivan Vavilov on 09/02/16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import Foundation
import CoreData
@objc(CDEntity)
class CDEntity: NSManagedObject {
// Insert code here to add functionality to your managed object subclass
}

View File

@ -0,0 +1,40 @@
//
// CDFolder+CoreDataProperties.swift
// DAO
//
// Created by Ivan Vavilov on 5/2/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import Foundation
import CoreData
extension CDFolder {
@nonobjc
class func fetchRequest() -> NSFetchRequest<CDFolder> {
return NSFetchRequest<CDFolder>(entityName: "CDFolder")
}
@NSManaged var name: String
@NSManaged var messages: NSSet?
}
// MARK: Generated accessors for messages
extension CDFolder {
@objc(addMessagesObject:)
@NSManaged func addToMessages(_ value: CDMessage)
@objc(removeMessagesObject:)
@NSManaged func removeFromMessages(_ value: CDMessage)
@objc(addMessages:)
@NSManaged func addToMessages(_ values: NSSet)
@objc(removeMessages:)
@NSManaged func removeFromMessages(_ values: NSSet)
}

View File

@ -0,0 +1,15 @@
//
// CDFolder.swift
// DAO
//
// Created by Ivan Vavilov on 5/2/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import Foundation
import CoreData
@objc(CDFolder)
class CDFolder: CDEntity {
}

View File

@ -0,0 +1,22 @@
//
// CDMessage+CoreDataProperties.swift
// DAO
//
// Created by Ivan Vavilov on 5/2/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import Foundation
import CoreData
extension CDMessage {
@nonobjc
class func fetchRequest() -> NSFetchRequest<CDMessage> {
return NSFetchRequest<CDMessage>(entityName: "CDMessage")
}
@NSManaged var text: String?
}

View File

@ -0,0 +1,15 @@
//
// CDMessage.swift
// DAO
//
// Created by Ivan Vavilov on 5/2/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import Foundation
import CoreData
@objc(CDMessage)
class CDMessage: CDEntity {
}

View File

@ -0,0 +1,45 @@
//
// Folder.swift
// DAO
//
// Created by Igor Bulyga on 09.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import DAO
class Folder: Entity {
var name: String = ""
var messages = [Message]()
init(entityId: String, name: String, messages: [Message]) {
self.name = name
self.messages = messages
super.init(entityId: entityId)
}
required init() {
super.init()
}
override func equals<T>(_ other: T) -> Bool where T : Folder {
return (super.equals(other)) && self.name == other.name && self.messagesArrayEquals(other.messages)
}
fileprivate func messagesArrayEquals(_ otherMessages: [Message]) -> Bool {
if (self.messages.count != otherMessages.count) { return false }
for message in otherMessages {
if (!messages.contains(message)) { return false }
}
return true
}
}

View File

@ -0,0 +1,31 @@
//
// Message.swift
// DAO
//
// Created by Igor Bulyga on 05.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import DAO
class Message: Entity {
var text: String?
init(entityId: String, text: String?)
{
self.text = text
super.init(entityId: entityId)
}
required init()
{
super.init()
}
override func equals<T>(_ other: T) -> Bool where T: Message
{
return super.equals(other) && self.text == other.text
}
}

View File

@ -0,0 +1,34 @@
//
// DBBook.swift
// DAO
//
// Created by Ivan Vavilov on 5/17/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import DAO
import RealmSwift
final class DBBook: DBEntity, CascadeDeletionProtocol {
dynamic var name: String = ""
let authors = List<RLMString>()
let dates = List<RLMDate>()
let pages = List<RLMInteger>()
let attachments = List<RLMData>()
var objectsToDelete: [Object] {
let authors = Array(self.authors) as [Object]
let dates = Array(self.dates) as [Object]
let pages = Array(self.pages) as [Object]
let attachments = Array(self.attachments) as [Object]
return authors + dates + pages + attachments
}
}

View File

@ -0,0 +1,22 @@
//
// DBEntity.swift
// DAO
//
// Created by Igor Bulyga on 05.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import DAO
class DBEntity: RLMEntry {
class func entityWithId(_ entityId: String) -> DBEntity
{
let entity = DBEntity()
entity.entryId = entityId
return entity
}
}

View File

@ -0,0 +1,29 @@
//
// DBFolder.swift
// DAO
//
// Created by Igor Bulyga on 09.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import DAO
import RealmSwift
class DBFolder: DBEntity, CascadeDeletionProtocol {
dynamic var name: String = ""
var messages = List<DBMessage>()
class func folderWithId(_ entryId: String, name: String, messages: List<DBMessage>) -> DBFolder {
let folder = DBFolder()
folder.entryId = entryId
folder.name = name
folder.messages.append(objectsIn: messages)
return folder
}
var objectsToDelete: [Object] {
return Array(messages)
}
}

View File

@ -0,0 +1,21 @@
//
// DBMessage.swift
// DAO
//
// Created by Igor Bulyga on 09.02.16.
// Copyright © 2016 RedMadRobot LLC. All rights reserved.
//
import DAO
class DBMessage: DBEntity {
dynamic var text: String?
class func messageWithId(_ entityId: String, text: String?) -> DBMessage {
let message = DBMessage()
message.entryId = entityId
message.text = text
return message
}
}

35
Example/DAO/Info.plist Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16E195" minimumToolsVersion="Xcode 7.0" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="CDEntity" representedClassName="CDEntity" syncable="YES">
<attribute name="entryId" attributeType="String" defaultValueString="1" syncable="YES"/>
</entity>
<entity name="CDFolder" representedClassName="CDFolder" parentEntity="CDEntity" syncable="YES">
<attribute name="name" attributeType="String" defaultValueString=" " syncable="YES"/>
<relationship name="messages" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="CDMessage" syncable="YES"/>
</entity>
<entity name="CDMessage" representedClassName="CDMessage" parentEntity="CDEntity" syncable="YES">
<attribute name="text" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<elements>
<element name="CDEntity" positionX="-63" positionY="-18" width="128" height="60"/>
<element name="CDFolder" positionX="-54" positionY="0" width="128" height="75"/>
<element name="CDMessage" positionX="-63" positionY="-9" width="128" height="60"/>
</elements>
</model>

13
Example/Podfile Normal file
View File

@ -0,0 +1,13 @@
use_frameworks!
target 'DAO_Example' do
pod 'DAO', :path => '../'
target 'CoreDataDAOTests' do
inherit! :search_paths
end
target 'RealmDAOTests' do
inherit! :search_paths
end
end

28
Example/Podfile.lock Normal file
View File

@ -0,0 +1,28 @@
PODS:
- DAO (1.0.0):
- DAO/CoreData (= 1.0.0)
- DAO/Realm (= 1.0.0)
- DAO/CoreData (1.0.0)
- DAO/Realm (1.0.0):
- RealmSwift
- Realm (2.8.1):
- Realm/Headers (= 2.8.1)
- Realm/Headers (2.8.1)
- RealmSwift (2.8.1):
- Realm (= 2.8.1)
DEPENDENCIES:
- DAO (from `../`)
EXTERNAL SOURCES:
DAO:
:path: ../
SPEC CHECKSUMS:
DAO: 29f9c48e72c0a4ca6ed59a87718bb18978b682e0
Realm: 2627602ad6818451f0cb8c2a6e072f7f10a5f360
RealmSwift: 4764ca7657f2193c256fb032c0b123926f70dbcd
PODFILE CHECKSUM: 304d7b9f54070467c355fe795db431630f017f61
COCOAPODS: 1.2.1

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -0,0 +1,43 @@
//
// RealmDAOBookTests.swift
// DAO
//
// Created by Ivan Vavilov on 5/17/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import XCTest
import DAO
@testable import DAO_Example
class RealmDAOBookTests: XCTestCase {
let dao = RealmDAO(RLMBookTranslator())
func testPersist() {
let book = Book(entityId: "book1", name: "Swift", authors: ["Chris Lattner"],
dates: [Date(timeIntervalSince1970: 1000000)],
pages: [100, 200], attachments: [Data()])
do {
try dao.persist(book)
} catch {
XCTFail("Persist is failed")
}
if let savedBook = dao.read(book.entityId) {
XCTAssertEqual(book, savedBook)
XCTAssertFalse(savedBook.authors.isEmpty)
XCTAssertEqual(savedBook.authors.first, "Chris Lattner")
XCTAssertFalse(savedBook.dates.isEmpty)
XCTAssertFalse(savedBook.pages.isEmpty)
XCTAssertEqual(savedBook.pages.count, 2)
XCTAssertFalse(savedBook.attachments.isEmpty)
} else {
XCTFail("Persist is failed")
}
}
}

View File

@ -0,0 +1,156 @@
//
// RealmDAOEraseTests.swift
// DAO
//
// Created by Ivan Vavilov on 4/27/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import XCTest
import DAO
@testable import DAO_Example
final class RealmDAOEntityTests: XCTestCase {
let dao = RealmDAO(RLMEntityTranslator())
func testReadById() {
let entity = Entity(entityId: "2")
do {
try dao.persist(entity)
} catch {
XCTFail("Persist is failed")
}
if let savedEntity = dao.read("2") {
XCTAssertEqual(entity, savedEntity)
} else {
XCTFail("Read is failed")
}
}
func testAsyncReadById() {
let entity = Entity(entityId: "2_back")
let exp = expectation(description: "")
DispatchQueue.global().async {
do {
try self.dao.persist(entity)
} catch {
XCTFail("Async read by id is failed")
}
DispatchQueue.main.async {
if let savedEntity = self.dao.read("2_back") {
XCTAssertEqual(savedEntity.entityId, entity.entityId)
} else {
XCTFail("Async read by id is failed")
}
exp.fulfill()
}
}
waitForExpectations(timeout: 5) { error in
if error != nil {
XCTFail("Async read by id is failed")
}
XCTAssert(true)
}
}
func testPersist() {
let entity = Entity(entityId: "1")
do {
try dao.persist(entity)
} catch {
XCTFail("Saving entity is failed")
}
XCTAssert(true)
}
func testPersistAll() {
let firstEntity = Entity(entityId: "2")
let secondEntity = Entity(entityId: "3")
do {
try dao.persist([firstEntity, secondEntity])
} catch {
XCTFail("Saving entities is failed")
}
XCTAssert(true)
}
func testAsyncPersist() {
let exp = expectation(description: "")
DispatchQueue.global().async {
let entity = Entity(entityId: "1_back")
do {
try self.dao.persist(entity)
} catch {
XCTFail("Saving entity in background is failed")
}
exp.fulfill()
}
waitForExpectations(timeout: 5) { error in
if error != nil {
XCTFail("Saving entity in background is failed")
}
XCTAssert(true)
}
}
func testEraseById() {
let entity = Entity(entityId: "3")
do {
try dao.persist(entity)
try dao.erase("3")
} catch {
XCTFail("Erase is failed")
}
XCTAssertNil(dao.read("3"))
}
func testAsyncEraseById() {
let entity = Entity(entityId: "2_back")
do {
try dao.persist(entity)
} catch {
XCTFail("Async erase by id is failed")
}
let exp = expectation(description: "")
DispatchQueue.global().async {
do {
try self.dao.erase("2_back")
} catch {
XCTFail("Async erase by id is failed")
}
exp.fulfill()
}
waitForExpectations(timeout: 5) { error in
if error != nil {
XCTFail("Async erase by id is failed")
}
XCTAssert(true)
}
}
}

View File

@ -0,0 +1,45 @@
//
// RealmDAOFolderTests.swift
// DAO
//
// Created by Ivan Vavilov on 4/28/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import XCTest
import DAO
@testable import DAO_Example
final class RealmDAOFolderTests: XCTestCase {
let messageDAO = RealmDAO(RLMMessageTranslator())
let folderDAO = RealmDAO(RLMFolderTranslator())
func testCascadeErase() {
let message = Message(entityId: "V.message", text: "V.message.text")
let folder = Folder(entityId: "V", name: "Delete", messages: [message])
do {
try folderDAO.persist(folder)
} catch {
XCTFail("Persist folder is failed")
}
let savedMessage = messageDAO.read("V.message")
XCTAssertNotNil(savedMessage)
do {
try folderDAO.erase("V")
} catch {
XCTFail("Erase folder is failed")
}
XCTAssertNil(messageDAO.read("V.message"))
}
}

View File

@ -0,0 +1,56 @@
//
// RealmDAOMessagesTests.swift
// DAO
//
// Created by Ivan Vavilov on 4/28/17.
// Copyright © 2017 RedMadRobot LLC. All rights reserved.
//
import XCTest
import DAO
@testable import DAO_Example
final class RealmDAOMessagesTests: XCTestCase {
let dao = RealmDAO(RLMMessageTranslator())
func testPersistMessage() {
let message = Message(entityId: "abc", text: "text")
do {
try dao.persist(message)
} catch {
XCTFail("Persist is failed")
}
XCTAssertEqual(message, dao.read(message.entityId))
}
func testReadMessage() {
let message = Message(entityId: "def", text: "text 2")
do {
try dao.persist(message)
} catch {
XCTFail("Persist is failed")
}
XCTAssertEqual(message, dao.read("def"))
}
func testEraseMessage() {
let message = Message(entityId: "ghi", text: "text 2")
do {
try dao.persist(message)
try dao.erase("ghi")
} catch {
XCTFail("Persist or erase is failed")
}
XCTAssertNil(dao.read("ghi"))
}
}

View File

@ -0,0 +1,4 @@
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

19
LICENSE Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2017 RedMadRobot <iv@redmadrobot.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

66
README.md Normal file
View File

@ -0,0 +1,66 @@
CoreDAO
=======
An implementation of [DAO pattern](http://www.oracle.com/technetwork/java/dataaccessobject-138824.html) for CoreData and Realm.
Helps you think less about database in your application.
## Features
- Use your persistence layer synchronously for CRUD operations.
- Abstraction of database objects (entries) from application objects (entities).
- Abstraction from concurrency.
## Install
Cocoapods
For using with CoreData:
```ruby
pod 'CoreDAO/CoreData'
```
Or with Realm:
```ruby
pod 'CoreDAO/Realm'
```
## Usage
```swift
// Create DAO instance
let dao = RealmDAO(RLMMessageTranslator())
//...
// Create message entity
let message = Message(entityId: "abc", text: "text")
// Save message to database
try? dao.persist(message)
// Read saved message from database
let savedMessage = dao.read(message.entityId)
// Delete message from database
try? dao.erase(message.entityId)
```
Please look at the example project for more information.
## When not recommended to use
- If you have big and complex database schema. Many entities, many relationships.
- If you want to use many features of database. Realm Mobile Platform, for instance is not comaptible with this implementation.
- If you have thousands of objects (> 10-20K). Performance can be the issue.
## Requirements
- XCode 8
- Swift 3
- iOS 9
## Authors
Ivan Vavilov - iv@redmadrobot.com

1
_Pods.xcodeproj Symbolic link
View File

@ -0,0 +1 @@
Example/Pods/Pods.xcodeproj