Reputation: 1754
I have below Struct and I am creating a default object using the Struct. After creating the object I am saving to user defaults. but get the error . Please see below code and error. Let me know how this object can be saved to user defaults.
struct FlightSearchObj {
var FlightTripType:Int = 0
var FlightArrObj: [FlightObj]?
var FlightTravellers: [String : Int] = ["Adults": 1, "Child": 0, "Infants": 0]
var FlightClass : String = "Economy"
var PreferredAirline : [String] = []
var FlightFareType : String = "All"
}
struct FlightObj {
var fromAirportObj:AirportDetail?
var toAirportObj:AirportDetail?
var DepartDate: String?
}
In ViewController
var finalOneWayRoundFlightSearchObj : FlightSearchObj?
var finalMultiFlightSearchObj : FlightSearchObj?
//DefaultObject for Flights
finalOneWayRoundFlightSearchObj = FlightSearchObj()
finalMultiFlightSearchObj = FlightSearchObj()
var flightArrObj = [FlightObj]()
let flightObj = FlightObj()
flightArrObj.append(flightObj)
flightArrObj.append(flightObj)
finalOneWayRoundFlightSearchObj?.FlightArrObj = flightArrObj
finalMultiFlightSearchObj?.FlightArrObj = flightArrObj
print(finalOneWayRoundFlightSearchObj?.FlightArrObj?.count ?? 0)
print(finalMultiFlightSearchObj?.FlightArrObj?.count ?? 0)
FetchOnewayRoundTripObjValues(obj:finalOneWayRoundFlightSearchObj!)
FetchMultiCityObjValues(obj:finalMultiFlightSearchObj!)
func FetchOnewayRoundTripObjValues(obj:FlightSearchObj){
if (Constants.sharedInstance.defaults.value(forKey: "flightOnewayRoundTripObj") != nil){
print("OneWay/RoundTrip Obj found - \(obj)")
}else{
print("OneWay/RoundTrip Obj not found")
print(obj)
Constants.sharedInstance.defaults.set(obj, forKey: "flightOnewayRoundTripObj")
}
}
func FetchMultiCityObjValues(obj:FlightSearchObj){
if (Constants.sharedInstance.defaults.value(forKey: "flightMultiFlightObj") != nil){
print("MultiFlight Obj found - \(obj)")
}else{
print("MultiFlight Obj not found")
Constants.sharedInstance.defaults.set(obj, forKey: "flightMultiFlightObj")
}
}
Error * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object BookingApp.FlightSearchObj(FlightTripType: 0, FlightArrObj: Optional([BookingApp.FlightObj(fromAirportObj: nil, toAirportObj: nil, DepartDate: nil), BookingApp.FlightObj(fromAirportObj: nil, toAirportObj: nil, DepartDate: nil)]), FlightTravellers: ["Adults": 1, "Child": 0, "Infants": 0], FlightClass: "Economy", PreferredAirline: [], FlightFareType: "All") for key flightOnewayRoundTripObj' * First throw call stack: (0x202978ec4 0x201b49a40 0x20287f594 0x2029ab140 0x2029ab80c 0x2029ab580 0x2029ab930 0x202864408 0x2028f4908 0x2028f425c 0x202860db4 0x202863da4 0x2029b64d8 0x20333b4dc 0x103060038 0x1030644f8 0x102a56db8 0x102adcadc 0x102add8cc 0x22f6936d0 0x22f693b00 0x22f5ec2ec 0x22f600dac 0x22f602280 0x22f5e4470 0x23010373c 0x206f75b74 0x206f7ab2c 0x206ed944c 0x206f07d7c 0x206f08be4 0x2029087cc 0x202903460 0x202903a00 0x2029031f0 0x204b7c584 0x22fc5abc0 0x1030fb894 0x2023c2bb4) libc++abi.dylib: terminating with uncaught exception of type NSException
Upvotes: 0
Views: 78
Reputation: 1560
Confirm protocol Codable
in all your struct which you want to save in UserDefaults
.
struct FlightSearchObj: Codable {
var FlightTripType:Int = 0
var FlightArrObj: [FlightObj]?
var FlightTravellers: [String : Int] = ["Adults": 1, "Child": 0, "Infants": 0]
var FlightClass : String = "Economy"
var PreferredAirline : [String] = []
var FlightFareType : String = "All"
}
struct FlightObj: Codable {
var fromAirportObj:AirportDetail?
var toAirportObj:AirportDetail?
var DepartDate: String?
}
struct AirportDetail: Codable {
// Your properties
}
Now you need to save and get that object from UserDefaults
using PropertyListEncoder
and PropertyListDecoder
.
In your case
func FetchOnewayRoundTripObjValues(obj:FlightSearchObj){
if let data = UserDefaults.standard.value(forKey:"flightOnewayRoundTripObj") as? Data {
let res = try? PropertyListDecoder().decode(FlightSearchObj.self, from: data)
print("OneWay/RoundTrip Obj found - \(res)")
}else{
print("OneWay/RoundTrip Obj not found")
print(obj)
UserDefaults.standard.set(try? PropertyListEncoder().encode(obj), forKey:"flightOnewayRoundTripObj")
// Constants.sharedInstance.defaults.set(obj, forKey: "flightOnewayRoundTripObj")
}
}
func FetchMultiCityObjValues(obj:FlightSearchObj){
if let data = UserDefaults.standard.value(forKey:"flightOnewayRoundTripObj") as? Data {
let res = try? PropertyListDecoder().decode(FlightSearchObj.self, from: data)
print("MultiFlight Obj found - \(res)")
}else{
print("MultiFlight Obj not found")
UserDefaults.standard.set(try? PropertyListEncoder().encode(obj), forKey:"flightMultiFlightObj")
// Constants.sharedInstance.defaults.set(obj, forKey: "flightMultiFlightObj")
}
}
Upvotes: 1
Reputation: 13833
In case of Struct you need to Make your struct codable simply by marking it as adopting the Codable
protocol:
struct FlightSearchObj:Codable {
var FlightTripType:Int = 0
var FlightArrObj: [FlightObj]?
var FlightTravellers: [String : Int] = ["Adults": 1, "Child": 0, "Infants": 0]
var FlightClass : String = "Economy"
var PreferredAirline : [String] = []
var FlightFareType : String = "All"
}
struct FlightObj:Codable {
var fromAirportObj:AirportDetail?
var toAirportObj:AirportDetail?
var DepartDate: String?
}
Also make AirportDetail Codable...
Upvotes: 0