Does anyone know, or have an example of, how to handle core data transient values with Swift? I know to use #NSManaged before the properties, but can't figure out how to code the logic to build the transient values using Swift.
Check mark the transient field in your data model for particular attribute(e.g. sectionTitle).
Create class for that entity, it will look something like
class Message: NSManagedObject {
#NSManaged var body: String?
#NSManaged var time: NSDate?
#NSManaged var sectionTitle: String?
}
Edit it and make it like this:
class Message: NSManagedObject {
#NSManaged var body: String?
#NSManaged var time: NSDate?
var sectionTitle: String? {
return time!.getTimeStrWithDayPrecision()
//'getTimeStrWithDayPrecision' will convert timestamp to day
//just for e.g.
//you can do anything here as computational properties
}
}
Update- Swift4
Use #objc tag for Swift 4 as:
#objc var sectionTitle: String? {
return time!.getTimeStrWithDayPrecision()
}
We should use willAccessValueForKey and didAccessValueForKey to support KVO
Related
I'm using Parse and I had a PFObject I was using to represent a "Job". It worked fined, but it was tedious always using setObject:forKey: and objectForKey: rather than accessing properties.
So, I decided to make a "proper" PFObject subclass. Now, every call made to "objectId" gives the above unrecognized selector error -- even calls that have nothing to do with my subclass.
I created my subclass "by the book", as far as I can tell (below), and I do call Job.registerSubclass() before Parse.setApplicationId: in my AppDelegate. Anybody seen this problem?
import Foundation
import Parse
class Job: PFObject, PFSubclassing {
#NSManaged var categoryName: String
#NSManaged var categoryId: String
#NSManaged var state: String
#NSManaged var details: String?
#NSManaged var jobDescription: String
#NSManaged var location: String
#NSManaged var dates: [String]
#NSManaged var images: PFFile?
#NSManaged var questionSequence: [String]?
#NSManaged var consumerResponseIndices: [Int]?
#NSManaged var isPosted: Bool
#NSManaged var bids: [AnyObject]?
override class func initialize() {
struct Static {
static var onceToken : dispatch_once_t = 0;
}
dispatch_once(&Static.onceToken) {
self.registerSubclass()
}
}
class func parseClassName() -> String {
return "Job"
}
}
I got the same issue before.
You may have this error when trying to convert NSArray/NSDictionary to String type, so it turns to NSContiguousString type.
You can check:
dates
questionSequence
consumerResponseIndices
bids
to see if this happened.
In my case the problem was :
if let countryLocale = (notification.userInfo![Constants.CountryLocale]!.firstObject as? String { code }
and solved with
if let countryLocale = (notification.userInfo![Constants.CountryLocale] as! [AnyObject]).first as? String { code }
I am fetching objects from Core Data with Swift and instead of having a "Themes" object I get NSManagedOBject
Class Enity:
Class: Themes.swift
import Foundation
import CoreData
#objc(Themes)
class Themes: NSManagedObject {
}
class: Themes+CoreDataProperties.swift
import Foundation
import CoreData
extension Themes {
#NSManaged var themeName: String?
#NSManaged var topBarColors: NSData?
#NSManaged var bottomBarColors: NSData?
#NSManaged var bottomBarIconsColor_default: NSData?
#NSManaged var bottomBarIconsColor_selected: NSData?
#NSManaged var background_image: NSData?
#NSManaged var isBackgroundBlured: NSNumber?
#NSManaged var font_phoneTitle: NSData?
#NSManaged var font_name: NSData?
#NSManaged var font_phoneNumber: NSData?
#NSManaged var font_barButtons: NSData?
#NSManaged var font_organization: NSData?
#NSManaged var font_initiala: NSData?
#NSManaged var isPredefined: NSNumber?
#NSManaged var isRandomInitialBackgroundColor: NSNumber?
///0 gratis, 1 cu bani etc
#NSManaged var priceTier: NSNumber?
}
Fetching:
func fetchThemes() {
let moc = AppDelegate().managedObjectContext
let personFetch = NSFetchRequest(entityName: "Themes")
do {
let fetchedPerson = try moc.executeFetchRequest(personFetch) as! [Themes]
print("fetched: \(fetchedPerson)")
arr_themes = fetchedPerson
} catch {
fatalError("Failed to fetch person: \(error)")
}
}
And I get this and crash:
Any idea what the problem might be?
Themes is an NSManagedObject subclass. It's not clear why you are using setters and getters in this way, You don't need to do that at all. The NSManagedObject will never be assigned as a color in any case. You might want to have a look at the following SO Answer. You can also search for related questions on the right-hand side of that answer so that you can get a good idea of how to store, retrieve the UIColor on Core Data. Google will produce detailed code for using UIColor with Core Data.
The gist of this is:
Create an attribute to store the color and mark as Transformable
Generate the NSManagedObject subclass for the Themes object
Change the generated type from NSObject? to UIColor?
Add import UIKit to top of the Themes subclass file
Once you have the class created correctly you can do the following in your code (and Core Data will managed UIColor storage automatically).
//Themes class after regeneration when you set the attribute to Transformable in the Core Data Model Editor and regenerate
#NSManaged var backgroundColor: NSObject?
//after you update to support adding a UIColor
import UIKit
//...
#NSManaged var backgroundColor: UIColor?
//create your new Themes object
var colorObject:Themes = //...
//Set the backgroundColor attribute
colorObject.backgroundColor = UIColor().redColor()
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 am currently using Swift and Parse and have run into an issue which I haven't been able resolve for the past several hours.
On a button click, I am attempting to add an Employee object to an Event object's eventAttendee's array.
#IBAction func joinEvent(sender: AnyObject) {
var employee = Employee.currentUser()
employee.events.append(event)
employee.saveInBackgroundWithBlock(nil)
event.eventAttendees.append(employee)
event.saveInBackgroundWithBlock(nil)
}
The event is added to the employee events, but the employee is not added to the event attendees list. The function throws a EXC_BAD_ACCESS (code=1, address=0x0) on the append(employee) line, with no other error message.
My event class looks like this:
class VolunteerEvent : PFObject, PFSubclassing {
#NSManaged var eventName: String
#NSManaged var dateOfEvent: NSDate
#NSManaged var eventDescription: String
#NSManaged var eventURL: String?
#NSManaged var eventImage: PFFile
#NSManaged var contactEmail: String
#NSManaged var contactPhone: NSNumber
#NSManaged var eventOrganizer: Employee
#NSManaged var eventAttendees: [Employee]
class func parseClassName() -> String {
return "VolunteerEvent"
}
}
My Employee class extends PFUser, although when I print out the description of my employee I get that it is a PFUser. I can't tell if this is the issue. When I print out the event, it looks like I expect it to look. I also tried switching the eventAttendees to be an array of PFUser's instead of Employee's, but that didn't work either.
Any help would be much appreciated. Thank you.
I subclass my PFObjects this way,
class Person : PFObject, PFSubclassing {
var firstName: String {
get {
return objectForKey("firstName") as? String ?? ""
}
set {
setObject(newValue, forKey: "firstName")
}
}
}
This way if there is no string in the parse database, I don't get nil, i get an empty string.
You can do this with your array, in fact all your object properties.
If nothing is returned, then you will get an empty array of Employee, rather than a nil object - which will cause your crash when you try an append to it.
You need to initialize your array before adding to it. Try var eventAttendees: [Employee] = []
I have one to many relationship in my coredata model. For each News object I have many details object.
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: NSOrderedSet
}
class JobDetail: NSManagedObject {
#NSManaged var message: String
#NSManaged var date: NSDate
#NSManaged var location: String
#NSManaged var status: NSNumber
#NSManaged var parent: Job
}
So, how can I remove all details from Job? My current approach is to delete Job itself and create it again which is slower.
I have tried to delete with,
context?.deletedObjects(myJob.detail)
but it didn’t work. It says
'(#lvalue NSOrderedSet) -> _' is not identical to 'Set'
It seems that you mixed-up deleteObject() with deletedObjects().
deletedObjects() is a method to get a list of all managed objects which
have been marked for deletion in the managed object context. What you have to call is deleteObject()
for each object. Something like (not compiler-checked):
for detail in myJob.details {
context.deleteObject(detail)
}