Giter Club home page Giter Club logo

aerecord's Introduction

Swift 4.2 Platforms iOS | watchOS | tvOS | macOS CocoaPods Carthage Swift Package Manager License MIT

⚠️ Since this repository is going to be archived soon, I suggest migrating to NSPersistentContainer instead (available since iOS 10). For other convenience helpers, beside managing stack, I'm currently just using this.

AERecord

Super awesome Swift minion for Core Data (iOS, macOS, tvOS)

I made this for personal use, but feel free to use it or contribute. For more examples check out Sources and Tests.

Index

Intro

AECoreDataUI was previously part of AERecord, so you may want to check that also.

Why do we need yet another one Core Data wrapper? You tell me!
Inspired by many different (spoiler alert) magical solutions, I wanted something which combines complexity and functionality just about right. All that boilerplate code for setting up of Core Data stack, passing the right NSManagedObjectContext all accross the project and different threads, not to mention that boring NSFetchRequest boilerplates for any kind of creating or querying the data - should be more simple with this.

Features

  • Create default or custom Core Data stack (or more stacks) easily accessible from everywhere
  • Have main and background contexts, always in sync, but don't worry about it
  • CRUD data in many ways with generic one liners
  • iCloud support
  • Covered with unit tests
  • Covered with inline docs

Usage

You may see this demo project for example.

Create Core Data stack

Almost everything in AERecord is made with 'optional' parameters (which have default values if you don't specify anything).
So you can load (create if doesn't already exist) CoreData stack like this:

do {
    try AERecord.loadCoreDataStack()
} catch {
    print(error)
}

or like this:

let myModel: NSManagedObjectModel = AERecord.modelFromBundle(for: MyClass.self)
let myStoreType = NSInMemoryStoreType
let myConfiguration = ...
let myStoreURL = AERecord.storeURL(for: "MyName")
let myOptions = [NSMigratePersistentStoresAutomaticallyOption : true]
do {
    try AERecord.loadCoreDataStack(managedObjectModel: myModel, storeType: myStoreType, configuration: myConfiguration, storeURL: myStoreURL, options: myOptions)
} catch {
    print(error)
}

or any combination of these.

If for any reason you want to completely remove your stack and start over (separate demo data stack for example) you can do it as simple as this:

do {
    try AERecord.destroyCoreDataStack() // destroy default stack
} catch {
    print(error)
}

do {
    let demoStoreURL = AERecord.storeURL(for: "Demo")
    try AERecord.destroyCoreDataStack(storeURL: demoStoreURL) // destroy custom stack
} catch {
    print(error)
}

Similarly you can delete all data from all entities (without messing with the stack) like this:

AERecord.truncateAllData()

Context operations

Context for current thread (Context.default) is used if you don't specify any (all examples below are using Context.default).

// get context
AERecord.Context.main // get NSManagedObjectContext for main thread
AERecord.Context.background // get NSManagedObjectContext for background thread
AERecord.Context.default // get NSManagedObjectContext for current thread

// execute NSFetchRequest
let request = ...
let managedObjects = AERecord.execute(fetchRequest: request) // returns array of objects

// save context
AERecord.save() // save default context
AERecord.saveAndWait() // save default context and wait for save to finish

// turn managed objects into faults (you don't need this often, but sometimes you do)
let objectIDs = ...
AERecord.refreshObjects(with: [objectIDs], mergeChanges: true) // turn objects for given IDs into faults
AERecord.refreshRegisteredObjects(mergeChanges: true) // turn all registered objects into faults

Easy Queries

Easy querying helpers are created as NSManagedObject extension.
All queries are called on generic NSManagedObject, and Context.default is used if you don't specify any (all examples below are using Context.default). All finders have optional parameter for NSSortDescriptor which is not used in these examples. For even more examples check out unit tests.

General

If you need custom NSFetchRequest, you can use createPredicate(with:) and createFetchRequest(predicate:sortdDescriptors:), tweak it as you wish and execute with AERecord.

// create request for any entity type
let attributes = ...
let predicate = NSManagedObject.createPredicate(with: attributes)
let sortDescriptors = ...
let request = NSManagedObject.createFetchRequest(predicate: predicate, sortDescriptors: sortDescriptors)

// set some custom request properties
request.someProperty = someValue

// execute request and get array of entity objects
let managedObjects = AERecord.execute(fetchRequest: request)

Of course, all of the often needed requests for creating, finding, counting or deleting entities are already there, so just keep reading.

Create

NSManagedObject.create() // create new object

let attributes = ...
NSManagedObject.create(with: attributes) // create new object and sets it's attributes

NSManagedObject.firstOrCreate(with: "city", value: "Belgrade") // get existing object (or create new if it doesn't already exist) with given attribute

let attributes = ...
NSManagedObject.firstOrCreate(with: attributes) // get existing object (or create new if it doesn't already exist) with given attributes

Find first

NSManagedObject.first() // get first object

let predicate = ...
NSManagedObject.first(with: predicate) // get first object with predicate

NSManagedObject.first(with: "bike", value: "KTM") // get first object with given attribute name and value

let attributes = ...
NSManagedObject.first(with: attributes) // get first object with given attributes

NSManagedObject.first(orderedBy: "speed", ascending: false) // get first object ordered by given attribute name

Find all

NSManagedObject.all() // get all objects

let predicate = ...
NSManagedObject.all(with: predicate) // get all objects with predicate

NSManagedObject.all(with: "year", value: 1984) // get all objects with given attribute name and value

let attributes = ...
NSManagedObject.all(with: attributes) // get all objects with given attributes

Delete

let managedObject = ...
managedObject.delete() // delete object (call on instance)

NSManagedObject.deleteAll() // delete all objects

NSManagedObject.deleteAll(with: "fat", value: true) // delete all objects with given attribute name and value

let attributes = ...
NSManagedObject.deleteAll(with: attributes) // delete all objects with given attributes

let predicate = ...
NSManagedObject.deleteAll(with: predicate) // delete all objects with given predicate

Count

NSManagedObject.count() // count all objects

let predicate = ...
NSManagedObject.count(with: predicate) // count all objects with predicate

NSManagedObject.count(with: "selected", value: true) // count all objects with given attribute name and value

let attributes = ...
NSManagedObject.count(with: attributes) // count all objects with given attributes

Distinct

do {
    try NSManagedObject.distinctValues(for: "city") // get array of all distinct values for given attribute name
} catch {
    print(error)
}

do {
    let attributes = ["country", "city"]
    try NSManagedObject.distinctRecords(for: attributes) // get dictionary with name and values of all distinct records for multiple given attributes
} catch {
    print(error)
}

Auto Increment

If you need to have auto incremented attribute, just create one with Int type and get next ID like this:

NSManagedObject.autoIncrementedInteger(for: "myCustomAutoID") // returns next ID for given attribute of Integer type

Turn managed object into fault

NSFetchedResultsController is designed to watch only one entity at a time, but when there is a bit more complex UI (ex. showing data from related entities too), you sometimes have to manually refresh this related data, which can be done by turning 'watched' entity object into fault. This is shortcut for doing just that (mergeChanges parameter defaults to true). You can read more about turning objects into faults in Core Data documentation.

let managedObject = ...
managedObject.refresh() // turns instance of managed object into fault

Batch update

Batch updating is the 'new' feature from iOS 8. It's doing stuff directly in persistent store, so be carefull with this and read the docs first. Btw, NSPredicate is also optional parameter here.

NSManagedObject.batchUpdate(properties: ["timeStamp" : NSDate()]) // returns NSBatchUpdateResult?

NSManagedObject.objectsCountForBatchUpdate(properties: ["timeStamp" : NSDate()]) // returns count of updated objects

NSManagedObject.batchUpdateAndRefreshObjects(properties: ["timeStamp" : NSDate()]) // turns updated objects into faults after updating them in persistent store

Installation

License

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

aerecord's People

Contributors

ascarrambad avatar jakubknejzlik avatar lweek avatar maxkramer avatar screon avatar tadija avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aerecord's Issues

Download and Save Async Data in Multiple Threads

hey Marko,

i have an issue and i-m thinking that i doing something wrong with saving or creating/mapping CoreDataModels while getting data from a Webservice.
Situation:

  1. I download from a Webservice all users cardboxes and serialize the Json into an DTO Object and then map the DTO to the CoreData DBOCardBoxModel
  2. ForEach downloaded and mapped Cardbox download the Cards async
    2.1) When the Api Call is finished, serialize the Json into a DTO Object
    2.1.1) Then i want create a new CoreDataModel when the DTO.cardNbr not exists, else get first and map then the properties from the dto to dbo
    2.1.2) In the Mapper.Map(dto->dbo) i want to map all the properties and set relations, so in example a card can have multiple choice answers, so i want to create them and add this relation to the card

Exception throw at the firstOrCreateWithAttributes methode when my call was for example 25 times called, when it called 5 times the exception didnt throw.
I think it is because the NSManagementObjectContext is not on each thread, how can i handle this?

Here is some of my Code:
I using the following extensions:

Another question from me is where i place my the Save funktion? I¥m not shure about this.
1.) The Api Call that will call 25 Times: (the self.saveDB will call the saveAndWait(default) funktion)

public func ActiveCardBoxesById(dboCardBoxes : Array<String>){
        //let operationQueue = NSOperationQueue()
        //operationQueue.maxConcurrentOperationCount = dboCardBoxes.count
        for cardBox in dboCardBoxes {
            if self.CanSendRequest() {
                var request = self.CreateBaseRequest()
                request.requestSerializer.headers["clientid"] = self.UniqueId
                request.GET("/cardbox/\(cardBox)/cards", parameters: nil, success: {(response: HTTPResponse) -> Void in
                    if (response.responseObject != nil) {
                        //TODO
                        let dtoCards = Cards(JSONDecoder(response.responseObject!))
                        for dtoCard in dtoCards.cards! {
                            var dboCard = DBOCard.firstOrCreateWithAttribute("cardNbr", value: dtoCard.cardNbr!) as DBOCard
                            Mapper.Map(dtoCard, dbo: dboCard)
                        }

                        self.dataDelegate?.ConfirmLastSyncCardBox!()
                        self.logger.info("ConfirmLastSyncCardBox \(cardBox)")
                    }
                    }, failure: {(error: NSError, response: HTTPResponse?) -> Void in
                        self.logger.error("Getting ActiveCardboxesById throw error : \(error)")
                        self.baseDelegate?.ErrorInWebService(error)
                })


            }
            else {
                logger.warn("Can not communicate with API")
                self.baseDelegate?.ErrorSendingRequest()
            }
        }
        self.saveDB()

    }

2.) This is the Mapper.Map methode: (the self.saveDB will call the saveAndWait(default) funktion)

class func Map(dto : DTOCard, dbo : DBOCard) -> DBOCard {
        if let cardNbr = dto.cardNbr {
            dbo.setValue(cardNbr, forKey: "cardNbr")
        }
        if let cardBoxNbr = dto.cardBoxNbr {
            dbo.setValue(cardBoxNbr, forKey: "cardBoxNbr")
        }
        if let daystowait = dto.daystowait {
            dbo.setValue(daystowait, forKey: "daystowait")
        }
        if let delay = dto.delay {
            dbo.setValue(delay, forKey: "delay")
        }
        if let favorite = dto.favorite {
            dbo.setValue(favorite, forKey: "favorite")
        }
        if let knownInPlannedRow = dto.knownInPlannedRow {
            dbo.setValue(knownInPlannedRow, forKey: "knownInPlannedRow")
        }
        if let knownInRow = dto.knownInRow {
            dbo.setValue(knownInRow, forKey: "knownInRow")
        }
        if let lastPlannedPlayed = dto.lastPlannedPlayed {
            dbo.setValue(lastPlannedPlayed, forKey: "lastPlannedPlayed")
        }
        if let lastPlayed = dto.lastPlayed {
            dbo.setValue(lastPlayed, forKey: "lastPlayed")
        }
        if let multipleChoice = dto.multipleChoice {
            dbo.setValue(multipleChoice, forKey: "multipleChoice")
        }
        if let timesKnown = dto.timesKnown {
            dbo.setValue(timesKnown, forKey: "timesKnown")
        }
        if let timesNotKnown = dto.timesNotKnown {
            dbo.setValue(timesNotKnown, forKey: "timesNotKnown")
        }
        if let selectedForLearning = dto.selectedForLearning {
            dbo.setValue(selectedForLearning, forKey: "selectedForLearning")
        }
        if let delete = dto.delete {
            dbo.setValue(delete, forKey: "delete")
        }
        if let answer = dto.answer {
            dbo.setValue(answer, forKey: "answer")
        }
        if let answerImage = dto.answerImage {
            dbo.setValue(answerImage, forKey: "answerImage")
        }
        if let answerPureText = dto.answerPureText {
            dbo.setValue(answerPureText, forKey: "answerPureText")
        }
        if let question = dto.question {
            dbo.setValue(question, forKey: "question")
        }
        if let questionImage = dto.questionImage {
            dbo.setValue(questionImage, forKey: "questionImage")
        }
        if let questionPureText = dto.questionPureText {
            dbo.setValue(questionPureText, forKey: "questionPureText")
        }

        if let dtoMultipleChoices = dto.multipleChoiceCards {
            var counter = 1
            for dtoMultipleChoice in dtoMultipleChoices {
                var acessableOrderIndex = counter
                if let orderIndex = dtoMultipleChoice.orderIndex {
                    acessableOrderIndex = orderIndex
                }
                //TODO LOOK FIRST FOR CARDID AND ORDERINDEX
                let predicate = NSPredicate(format: "cardId = \(dtoMultipleChoice.cardId! + counter) AND orderIndex = \(acessableOrderIndex)")
                var mappedMultipleChoice : DBOMultipleChoice
                if let existingDboMultipleChoice = DBOMultipleChoice.firstWithPredicate(predicate!) as? DBOMultipleChoice {
                    mappedMultipleChoice = self.Map(dtoMultipleChoice, dbo: existingDboMultipleChoice)
                    mappedMultipleChoice.setValue(acessableOrderIndex, forKey: "orderIndex")
                }
                else {
                    var dboMultipleChoice = DBOMultipleChoice.firstOrCreateWithAttribute("cardId", value: dtoMultipleChoice.cardId! + counter) as DBOMultipleChoice
                    mappedMultipleChoice = self.Map(dtoMultipleChoice, dbo: dboMultipleChoice)
                    mappedMultipleChoice.setValue(acessableOrderIndex, forKey: "orderIndex")
                }

                dbo.addMultipleChoice(mappedMultipleChoice)
            }
            counter = 1
        }
        if let dtoCategories = dto.categories {
            for dtoCategory in dtoCategories {
                var dboCategory = DBOCategory.firstOrCreateWithAttribute("categoryId", value: dtoCategory.categoryId!) as DBOCategory
                var mappedCategory = self.Map(dtoCategory, dbo: dboCategory)
                mappedCategory.addCard(dbo)
                //add category to card
                dbo.addCategorie(mappedCategory)
                //add card to category

            }
        }
//        //get cardbox and add card
        if let dboCardBox = DBOCardBox.firstWithAttribute("cardBoxNbr", value: "\(dbo.cardBoxNbr)") as? DBOCardBox {
            //we have an cardbox
            dboCardBox.addCard(dbo)
            dbo.cardInCardBox = dboCardBox
        }
        self.save()
        return dbo
    }

Exceptions sometimes dangling with reference Dangling reference to an invalid object.=null, NSValidationErrorValue

Or
Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFSet: 0x7fc1aa487870> was mutated while being enumerated.'

XCode Version: 6.1

Update record

Hi,

is there any way to update an already stored record?

Thanks

? Ambiguous Use Errors

In AERecord on lines 442 and 457 under Swift 2.1 and xCode 7.1 (7B91b) - App Store version with OS X 10.11.1, I am getting "Ambiguous use of 'entityName' " and "Ambiguous use of 'create(context:)' " respectively. I am building for IOS 9.1.

I think what could be the issue is I'm trying to use the same dataModel for both the app and my tests, i.e., I have the app schema and it is included in both the app and the test targets. I was also hoping I could also include your AERecord tests and test model (as they are thorough and I knew I would be able to learn something from them.

I'm probably doing something incorrectly as I'm just getting started with your library.

There has been a little discussion one SO (http://stackoverflow.com/questions/24087011/ambiguous-use-of-propertyname-error-given-overridden-property-with-didset-ob) as this possibly being an error in xCode but I think it's been radar'ed and fixed.

Any ideas or help would be greatly appreciated and thanx in advance

How to do this in AERecord

Sum a property:

    func totalUnreadCount(whereParentChatId: String?) -> Int {
        let req = NSFetchRequest<NSDictionary>.init(entityName: Conversation.entityName())
        if let parentChatId = whereParentChatId {
            req.predicate = NSPredicate.init(format: "parentChatId=%@", parentChatId)
        } else {
            req.predicate = NSPredicate.init(format: "parentChatId = nil")
        }
        let expressDescription = NSExpressionDescription.init()
        let express = NSExpression.init(format: "@sum.unreadCount")
        expressDescription.expression = express
        expressDescription.name = "total"
        expressDescription.expressionResultType = .integer32AttributeType
        req.propertiesToFetch = [expressDescription]
        req.resultType = .dictionaryResultType
        var count = 0
        dbContext().performAndWait {
            let result = try? dbContext().fetch(req)
            if let total = result?.first?["total"] as? Int {
                count = total
            }
        }
        return count
    }

Improvement of NSManagedObject.firstOrCreate

I would like to give one suggestion regarding the firstOrCreate function.
while doing firstOrCreate keep one primary key so that you can check if that key already exists then only update the data related to that key instead of creating one more record.

to demonstrate suppose say I have an NSManagedObject called Person which keeps his id, balance, name, phone, email as String. So each time I call the update_person_record gives me an array of id, balance, name, phone, email.

So upon calling this
let value = ["id":id, "balance" : balance, "name": name, "phone": phone, "email": email]; _ = Person.firstOrCreate(with: value); AERecord.save();

It will create the same person with same details having a different balance. So please provide a primary key so that it will directly update values which have been updated.

EXC_BAD_INSTRUCTION DispatchQueue

If I want to create an NSManagedObject in a background thread than EXC_BAD_INSTRUCTION (code=EXC_i386_INVOP, subcode=0x0) arise.

@discardableResult class func create(in context: NSManagedObjectContext = AERecord.Context.default) -> Self {
let entityDescription = NSEntityDescription.entity(forEntityName: entityName, in: context)!
let object = self.init(entity: entityDescription, insertInto: context) // error line Line 104 in Query.swift
return object
}

Part of my code:
DispatchQueue.global(qos: .background).async{
let model = Model.create()
}

Do you know what's going wrong?
Thank you for your efforts

iCloud support

Hi,

In the readme it is mentioned that AERecord supports iCloud. Besides notification references in the code, I could not find how to set up CloudKit syncing.

Is there any documentation or references regarding iCloud sync?

Crash!

conversation.delete()

it crashed without any message

Question: mergePolicy

I've tried setting the mergePolicy by loading AERecord with the myOptions parameters, but the mergePolicy option or configuration is not read correctly.

Currently I'm using this code to set the mergePolicy, is this the best (or only) way to do this?

AERecord.Context.default.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy AERecord.Context.background.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy AERecord.Context.main.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

Full loading code:

`
let myOptions = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption : true]
do {
try AERecord.loadCoreDataStack(options: myOptions)
AERecord.Context.default.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
AERecord.Context.background.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
AERecord.Context.main.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

} catch {
debugPrint(error)
}
`

AutoUpdate Int Value

Hi,
I tried this out though when I create an NSManagedObject Subclass it automatically changed the integer 16 to NSNumber.

I tried running with the code (NSManagedObject.autoIncrementedIntegerAttribute("myCustomAutoID") though it didn't seem to do anything.
Just wondering what I might be doing wrong.

Thanks in advance for your help.

Carthage support

This is a sister issue to #5. While adding support for a package manager, consider supporting Carthage as well.

I love this project!

iCloud sync support missing...

Hi Tadija,

Could you add the persistentStoreCoordinator Notification to the AERecord to add the iCloud Sync support?

e.g. like this ->
func startReceivingContextNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "contextDidSave:", name: NSManagedObjectContextDidSaveNotification, object: mainContext)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "contextDidSave:", name: NSManagedObjectContextDidSaveNotification, object: backgroundContext)

    // ADDED ICLoud Support
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "storesWillChange:", name: NSPersistentStoreCoordinatorStoresWillChangeNotification, object: persistentStoreCoordinator)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "storesDidChange:", name: NSPersistentStoreCoordinatorStoresDidChangeNotification, object: persistentStoreCoordinator)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "persistentStoreDidImportUbiquitousContentChanges:", name: NSPersistentStoreDidImportUbiquitousContentChangesNotification, object: persistentStoreCoordinator)

}


// MARK: - iCloud Support
@objc func persistentStoreDidImportUbiquitousContentChanges(changeNotification: NSNotification) {

    if let context = changeNotification.object as? NSManagedObjectContext {
        let contextToRefresh = context == mainContext ? backgroundContext : mainContext
        contextToRefresh.performBlock({ () -> Void in
            contextToRefresh.mergeChangesFromContextDidSaveNotification(changeNotification)
        })
        contextToRefresh.reset()
    }

@objc func storesWillChange(notification: NSNotification) {

    let moc = defaultContext
    // TODO: async error throwing
    moc.performBlockAndWait { () -> Void in
        if moc.hasChanges {
            do {
                try moc.save()
            } catch {
                print(error)
            }
        }
        moc.reset()
    }

    // Refresh your User Interface.
    NSNotificationCenter.defaultCenter().postNotificationName("StoreWillChange", object: self)

}

@objc func storesDidChange(notification: NSNotification) {
    // Refresh your User Interface.
    NSNotificationCenter.defaultCenter().postNotificationName("StoreHasChanged", object: self)
}

How to initialise an object but not add it to the persistent store

I would like to initialise an object and populate it but not add it to the persistent store. I would like to have a user on a form, and add data to fields of a managedobject but only save it once the user presses the save button.

How do I go about doing it in AERecord?

destroyCoreDataStack() doesn't work in latest CoreData version

http://stackoverflow.com/questions/18277092/persistentstorecoordinator-sqlite-error-code522-not-an-error/20268379#20268379

My Code

  func destroyCoreDataStack(storeURL storeURL: NSURL = defaultURL) throws {
    // must load this core data stack first
    do {
      try loadCoreDataStack(storeURL: storeURL) // because there is no persistentStoreCoordinator if destroyCoreDataStack is called before loadCoreDataStack
      // also if we're in other stack currently that persistentStoreCoordinator doesn't know about this storeURL
    } catch {
      throw error
    }
    stopReceivingContextNotifications() // stop receiving notifications for these contexts

    // reset contexts
    mainContext.reset()
    backgroundContext.reset()

    // finally, remove persistent store
    if let coordinator = persistentStoreCoordinator {

        do {
            try coordinator.destroyPersistentStoreAtURL(storeURL, withType: NSSQLiteStoreType, options: nil)
        } catch {
            throw error
        }
    }

    // reset coordinator and model
    persistentStoreCoordinator = nil
    managedObjectModel = nil
  }

Could you give me some tips to the crash `*** Collection <__NSCFSet: 0x28355f810> was mutated while being enumerated.`

the code is:

    func conversation(whereChatId: String) -> Conversation? {
        guard AERecord.Context.default.persistentStoreCoordinator != nil else {
            return nil
        }
        let predicate = NSPredicate.init(format: "chatId=%@", whereChatId)
        let con = Conversation.first(with: predicate)
        return con
    }

the crash is:

*** Collection <__NSCFSet: 0x28355f810> was mutated while being enumerated.
ClouderWork + 8451948

I have got this error some times in my project using AERecord, would you please help me to fix it? I can't fix it by myself, I need your help!
Very thanks!

how to deal with relationships using AERecord? Any Demo?

Dear Tadija,
    I am from China, and I'm glad to several times google out that your AERecord project is the best CoreData wrapper framework in the world.
    And I have studied the demo project of AERecord. But I am unable to find any document or clue that AERecord project support the relationship features of CoreData.
    Could I introduce my project briefly to you and ask for your help on how to let AERecord support the relationship in my datamodel?
    I am trying to create a new app that could read out RSS texts by voice. my project address is at https://github.com/evering7/iSpeak7
    In my datamodel of this App, there are two entities: SourceRSS and ItemRSS. SourceRSS would map the RSS feed in the web, while ItemRSS would map one of the RSS full texts in the RSS feed. So, there are one to many realationship between SourceRSS and ItemRSS entity.
    In the design of my app, I would like to first generate the SourceRSS data by the urls of RSS feeds, and in this time there are no corresponding ItemRSS data in the CoreData Store. Later, after the SourceRSS data were loaded and ready, the App of mine would extract the info in my SourceRSS data and load detailed info of RSS texts into ItemRSS.
    So my first question is how I can use AERecord to save the SourceRSS data in my first time loading of SourceRSS without touching the relationship between SourceRSS and ItemRSS (in this time the ItemRSS's info is just null or empty).
    My second question is how I can use AERecord to auto establish the relationship between SourceRSS and ItemRSS after my App has extracted and analyzed info in SourceRSS data and is about to writing ItemRSS info into CoreData strore.
    I am very eager and hope to get the help of you guiding me on these above two questions because I can not find any clue on your demo project on these things of relationships.
    My third question is whether I can use part of AERecord to create the stack, saving features and use other method that is not part of AERecord to create a data relationships if we finally found that AERecord can't support the maintenace of CoreData relationships.
    Thank you and hoping that your reply coming to me soon.
    Best Regards
    

    Jianfei
    @FoxLi99
    
    Putian, China
    My Email: evering7 AT 139 DOT com

I'm getting this error on latest version of AERecord

I did a pod update and i started facing this error. This problem is on 3.0.0 on 2.1.0 it works fine

 private class func _firstOrCreateWithAttributes<T>(attributes: [String : AnyObject], predicateType: NSCompoundPredicateType = defaultPredicateType, context: NSManagedObjectContext = AERecord.defaultContext) -> T {
        let predicate = createPredicateForAttributes(attributes, predicateType: predicateType)
        let request = createFetchRequest(predicate: predicate)
        request.fetchLimit = 1
        let objects = AERecord.executeFetchRequest(request, context: context)

        return (objects.first ?? createWithAttributes(attributes, context: context)) as! T //Here i get the error
    }

ERROR

Could not cast value of type 'NSManagedObject_AccountDetails_' (0x7fd43ae881b0) to 'FeedbackChamp.AccountDetails' (0x1081b1220).

MY CODE

AccountDetails.firstOrCreateWithAttributes(["data" : readableJSON["result"]["hoteladded"].bool! ? 1 : 0, "detailName": "num_hotels"])

AccountDetails.firstOrCreateWithAttributes(["data" : readableJSON["result"]["num_restaurants"].int!, "detailName": "num_restaurants"])

AERecord.saveContextAndWait()

Please fix it as soon as posible

Swift 1.2 Support

Hi,

is there any chance of this (and AEXML) getting updated to Swift 1.2?
All the other frameworks i am using already have a 1.2 branch. If there is no plan to do this i would it myself but otherwise it would be a waste of time :).

Swift 2.0 support

Thanks for creating and sharing this library with the world, it's proving quite helpful.

What plans (if any) do you have for supporting Swift 2.0?

Thanks.

Swift 3

Did you think about upgrading to Swift 3? If yes, when? Thank you.

I guess, Stack class name conflicting in my Project with some other framework

Also another issue:
/Users/.../Pods/AERecord/Sources/AERecord.swift:69:82: Class 'Stack' is internal and cannot be referenced from a default argument value (multiple time this issue for different methods/properties)
/Users/.../Pods/AERecord/Sources/Query.swift:581:71: Static let 'defaultPredicateType' is private and cannot be referenced from a default argument value (multiple time this issue for different methods/properties)

I tested your classes in your test project AECoreDataDemo, and its working fine. Suggest me what I do?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.