Currently I have a subclass of NSManaged object called Folder with property called item that is of type NSSet.
class Folder: NSManagedObject {
#NSManaged var title: String
#NSManaged var date: NSDate
#NSManaged var item: NSSet
func itemMutableArray() -> NSMutableArray {
var mutableArray: NSMutableArray!
mutableArray = [item.allObjects]
return mutableArray
}
Item class:
class Item: NSManagedObject {
#NSManaged var title: String
#NSManaged var date: NSDate
#NSManaged var completed: Bool
Does anybody have any suggestions with where I am currently going wrong ?
Here is my previous function I was using which now I want to convert my NSSet to an NSMutableArray.
func itemArray() -> [Item] {
let sortDescriptor = NSSortDescriptor(key: "date", ascending: true)
return item.sortedArrayUsingDescriptors([sortDescriptor]) as! [Item]
}
func itemMutableArray() -> NSMutableArray {
return NSMutableArray(array: (item.allObjects as! [Item]).sorted{ $0.date.compare($1.date) == NSComparisonResult.OrderedAscending } )
}
use Swift types, they are much more versatile
This puts the NSSet into an Array (var is mutable) and sorts it ascending by property date
#NSManaged var title: String
#NSManaged var date: NSDate
#NSManaged var item: NSSet
var sortedItemArray : Array<Item> {
var array = item.allObjects as! [Item]
return sorted(array) {$0.date < $1.date }
}
Related
I'm working with web app. I have UITableViewController which deals with NSFetchedResultsController. I store tableView's objects through CoreData. When a user refreshes UI I perform server request and then call batch update for each new entity, my CoreData class looks like:
extension DBOrder {
#NSManaged var comment: String
#NSManaged var date: NSNumber
#NSManaged var id: NSNumber
#NSManaged var maturity_date: NSNumber
#NSManaged var number_of_tasks: NSNumber
#NSManaged var price: NSNumber
#NSManaged var status: String
#NSManaged var subject: String
#NSManaged var taskImages: [String]
#NSManaged var theme: String
}
"id" is unique for each object. "propertiesToUpdate" consists of some fields like "maturity_date": 1470427641000, "status": "some status" and etc. "entityName" is "DBOrder". And privateContext is NSManagedObjectContext type to update entities in background
func updateCoreData(id: NSNumber, entityName: String, propertiesToUpdate: [String: AnyObject], privateContext: NSManagedObjectContext) -> Bool {
let batchRequest = NSBatchUpdateRequest(entityName: entityName)
batchRequest.predicate = NSPredicate(format: "id == %#", id)
if !doesOrderExists(entityName, id: id, context: privateContext) {
return false
}
batchRequest.propertiesToUpdate = propertiesToUpdate
batchRequest.resultType = .UpdatedObjectIDsResultType
do {
let res = try privateContext.executeRequest(batchRequest) as! NSBatchUpdateResult
let orderIDs = res.result as! [NSManagedObjectID]
return (orderIDs.count != 0) ? true : false
} catch {
print(error)
}
return false
}
This function is called for each object that has been loaded from server. If object is already existed then I update it else create the new one.
Finally, the problem: when I use batch update it works incorrect with NSNumber. It always puts NSNumber fields to nil and works as it should with String fields. So, what I'm doing wrong?
I have two NSManagedObject classes "Person" and "Animal". Both classes have a "name" property. How can I sort them alphabetically into a single array?
class Person: NSManagedObject {
#NSManaged var name:String?
#NSManaged var occupation:String?
}
class Animal: NSManagedObject {
#NSManaged var name:String?
#NSManaged var breed:String?
}
//This array is filled with both people and animal objects from my database
var peopleAndAnimals = [NSManagedObject]()
peopleAndAnimals.sort(//I want to sort alphabetically by name here)
Try this:
peopleAndAnimals.sortInPlace {
if let name1 = $0.valueForKey("name") as? String,
name2 = $1.valueForKey("name") as? String {
return name1 < name2
} else {
return false
}
}
I would look into using NSSortDescriptor, that's how I usually alphabetize arrays. Here's the NSHipster page for it http://nshipster.com/nssortdescriptor/.
In my calendarViewController I'd like to prepare an array containing dates. In my model i have to-may relationship where one medicine can have multiple dates of taking pill. How can i perform a loop through this set to append an array ?
My models:
extension Medicine {
#NSManaged var amount: String?
#NSManaged var endDate: String?
#NSManaged var name: String?
#NSManaged var time: String?
#NSManaged var notificationSet: NSNumber?
#NSManaged var taken: NSOrderedSet?
}
Model Dates
extension Dates {
#NSManaged var date: NSDate?
#NSManaged var takes: Medicine?
}
I'd like to perform loop like this ,but instead these dates i'd like those from CoreData:
var dates = [NSDate(timeIntervalSinceNow: 60*60*24*2), NSDate(timeIntervalSinceNow: 60*60*24*3), NSDate(timeIntervalSinceNow: 60*60*24*5), NSDate(timeIntervalSinceNow: 60*60*24*7)]
func calendar(calendar: CKCalendarView!, configureDateItem dateItem: CKDateItem!, forDate date: NSDate!) {
for dateTaken in dates {
if calendar.date(date, isSameDayAsDate: dateTaken) {
dateItem.backgroundColor = UIColor.redColor()
}
}
}
Fetch your Medicine entity and then create the array like this:
let dates = medicine.taken.map { $0.date }
Not sure about the NSOrderedSet which tends to be buggy so I generally avoid it, but you can try appending as! [NSDate] to make sure you have an proper array of dates.
I have the classes Tema, Oppgave and Fag. One Fag has many Oppgaves and one Tema has many Oppgaves. However, every Oppgave in a Tema has the same Fag.
I want to display only the Temas where its Oppgaves has a certain Fag.
These are my relevant models:
class Oppgave: NSManagedObject {
#NSManaged var isArchived: NSNumber
#NSManaged var isComplete: NSNumber
#NSManaged var lflink: String
#NSManaged var link: String
#NSManaged var nokkel: String
#NSManaged var oppgaveNr: NSNumber
#NSManaged var sett: Sett
#NSManaged var tema: Tema
#NSManaged var fag: Fag
}
class Tema: NSManagedObject {
#NSManaged var title: String
#NSManaged var oppgave: NSSet
}
class Fag: NSManagedObject {
#NSManaged var title: String
#NSManaged var fagKode: String
#NSManaged var isUnlocked: NSNumber
#NSManaged var oppgave: NSSet
}
This is my fetchrequest:
//This variable gets a value from a prepareForSegue function earlier
var fag:Fag!
var temaer:[Tema] = []
var fetchResultController:NSFetchedResultsController!
override func viewDidLoad() {
super.viewDidLoad()
println("Oppgaver fetches fra databasen")
var fetchRequest = NSFetchRequest(entityName: "Tema")
let sortDescriptor = NSSortDescriptor(key: "title", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
//This is the line thats giving me the error
fetchRequest.predicate = NSPredicate(format: "oppgave.allObjects.first?.fag.fagKode == %#", fag.fagKode)
if let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext{
fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
fetchResultController.delegate = self
var e:NSError?
var result = fetchResultController.performFetch(&e)
temaer = fetchResultController.fetchedObjects as! [Tema]
if result != true{
println(e?.localizedDescription)
}
}
}
How can i get rid of the errors and retrieve the objects i want to?
Since all Oppgave for the same Tema have the same Fag, your requirement, "the Temas where its Oppgaves has a certain Fag", is equivalent to "the Temas where ANY of its Oppgaves has a certain Fag", for which the predicate is:
fetchRequest.predicate = NSPredicate(format: "ANY oppgave.fag == %#", fag)
I am trying to use Core Data to save some of my application data. I have following classes. Basically I want to store the properties of each job, and use it later on.
Following is the class I currently use in my application.
class Job {
var name:String?
var count = 1
var id:String
var startDate:NSDate?
var finishDate:NSDate?
var expected:NSDate?
var detail:Array<JobDetail> = []
var isFinished:Bool?
var sender:String?
var receiver:String?
init(name:String?, id:String) {
self.name = name
self.id = id
self.isFinished = false
self.startDate = NSDate()
}
func addDetail (message:String?, date:NSDate?, location:String?, status: DetailStatus) {
detail.append(JobDetail(message: message, date: date, location: location, status: status))
if status == DetailStatus.OK {
self.isFinished = true
self.finishDate = date
}
}
}
enum DetailStatus {
case OK
case Error
case Exception
case Unknown
}
class JobDetail {
var message:String?
var date:NSDate?
var location:String?
var status:DetailStatus
init(message:String?, date:NSDate?, location:String?, status: DetailStatus) {
self.message = message
self.date = date
self.location = location
self.status = status
}
}
NSManagedObject sub class I created with Xcode after I create the data model.
class Job: NSManagedObject {
#NSManaged var name: String
#NSManaged var count: NSNumber
#NSManaged var id: String
#NSManaged var startDate: NSDate
#NSManaged var finishDate: NSDate
#NSManaged var expected: NSDate
#NSManaged var isFinished: NSNumber
#NSManaged var sender: String
#NSManaged var receiver: String
#NSManaged var details: NSSet
}
class JobDetail: NSManagedObject {
#NSManaged var message: String
#NSManaged var date: NSDate
#NSManaged var location: String
#NSManaged var status: NSNumber
#NSManaged var parent: Job
}
Here are the screenshots of my data model.
Basically I want to CRUD Job in my application so that I can show them in my tableview. I have everything setup, but because I couldn’t setup Core Data I don’t have persistence. I will appreciate if you can help me to setup Core Data.
Refer this. May be it's useful to you...
http://www.raywenderlich.com/85578/first-core-data-app-using-swift
It seems from the screenshots that your setup is correct. Link details with jobs like this.
detail1.parent = job
detail2.parent = job
context.save(nil)
Get all details for a job like this
job.details
This is unordered, but you can sort them using sortedArrayUsingDescriptors.
let sortedDetails = job.details.sortedArrayUsingDescriptors(
[NSSortDescriptor(key:"date" ascending: false)])