I am storing a transformable in CoreData and am trying to make it NSSecureCoding compliant, but I keep getting Unexpectedly found nil whilst unwrapping an optional value, when I try to decode
in the XCDataModel, I am set the property as transformable and use the custom class AssignedExerciseObjects, I have also set the transformer to AssignedExerciseObjectsValueTransformer
I have also registered the transformer in my CoreData stack
here is a copy of my transformer
#objc(AssignedExerciseObjectsValueTransformer)
final class AssignedExerciseObjectsValueTransformer: NSSecureUnarchiveFromDataTransformer {
static let name = NSValueTransformerName(rawValue: String(describing: AssignedExerciseObjectsValueTransformer.self))
override static var allowedTopLevelClasses: [AnyClass] {
return [NSArray.self, AssignedExerciseObjects.self]
}
/// Registers the transformer.
public static func register() {
let transformer = AssignedExerciseObjectsValueTransformer()
ValueTransformer.setValueTransformer(transformer, forName: name)
}
}
and here is a copy of my custom class
import Foundation
public class AssignedExerciseObjects: NSObject, NSSecureCoding {
public static var supportsSecureCoding: Bool = true
public var assignedExerciseObjects: [AssignedExerciseObject] = []
enum Key:String {
case assignedExerciseObjects = "assignedExerciseObjects"
}
init(assignedExerciseObjects: [AssignedExerciseObject]) {
self.assignedExerciseObjects = assignedExerciseObjects
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(assignedExerciseObjects, forKey: Key.assignedExerciseObjects.rawValue)
}
public required convenience init?(coder aDecoder: NSCoder) {
let mAssignedExerciseObjects = aDecoder.decodeObject(of: NSArray.self, forKey: Key.assignedExerciseObjects.rawValue) as! [AssignedExerciseObject]
self.init(assignedExerciseObjects: mAssignedExerciseObjects)
}
}
public class AssignedExerciseObject: NSObject, NSSecureCoding {
public static var supportsSecureCoding: Bool = true
public var mainExercise: String = ""
public var prepareTime: String = ""
public var exerciseTime: String = ""
public var highIntensityTime: String = ""
public var restTime: String = ""
public var highLowSplit: Bool = false
public var isCompleted: Bool = false
public var isSkipped: Bool = false
public var order: Double = 0
enum Key:String {
case mainExercise = "mainExercise"
case prepareTime = "prepareTime"
case exerciseTime = "exerciseTime"
case highIntensityTime = "highIntensityTime"
case restTime = "restTime"
case highLowSplit = "highLowSplit"
case isCompleted = "isCompleted"
case isSkipped = "isSkipped"
case order = "order"
}
init(mainExercise: String, prepareTime: String, exerciseTime: String, highIntensityTime: String, restTime: String, highLowSplit: Bool, isCompleted: Bool, isSkipped: Bool, order: Double) {
self.mainExercise = mainExercise
self.prepareTime = prepareTime
self.exerciseTime = exerciseTime
self.highIntensityTime = highIntensityTime
self.restTime = restTime
self.highLowSplit = highLowSplit
self.isCompleted = isCompleted
self.isSkipped = isSkipped
self.order = order
}
public override init() {
super.init()
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(mainExercise, forKey: Key.mainExercise.rawValue)
aCoder.encode(prepareTime, forKey: Key.prepareTime.rawValue)
aCoder.encode(exerciseTime, forKey: Key.exerciseTime.rawValue)
aCoder.encode(highIntensityTime, forKey: Key.highIntensityTime.rawValue)
aCoder.encode(restTime, forKey: Key.restTime.rawValue)
aCoder.encode(highLowSplit, forKey: Key.highLowSplit.rawValue)
aCoder.encode(isCompleted, forKey: Key.isCompleted.rawValue)
aCoder.encode(isSkipped, forKey: Key.isSkipped.rawValue)
aCoder.encode(order, forKey: Key.order.rawValue)
}
public required convenience init?(coder aDecoder: NSCoder) {
let mMainExercise = aDecoder.decodeObject(of: NSString.self, forKey: Key.mainExercise.rawValue)! as String
let mPrepareTime = aDecoder.decodeObject(of: NSString.self,forKey: Key.prepareTime.rawValue)! as String
let mExerciseTime = aDecoder.decodeObject(of: NSString.self,forKey: Key.exerciseTime.rawValue)! as String
let mHighIntensityTime = aDecoder.decodeObject(of: NSString.self,forKey: Key.highIntensityTime.rawValue)! as String
let mRestTime = aDecoder.decodeObject(of: NSString.self,forKey: Key.restTime.rawValue)! as String
let mHighLowSplit = aDecoder.decodeBool(forKey: Key.highLowSplit.rawValue)
let mIsCompleted = aDecoder.decodeBool(forKey: Key.isCompleted.rawValue)
let mIsSkipped = aDecoder.decodeBool(forKey: Key.isSkipped.rawValue)
let mOrder = aDecoder.decodeDouble(forKey: Key.order.rawValue)
self.init(mainExercise: String(mMainExercise), prepareTime:
String(mPrepareTime), exerciseTime: String(mExerciseTime), highIntensityTime: String(mHighIntensityTime), restTime: String(mRestTime), highLowSplit: Bool(mHighLowSplit), isCompleted: Bool(mIsCompleted), isSkipped: Bool(mIsSkipped), order: Double(mOrder))
}
}
this is where it gives me the error
let mAssignedExerciseObjects = aDecoder.decodeObject(of: NSArray.self, forKey: Key.assignedExerciseObjects.rawValue) as! [AssignedExerciseObject]
I'm still fairly new to swift, but I cannot for the life of me work out why it is returning a nil value?
when the record is created, it all seems to work fine, but when I try to display the record in a table, I get the error
any help is greatly appreciated
regards
Jamie
OK, I've fixed it
Adding my custom class fixed the issue
let mAssignedExerciseObjects = aDecoder.decodeObject(of: [AssignedExerciseObject.self, NSArray.self], forKey: Key.assignedExerciseObjects.rawValue) as! [AssignedExerciseObject]
Related
I'm attempting to:
Load an array of custom objects from JSON file.
Save it in CoreData.
Fetch it using NSFetchRequest.
Note: Each element in the array of custom objects named 'Cube' also contains a nested array of custom objects named 'Algorithm', which also conform to NSCoding (shown in code snippet below).
Steps 1 + 2 seem to work fine. The error occurs when fetching the top level Entities named 'Cube', specifically right after the self.init() is called inside the nested class 'Algorithm'.
Algorithm class:
#objc(Algorithm)
public class Algorithm: NSManagedObject, Decodable, Encodable, NSSecureCoding {
enum CodingKeys: String, CodingKey {
case imageNumber, alg, alternativeAlgs, type, tags, isFavorite, optimalMoves, name }
public static var supportsSecureCoding = true
public func encode(with coder: NSCoder) {
coder.encode(imageNumber, forKey: CodingKeys.imageNumber.rawValue)
coder.encode(optimalMoves, forKey: CodingKeys.optimalMoves.rawValue)
coder.encode(alg, forKey: CodingKeys.alg.rawValue)
coder.encode(name, forKey: CodingKeys.name.rawValue)
coder.encode(type, forKey: CodingKeys.type.rawValue)
coder.encode(isFavorite, forKey: CodingKeys.isFavorite.rawValue)
coder.encode(alternativeAlgs, forKey: CodingKeys.alternativeAlgs.rawValue)
coder.encode(tags, forKey: CodingKeys.tags.rawValue) }
required convenience public init?(coder: NSCoder) {
self.init()
imageNumber = coder.decodeObject(forKey: CodingKeys.imageNumber.rawValue) as? String ?? ""
optimalMoves = coder.decodeObject(forKey: CodingKeys.optimalMoves.rawValue) as? String ?? ""
alg = coder.decodeObject(forKey: CodingKeys.alg.rawValue) as? String ?? ""
name = coder.decodeObject(forKey: CodingKeys.name.rawValue) as? String ?? ""
type = coder.decodeObject(forKey: CodingKeys.type.rawValue) as? String ?? ""
isFavorite = coder.decodeBool(forKey: CodingKeys.isFavorite.rawValue)
alternativeAlgs = coder.decodeObject(forKey: CodingKeys.alternativeAlgs.rawValue) as? [String] ?? []
tags = coder.decodeObject(forKey: CodingKeys.tags.rawValue) as? [String] ?? [] }
required convenience public init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[CodingUserInfoKey.managedObjectContext] as? NSManagedObjectContext else {
throw DecoderConfigurationError.missingManagedObjectContext
}
self.init(context: context)
let container = try decoder.container(keyedBy: CodingKeys.self)
self.imageNumber = try container.decode(String.self, forKey: .imageNumber)
self.optimalMoves = try container.decode(String.self, forKey: .optimalMoves)
self.alg = try container.decode(String.self, forKey: .alg)
self.name = try container.decode(String.self, forKey: .name)
self.type = try container.decode(String.self, forKey: .type)
self.isFavorite = try container.decode(Bool.self, forKey: .isFavorite)
self.alternativeAlgs = try container.decode([String].self, forKey: .alternativeAlgs) as [String]
self.tags = try container.decode([String].self, forKey: .tags) as [String] }
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(imageNumber, forKey: .imageNumber)
try container.encode(optimalMoves, forKey: .optimalMoves)
try container.encode(alg, forKey: .alg)
try container.encode(name, forKey: .name)
try container.encode(type, forKey: .type)
try container.encode(isFavorite, forKey: .isFavorite)
try container.encode(alternativeAlgs, forKey: .alternativeAlgs)
try container.encode(tags, forKey: .tags) }
}
extension Algorithm {
#nonobjc public class func fetchRequest() -> NSFetchRequest<Algorithm> {
return NSFetchRequest<Algorithm>(entityName: "Algorithm")
}
#NSManaged public var alg: String
#NSManaged public var alternativeAlgs: [String]
#NSManaged public var imageNumber: String
#NSManaged public var isFavorite: Bool
#NSManaged public var name: String
#NSManaged public var optimalMoves: String
#NSManaged public var tags: [String]
#NSManaged public var type: String
#NSManaged public var cube: Cube?
}
extension Algorithm : Identifiable {
}
After reading people's comments I am aware I should replace the self.init() with NSManagedObject's designated init, but I haven't found the right way to do so. The app crashes after replacing the self.init() with the following code:
let context = CoreDataManager.shared.container.viewContext
self.init(context: context)
// self.init()
FWI - in the CoreData.xcdatamodeled file inspector the algorithms array is defined as Transformable with a custom transformer - AlgorithmDataTransformer:
#objc(AlgorithmDataTransformer)
public final class AlgorithmDataTransformer: ValueTransformer {
override public func transformedValue(_ value: Any?) -> Any? {
guard let array = value as? [Algorithm] else { return nil }
do {
return try NSKeyedArchiver.archivedData(withRootObject: array, requiringSecureCoding: true)
} catch {
assertionFailure("Failed to transform `Algorithm` to `Data`")
return nil
}
}
override public func reverseTransformedValue(_ value: Any?) -> Any? {
guard let data = value as? NSData else { return nil }
do {
return try NSKeyedUnarchiver.unarchivedArrayOfObjects(ofClass: Algorithm.self, from: data as Data)
} catch {
assertionFailure("Failed to transform `Data` to `Algorithm`")
return nil
}
}
}
extension AlgorithmDataTransformer {
/// The name of the transformer. This is the name used to register the transformer using `ValueTransformer.setValueTrandformer(_"forName:)`.
static let name = NSValueTransformerName(rawValue: String(describing: AlgorithmDataTransformer.self))
/// Registers the value transformer with `ValueTransformer`.
public static func register() {
let transformer = AlgorithmDataTransformer()
ValueTransformer.setValueTransformer(transformer, forName: name)
}
}
I have structure that consists of an a few variables.
struct Contact {
var id:String = "Contact - \(UUID())"
var fullname: String
var exercises : [Exercise]
}
The part i am interest in is the exercises section. This variable takes the following class:
class Exercise : NSObject , NSSecureCoding{
static var supportsSecureCoding: Bool = true
var excerciseName: String
var excerciseReps: String
var excerciseSets: String
var excerciseWeights: String
init(Name : String, Reps : String, Sets : String, Weights : String) {
excerciseName = Name
excerciseReps = Reps
excerciseSets = Sets
excerciseWeights = Weights
}
func encode(with aCoder: NSCoder) {
aCoder.encode(excerciseName, forKey: "excerciseName")
aCoder.encode(excerciseReps, forKey: "excerciseReps")
aCoder.encode(excerciseSets, forKey: "excerciseSets")
aCoder.encode(excerciseWeights, forKey: "excerciseWeights")
}
required convenience init?(coder aDecoder: NSCoder) {
let excerciseName = aDecoder.decodeObject(forKey: "excerciseName") as! String
let excerciseReps = aDecoder.decodeObject(forKey: "excerciseReps") as! String
let excerciseSets = aDecoder.decodeObject(forKey: "excerciseSets") as! String
let excerciseWeights = aDecoder.decodeObject(forKey: "excerciseWeights") as! String
self.init(Name: excerciseName, Reps: excerciseReps, Sets: excerciseSets, Weights: excerciseWeights)
}
}
In the view controller i want to access these variables in i have activated it:
var contacts = [Contact]()
My problem is when i am trying to access it it doesn't give me the option. when i type self.contacts. then nothing appears. i was expecting self.contacts.excercises to be there on auto fill. it that option isn't there. what am i missing?
I have a class with some properties, and I am using encode while saving and decoder while fetching, but some of the data are not optional, but at the first time when I am fetching it's null so when the decoder is calling and it found nill value it crashes the app.
So what I want is when I fetch the data and if no data found I can set some default value instead of crashing I can solve this by making those properties optional but I don't want that. and also not able to add try catch to make sure it doesn't crash
Please tell what changes should I make to this class and also share some example or links or tutorial that explains everything about encoder and decoder in depth (not some medium article with just overview)
I am new to swift so if you find anything wrong with this class do tell in comments and best ways to do with latest swift
import Foundation
enum AcModeType {
case acModeCool
case acModeDry
case acModeHeat
case acModeFan
case acModeTimer
}
enum FanModeType {
case fanModeLow
case fanModeMid
case fanModeHigh
case FanModeAuto
}
class AcDevice: Device {
var brandId: String?
var variant: String?
var brandName: String?
var acTemperature: Int = 16
var acMinTemperature: Int = 16
var acMaxTemperature: Int = 32
var weatherTemperature: Int = 0
var roomTemperature: Int = 0
var timeTable = [TimeTable]()
var currentAcMode: AcModeType = .acModeCool
var currentFanMode: FanModeType = .fanModeLow
var lastPowerOnTime: Double = 0.0
var isPowerOn = false
var isSleepOn = false
var isTimeTableOn = false
var hasScreen = false
required public init?(coder aDecoder: NSCoder) {
super.init();
brandId = (aDecoder.decodeObject(forKey: "brandId") as! String?)
variant = (aDecoder.decodeObject(forKey: "variant") as! String?)
brandName = (aDecoder.decodeObject(forKey: "brandName") as! String?)
acTemperature = (aDecoder.decodeObject(forKey: "temperature") as! Int)
acMinTemperature = (aDecoder.decodeObject(forKey: "acMinTemperature") as! Int )
acMaxTemperature = (aDecoder.decodeObject(forKey: "acMaxTemperature") as! Int )
weatherTemperature = (aDecoder.decodeObject(forKey: "weatherTemperature") as! Int)
roomTemperature = (aDecoder.decodeObject(forKey: "roomTemperature") as! Int )
currentAcMode = (aDecoder.decodeObject(forKey: "currentAcMode") as! AcModeType)
currentFanMode = (aDecoder.decodeObject(forKey: "currentFanMode") as! FanModeType)
lastPowerOnTime = (aDecoder.decodeObject(forKey: "lastPowerOnTime") as! Double)
if let timeTable = aDecoder.decodeObject(forKey: "timeTable") as! [TimeTable]? {self.timeTable=timeTable}
}
public override func encode(with aCoder: NSCoder) {
aCoder.encode(self.brandId, forKey: "brandId")
aCoder.encode(self.variant, forKey: "variant")
aCoder.encode(self.brandName, forKey: "brandName")
aCoder.encode(self.acTemperature, forKey: "temperature")
aCoder.encode(self.timeTable, forKey: "timeTable")
aCoder.encode(self.acMinTemperature, forKey: "acMinTemperature")
aCoder.encode(self.acMaxTemperature, forKey: "acMaxTemperature")
aCoder.encode(self.weatherTemperature, forKey: "weatherTemperature")
aCoder.encode(self.roomTemperature, forKey: "roomTemperature")
aCoder.encode(self.currentAcMode, forKey: "currentAcMode")
aCoder.encode(self.currentFanMode, forKey: "currentFanMode")
aCoder.encode(self.lastPowerOnTime, forKey: "lastPowerOnTime")
}
required public init() {
super.init();
brandId = ""
variant = ""
brandName = ""
isPowerOn = false;
isSleepOn = false;
isTimeTableOn = false;
hasScreen = false;
currentAcMode = .acModeCool
acMinTemperature = 16;
acMaxTemperature = 32;
currentFanMode = .fanModeLow
lastPowerOnTime = -1;
timeTable = [TimeTable]()
}
}
In your required public init?(coder aDecoder: NSCoder) you're using as! to force cast the results of decodeObject, so this will crash your app if it fails. Instead you could use as? in combination with a default value to unwrap your optionals.
For example:
brandId = aDecoder.decodeObject(forKey: "brandId") as? String ?? "your default string"
This uses ?? which is the nil coalescing operator to provide a default value when the left hand side is nil.
You can do that with Codable protocols in swift. Just have a look at the below link.
https://hackernoon.com/everything-about-codable-in-swift-4-97d0e18a2999
and,
Apple documentation for this:
https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types
I've created a class with some vars and lets. One of these vars is a String. I store them in UserDefaults. If I want to access the string of this class over a singleton class, I will always get an optional String. I don't know why.
Here is the class of the object:
import Foundation
import SpriteKit
class BallSkinsClass: NSObject, NSCoding {
let id: Int
var name: String
var isBuyed: Bool
let ID = "id"
let NAME = "name"
let ISBUYED = "isBuyed"
init(id: Int, name: String, isBuyed: Bool) {
self.id = id
self.name = name
self.isBuyed = isBuyed
}
required init?(coder aDecoder: NSCoder) {
self.id = aDecoder.decodeInteger(forKey: ID)
self.name = String(describing: aDecoder.decodeObject(forKey: NAME))
self.isBuyed = aDecoder.decodeBool(forKey: ISBUYED)
}
#objc func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: ID)
aCoder.encode(name, forKey: NAME)
aCoder.encode(isBuyed, forKey: ISBUYED)
}
}
To declare the skins, access, save and load I have these functions in my BallSkinsClass:
import Foundation
import SpriteKit
import GameKit
class BallSkins {
static var sharedInstance = BallSkins()
private init() {
}
let BALLSKINS = "ballSkins"
var standard: BallSkinsClass! = BallSkinsClass(id: 0, name: "Standard", isBuyed: true)
var billiard: BallSkinsClass! = BallSkinsClass(id: 1, name: "Billard", isBuyed: false)
var emoji: BallSkinsClass! = BallSkinsClass(id: 2, name: "Emojis", isBuyed: false)
func archiveBallSkins(ballSkins:[BallSkinsClass]) -> NSData {
print("archiving Skins")
let archivedBallSkins = NSKeyedArchiver.archivedData(withRootObject: ballSkins as Array)
return archivedBallSkins as NSData
}
func saveBallSkins(ballSkins:[BallSkinsClass]) {
let archivedBallSkins = archiveBallSkins(ballSkins: ballSkins)
UserDefaults.standard.set(archivedBallSkins, forKey: BALLSKINS)
print("saving Skins")
}
func retrieveBallSkins() -> [BallSkinsClass]? {
print("retrieving Skins")
if let unarchivedBallSkins = UserDefaults.standard.object(forKey: BALLSKINS) as? NSData {
return NSKeyedUnarchiver.unarchiveObject(with: unarchivedBallSkins as Data) as? [BallSkinsClass]
}
return nil
}
func loadBallSkins() {
print("loading Skins")
let archivedBallSkins = retrieveBallSkins()
for ballSkin in archivedBallSkins! {
switch ballSkin.id {
case 0 :
standard.isBuyed = ballSkin.isBuyed
case 1:
billiard.isBuyed = ballSkin.isBuyed
case 2:
emoji.isBuyed = ballSkin.isBuyed
default:
standard.isBuyed = ballSkin.isBuyed
}
}
}
}
If I want to access the name of the skin in any other scene or view I call:
ballSkins.sharedInstance.billiard.name
But this is an optional every time! I don't know why or where the error is.
I suppose it is caused by
required init?(coder aDecoder: NSCoder) {
self.id = aDecoder.decodeInteger(forKey: ID)
self.name = String(describing: aDecoder.decodeObject(forKey: NAME))
self.isBuyed = aDecoder.decodeBool(forKey: ISBUYED)
}
3rd line generates optional string because according to documentation
func decodeObject() -> Any?
and String(describing: ...) does not unwrap your value. You must unwrap all values from UserDefaults by yourself, providing defaultValue if nil is not possible
Hello I try to store a custom object with NSUserDefaults. I used this helpful post Saving custom SWIFT class with NSCoding to UserDefaults
But I get the following exception when I try it out
2015-05-12 11:05:14.994 KirchnerTime[4424:75095] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -length only defined for abstract class. Define -[Project length]!'
import Foundation
#objc(Project)
public class ProjectJobEntity: NSData, NSCoding
{
private let _barCode: String
private var _projectNumber: String
private var _projectDescription: String
private var _jobDescription: String
public var BarCode: String
{
get { return self._barCode }
}
public var ProjectNumber: String
{
get { return self._projectNumber }
set { self._projectNumber = newValue }
}
public var ProjectDescription: String
{
get { return self._projectDescription }
set { self._projectDescription = newValue }
}
public var JobDescription: String
{
get { return self._jobDescription }
set { self._jobDescription = newValue }
}
public init(barCode: String, projectNumber: String, projectDescription: String, jobDescription: String)
{
self._barCode = barCode
self._projectNumber = projectNumber
self._projectDescription = projectDescription
self._jobDescription = jobDescription
super.init()
}
public init(barCode: String)
{
self._barCode = barCode
self._projectNumber = ""
self._projectDescription = ""
self._jobDescription = ""
super.init()
}
override public func encodeWithCoder(aCoder: NSCoder)
{
aCoder.encodeObject(self._barCode, forKey: "barCode")
aCoder.encodeObject(self._projectNumber, forKey: "projectNumber")
aCoder.encodeObject(self._projectDescription, forKey: "projectDescription")
aCoder.encodeObject(self._jobDescription, forKey: "jobDescription")
}
required public init(coder aDecoder: NSCoder)
{
self._barCode = aDecoder.decodeObjectForKey("barCode") as! String
self._projectNumber = aDecoder.decodeObjectForKey("projectNumber") as! String
self._projectDescription = aDecoder.decodeObjectForKey("projectDescription") as! String
self._jobDescription = aDecoder.decodeObjectForKey("jobDescription") as! String
super.init(coder: aDecoder)
}
this is the object which should be stored.
public func saveSettings()
{
let settings = NSUserDefaults.standardUserDefaults()
settings.setValue(self._cardNumber, forKeyPath: cardNumberKey)
settings.setObject(NSKeyedArchiver.archivedDataWithRootObject(ProjectJobEntity(barCode: "Test")), forKey: "Project")
}
and this is how I try it.
I had same exception.
I use NSObject as parent class.
use under code
public class ProjectJobEntity: NSObject
{
private let _barCode: String
private var _projectNumber: String
private var _projectDescription: String
private var _jobDescription: String
public var BarCode: String
{
get { return self._barCode }
}
public var ProjectNumber: String
{
get { return self._projectNumber }
set { self._projectNumber = newValue }
}
public var ProjectDescription: String
{
get { return self._projectDescription }
set { self._projectDescription = newValue }
}
public var JobDescription: String
{
get { return self._jobDescription }
set { self._jobDescription = newValue }
}
public init(barCode: String, projectNumber: String, projectDescription: String, jobDescription: String)
{
self._barCode = barCode
self._projectNumber = projectNumber
self._projectDescription = projectDescription
self._jobDescription = jobDescription
super.init()
}
public init(barCode: String)
{
self._barCode = barCode
self._projectNumber = ""
self._projectDescription = ""
self._jobDescription = ""
super.init()
}
public func encodeWithCoder(aCoder: NSCoder)
{
aCoder.encodeObject(self._barCode, forKey: "barCode")
aCoder.encodeObject(self._projectNumber, forKey: "projectNumber")
aCoder.encodeObject(self._projectDescription, forKey: "projectDescription")
aCoder.encodeObject(self._jobDescription, forKey: "jobDescription")
}
public func initWithCoder(aDecoder: NSCoder) -> ProjectJobEntity
{
let barCode = aDecoder.decodeObjectForKey("barCode") as! String
let projectNumber = aDecoder.decodeObjectForKey("projectNumber") as! String
let projectDescription = aDecoder.decodeObjectForKey("projectDescription") as! String
let jobDescription = aDecoder.decodeObjectForKey("jobDescription") as! String
return ProjectJobEntity(barCode: barCode, projectNumber: projectNumber, projectDescription: projectDescription, jobDescription: jobDescription)
}
}