I wanted to create custom PFObject class, but it gives me a very confusing error "Property self.photo not initialized at super.init call"
here is code of my custom class :
import Foundation
import Parse
class Wish: PFObject, PFSubclassing {
var id: String?
var name: String?
var descriptionWish: String?
var photo: UIImage
var photoThumbnail: UIImage
var amount: Double?
var amountDonated: Int?
static func parseClassName() -> String {
return "Wish"
}
override init() {
super.init()
}
convenience init(id: String?, name: String?, descriptionWish: String?, photo: UIImage, photoThumbnail: UIImage, amount: Double?, amountDonated: Int?) {
self.init()
self.id = id
self.name = name
self.descriptionWish = descriptionWish
self.photo = photo
self.photoThumbnail = photoThumbnail
self.amount = amount
self.amountDonated = amountDonated
}
}
Any ideas how to make a custom initializer for this class ?
I want to call my wish class like this:
Wish(id: "123", name: "xxx", descriptionWish: "Lorem ipsum", photo: photoImage, photoThumbnail: photoImageThumbnail, amount: 22.20, amountDonated: 10)
and cast PFObject like this
let wish = myPfObject as Wish
Any help is appreciated!!!
Try updating your subclass to the following. Notice the NSManaged keywords for the Parse properties you've added to your Wish subclass and the removal of super.init()
You will probably also want to look into replacing the UIImage properties with the Parse-provided PFFile properties. You can easily store and load images using PFImageView included in the ParseUI framework.
import Foundation
import Parse
class Wish: PFObject, PFSubclassing {
// MARK: - Parse Core Wish Properties
#NSManaged var id: String?
#NSManaged var name: String?
#NSManaged var descriptionWish: String?
#NSManaged var photo: UIImage
#NSManaged var photoThumbnail: UIImage
#NSManaged var amount: Double?
#NSManaged var amountDonated: Int?
// MARK: - Lifecycle
override class func initialize() {
struct Static {
static var onceToken : dispatch_once_t = 0;
}
dispatch_once(&Static.onceToken) {
self.registerSubclass()
}
}
static func parseClassName() -> String {
return "Wish"
}
convenience init(id: String?, name: String?, descriptionWish: String?, photo: UIImage, photoThumbnail: UIImage, amount: Double?, amountDonated: Int?) {
self.init()
self.id = id
self.name = name
self.descriptionWish = descriptionWish
self.photo = photo
self.photoThumbnail = photoThumbnail
self.amount = amount
self.amountDonated = amountDonated
}
}
Related
I have the following class
// LearningItem
class LearningItem : NSObject {
var id: String
var title: String
var subtitle: String?
var image: String
var uploadDate: Int
init(id: String, title: String, image: String, uploadDate: Int) {
self.id = id
self.title = title
self.image = image
self.uploadDate = uploadDate
}
I have another class
// Book.swift
class Book: LearningItem {
var publishDate: String?
var author: String?
var mediaUrl: String?
var video : String?
var tags: [String]?
var lists: [String: AnyObject]?
var readCount: Int
var categories: [String]?
var courses: [String]?
var amazonBuyUrl: String?
var starCount: Int
var read: Bool?
var completed = [String : Int]()
var stars = [String : Int]()
var completedDate : Int?
var desc: String
var epub: String
var authorDesc: String
init(id: String, title: String, desc: String, authorDesc: String, image: String, epub: String, readCount: Int, uploadDate: Int, starCount: Int) {
super.init(id: id, title: title, image: image, uploadDate: uploadDate)
self.id = id
self.desc = desc
self.authorDesc = authorDesc
self.title = title
self.epub = epub
self.image = image
self.readCount = readCount
self.uploadDate = uploadDate
self.starCount = starCount
}
I get the error "Property 'self.readCount' not initialized at super.init call"
where I call "super.init(id: id, title: title, image: image, uploadDate: uploadDate)" in Book.swift
Class initialisation not finished until it's designated initializers
not finished with initializing all properties
and after that you can call super class's designated initializers
Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.
SO
Class initialization in Swift is a two-phase process. In the first phase, each stored property is assigned an initial value by the class that introduced it. Once the initial state for every stored property has been determined, the second phase begins, and each class is given the opportunity to customize its stored properties further before the new instance is considered ready for use.
apple docs https://docs.swift.org/swift-book/LanguageGuide/Initialization.html
so
class Book: LearningItem {
var publishDate: String?
var author: String?
var mediaUrl: String?
var video : String?
var tags: [String]?
var lists: [String: AnyObject]?
var readCount: Int
var categories: [String]?
var courses: [String]?
var amazonBuyUrl: String?
var starCount: Int
var read: Bool?
var completed = [String : Int]()
var stars = [String : Int]()
var completedDate : Int?
var desc: String
var epub: String
var authorDesc: String
init(id: String, title: String, desc: String, authorDesc: String, image: String, epub: String, readCount: Int, uploadDate: Int, starCount: Int) {
self.readCount = readCount
self.starCount = starCount
self.desc = desc
self.epub = epub
self.authorDesc = authorDesc
super.init(id: id, title: title, image: image, uploadDate: uploadDate)
}
}
I just inherited this app and I am trying to add a few fields to a form.
I am receiving this error - it seems to be calling a setPrice method on MedicalDevice.
Now as far as I can tell, I've added price to the class that is expecting it...
#objc(MedicalDevice)
public class MedicalDevice: NSManagedObject {
static let entityName = "MedicalDevice"
#nonobjc public class func fetchRequest() -> NSFetchRequest<MedicalDevice> {
return NSFetchRequest<MedicalDevice>(entityName: MedicalDevice.entityName)
}
convenience init(context moc: NSManagedObjectContext) {
self.init(entity: NSEntityDescription.entity(forEntityName: MedicalDevice.entityName, in: moc)!, insertInto: moc)
}
#NSManaged public var createdAt: Date?
#NSManaged public var deviceID: String?
#NSManaged public var expirationDate: Date?
#NSManaged public var lotNumber: String?
#NSManaged public var modelNumber: String?
#NSManaged public var catalogNumber: String?
#NSManaged public var deviceDescription: String?
#NSManaged public var brandName: String?
#NSManaged public var companyName: String?
#NSManaged public var quantity: String?
#NSManaged public var price: String?
#NSManaged public var location: String?
#NSManaged public var facilityID: String?
}
And addDevice works as such - this is where the exception is being thrown:
func addDevice(for deviceID: String, lotNumber: String, expirationDate: Date, modelNumber: String, catalogNumber: String, description: String, quantity: String, brandName: String, companyName: String, price: String, location: String, facilityID: String) {
let medicalDevice = MedicalDevice(context: self.persistentContainer.viewContext)
medicalDevice.createdAt = Date()
medicalDevice.deviceID = deviceID
medicalDevice.lotNumber = lotNumber
medicalDevice.expirationDate = expirationDate
medicalDevice.modelNumber = modelNumber
medicalDevice.catalogNumber = catalogNumber
medicalDevice.deviceDescription = description
medicalDevice.quantity = quantity
medicalDevice.brandName = brandName
medicalDevice.companyName = companyName
medicalDevice.price = price
medicalDevice.location = location
medicalDevice.facilityID = facilityID
self.saveContext()
}
Now, I don't see any setPrice method (which makes sense, I just added it in the various fields), but I also don't see setX, with X being any of the other fields which were definitely saving beforehand.
What could be causing this? Obviously setPrice is somehow being called, somewhere (generated in some way?) and it doesn't exist, I am guessing.
I need your help, I still have an beautiful EXC_BAD_ACCESS error on this line self.clinic!.copyWithDTO(clinicDTO).
Console : po self.clinic
Optional(<NSManagedObject: 0x7a7bd240> (entity: Clinic; id: 0x7a7bbe10 <x-coredata://7B916AD3-1989-426F-932F-0A62C755F2B4/Clinic/p1> ; data: <fault>))
I'm trying to fill properties on a sub entity in CoreData model by giving a DTO.
#objc(UserProfile)
class UserProfile: BaseStoredObject {
override class func entityName() -> String {
return "UserProfile"
}
override func copyWithDTO(dto: BaseDTO) {
if let userProfileDTO = dto as? UserProfileDTO {
self.id = userProfileDTO.id
self.login = userProfileDTO.login
self.password = userProfileDTO.password
self.lastname = userProfileDTO.lastname
self.email = userProfileDTO.email
self.createdOn = userProfileDTO.createdOn
self.gender = userProfileDTO.gender
self.userProfileType = userProfileDTO.userProfileType
self.firstname = userProfileDTO.firstname
self.fullname = userProfileDTO.fullname
if let clinicDTO = userProfileDTO.clinic {
if let unwrappedClinic = self.clinic {
unwrappedClinic.copyWithDTO(clinicDTO)
} else {
self.clinic = Clinic(entity: NSEntityDescription.entityForName("Clinic", inManagedObjectContext: self.managedObjectContext!)!, insertIntoManagedObjectContext: self.managedObjectContext)
self.clinic!.copyWithDTO(clinicDTO) // !! EXC_BAD_ACCESS (code=1, address=0x....)
}
}
} else {
fatalError("copyWithDTO: must be sent with UserProfileDTO")
}
}
}
#objc(Clinic)
class Clinic: BaseStoredObject {
override class func entityName() -> String {
return "Clinic"
}
override func copyWithDTO(dto: BaseDTO) {
if let clinicDTO = dto as? ClinicDTO {
self.id = clinicDTO.id
self.name = clinicDTO.name
self.phoneNumber = clinicDTO.phoneNumber
self.phoneNumber24hours = clinicDTO.phoneNumber24hours
self.nurseContactPhoneNumber = clinicDTO.nurseContactPhoneNumber
self.emergencyPhoneNumber = clinicDTO.emergencyPhoneNumber
self.internalClinicId = clinicDTO.internalClinicId
self.webserviceURL = ""
} else {
fatalError("copyWithDTO: must be sent with ClinicDTO")
}
}
}
extension UserProfile {
#NSManaged var id: String?
#NSManaged var login: String?
#NSManaged var password: String?
#NSManaged var lastname: String?
#NSManaged var firstname: String?
#NSManaged var email: String?
#NSManaged var createdOn: NSDate?
#NSManaged var userProfileType: NSNumber?
#NSManaged var gender: NSNumber?
#NSManaged var fullname: String?
#NSManaged var clinic: Clinic?
}
What I'm doing wrong ?
Thank you ;)
EDIT: BaseStoredObject is a subclass of NSManagedObject
I currently have a JSQMessagesViewController, but am running to the problem of storing my JSQMessages in Parse.com, since Parse.com won't allow this type of object. I've been trying to research ways of creating a class that subclasses PFObject while conforming to JSQMessageData so that I can create messages that are of type PFObject and thus able to be stored in Parse.com.
Below is my Messages class. In my JSQMessagesViewController I would typically call
var newMessage = JSQMessage(senderId: "user", displayName: "user", text: "testing chat")
But now how would I do this with my Messages class?
import Foundation
import UIKit
import Parse
class Message: PFObject, PFSubclassing, JSQMessageData {
var senderId_ : String!
var senderDisplayName_ : String!
var date_ : NSDate
var isMediaMessage_ : Bool
var hash_ : Int = 0
var text_ : String
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
class func parseClassName() -> String {
return "Messages"
}
convenience init(senderId: String?, text: String?) {
self.init(senderId: senderId!, senderDisplayName: senderId, isMediaMessage: false, hash: 0, text: text!)
}
init(senderId: String, senderDisplayName: String?, isMediaMessage: Bool, hash: Int, text: String) {
self.senderId_ = senderId
self.senderDisplayName_ = senderDisplayName
self.date_ = NSDate()
self.isMediaMessage_ = isMediaMessage
self.hash_ = hash
self.text_ = text
super.init()
}
func senderId() -> String? {
return senderId_;
}
func senderDisplayName() -> String? {
return senderDisplayName_;
}
func date() -> NSDate? {
return date_;
}
func isMediaMessage() -> Bool {
return isMediaMessage_;
}
func hash() -> UInt? {
return UInt(hash_);
}
func text() -> String! {
return text_;
}
func messageHash() -> UInt {
return UInt(hash_)
}
}
And my implementation in my ChatView that is a JSQMessagesViewController:
override func viewDidLoad(){
super.viewDidLoad()
var myObject = PFObject(className: "messages")
var myMessage = Message(senderId: "User", text: "Some text")
var messageArray:NSMutableArray = [myMessage]
myObject["myArray"] = messageArray
myObject.save()
}
Currently receiving error
fatal error: use of unimplemented initializer 'init()' for class Message
I'm pretty new to iOS/Swift/Parse and I'm trying to build a model of a class using PFSubclassing.
The data I'm trying to represent should look something like this
{
text: ""
location : {
name: "",
longitude: "",
latitude: ""
}
}
So fare the model I'm have is
class LocationModel {
var name: String?
var longitude: Float?
var latitude: Float?
}
class PostModel: PFObject, PFSubclassing {
class func parseClassName() -> String! {
return "Post"
}
#NSManaged var text: String?
var location: LocationModel?
}
The test property is being saved successfully but I'm unable to get the location properties to save.
The code I'm using to save a record to parse is
var test = PostModel()
test.location?.name = "ESB"
test.location?.latitude = 1
test.location?.longitude = 1
test.text = "This is a test post to see if this works!"
test.saveEventually { (success: Bool, error: NSError!) -> Void in
println(error)
println(success)
}
I did a lot of digging online but I'm unable to find a solution on how to represent an Object datatype in Swift using Parse PFSubclassing
Any help would be greatly appreciated.
Thank you
Here's my solution:
I will create a Hero object for example.
class Hero: PFObject, PFSubclassing {
#NSManaged var strengthPoint: Double
#NSManaged var name: String
static func parseClassName() -> String {
return "Hero"
}
init(strengthPoint: Double, name: String) {
super.init()
self.strengthPoint = strengthPoint
self.name = name
}
init(pfObject: PFObject) {
super.init()
self.strengthPoint = pfObject.object(forKey: "strengthPoint") as! Double
self.name = pfObject.object(forKey: "name") as! String
}
override init() {
super.init()
}
override class func query() -> PFQuery<PFObject>? {
let query = PFQuery(className: self.parseClassName())
query.order(byDescending: "createdAt")
query.cachePolicy = .networkOnly
return query
}
}
Now, after defining your model, you can use these methods to store and retrieve
Create your object in server
func createHero() {
let hero = Hero(strengthPoint: 2.5, name: "Superman")
hero.saveInBackground { (isSuccessful, error) in
print(error?.localizedDescription ?? "Success")
}
}
Retrieve object from server
func retrieveHero() {
let query = Hero.query()
query?.getFirstObjectInBackground(block: { (object, error) in
if error != nil {
print(error?.localizedDescription ?? "Something's wrong here")
} else if let object = object {
let hero = Hero(pfObject: object)
print(hero.strengthPoint) // 2.5
print(hero.name) // Superman
}
})
}
I have seen several different methods for PFSubclassing in Swift 1.2, but the following works best for me:
To begin with, make sure that you have the following in your Objective-C Bridging Header:
#import <Parse/PFObject+Subclass.h>
Here is a very basic example of subclassing PFObject:
import Foundation
import Parse
class Car: PFObject, PFSubclassing {
override class func initialize() {
self.registerSubclass()
}
static func parseClassName() -> String {
return "Car"
}
#NSManaged var model: String
#NSManaged var color: String
#NSManaged var yearManufactured: Int
}
So in your case, this would be:
class PostModel: PFObject, PFSubclassing {
override class func initialize() {
self.registerSubclass()
}
static func parseClassName() -> String {
return "Post"
}
#NSManaged var text: String?
}
Concerning your LocationModel...I'm a bit confused as to what exactly you are trying to accomplish with that. I hope this helps.