How to Convert Custom Object to Data Swift

Converting custom class object into NSData

Here is one simple example for you:

//Custom class.
class Person: NSObject, NSCoding {
var name: String!
var age: Int!
required convenience init(coder decoder: NSCoder) {
self.init()
self.name = decoder.decodeObjectForKey("name") as! String
self.age = decoder.decodeObjectForKey("age") as! Int
}
convenience init(name: String, age: Int) {
self.init()
self.name = name
self.age = age
}
func encodeWithCoder(coder: NSCoder) {
if let name = name { coder.encodeObject(name, forKey: "name") }
if let age = age { coder.encodeObject(age, forKey: "age") }

}
}

//create an instance of your custom class.
var newPerson = [Person]()

//add some values into custom class.
newPerson.append(Person(name: "Leo", age: 45))
newPerson.append(Person(name: "Dharmesh", age: 25))

//store you class object into NSUserDefaults.
let personData = NSKeyedArchiver.archivedDataWithRootObject(newPerson)
NSUserDefaults().setObject(personData, forKey: "personData")

//get your object from NSUserDefaults.
if let loadedData = NSUserDefaults().dataForKey("personData") {

if let loadedPerson = NSKeyedUnarchiver.unarchiveObjectWithData(loadedData) as? [Person] {
loadedPerson[0].name //"Leo"
loadedPerson[0].age //45
}
}

Tested with playground.

Hope this helps.

Convert a custom object to Data to be saved in NSUserDefauts

The issue there. is that you are mixing up Codable with NSCoding. To use NSKeyedArchiver's archivedData method you need to have a class that conforms to NSCoding. In you case you have a structure that conforms to Codable so you need to use JSONEncoder encode method. Note: Your equatable method declaration was wrong:

struct BallPark: Codable, Equatable  {
static func == (lhs: Self, rhs: Self) -> Bool {
return lhs.id == rhs.id
}
let id: String
let name: String?
let location: VenueCoordinates?
let mapEnabled: Bool?
let facilityStatus: String?
}


struct VenueCoordinates: Codable {
let latitude: String?
let longitude: String?

var lat: Double? {
guard let latitud = latitude else { return nil}
return Double(latitud)
}
var lon: Double? {
guard let longitude = longitude else { return nil}
return Double(longitude)
}
}


let bestBallParkToSave = BallPark.init(id: "1", name: "Steve", location: .init(latitude: "20.0", longitude: "40.0"), mapEnabled: true, facilityStatus: "a status")

do {
let encodedBestBallPark = try JSONEncoder().encode(bestBallParkToSave)
UserDefaults.standard.set(encodedBestBallPark, forKey: "favoriteBallPark")
if let ballParkData = UserDefaults.standard.data(forKey: "favoriteBallPark") {
let loadedBallPark = try JSONDecoder().decode(BallPark.self, from: ballParkData)
print(loadedBallPark) // BallPark(id: "1", name: Optional("Steve"), location: Optional(VenueCoordinates(latitude: Optional("20.0"), longitude: Optional("40.0"))), mapEnabled: Optional(true), facilityStatus: Optional("a status"))
}
} catch {
print(error)
}

You can also make your life easier extending UserDefaults and create customs encoding and decoding methods:

extension UserDefaults {
func decodeObject<T: Decodable>(forKey defaultName: String, using decoder: JSONDecoder = .init()) throws -> T {
try decoder.decode(T.self, from: data(forKey: defaultName) ?? .init())
}
func encode<T: Encodable>(_ value: T, forKey defaultName: String, using encoder: JSONEncoder = .init()) throws {
try set(encoder.encode(value), forKey: defaultName)
}
}

Usage:

let bestBallParkToSave = BallPark(id: "1", name: "Steve", location: .init(latitude: "20.0", longitude: "40.0"), mapEnabled: true, facilityStatus: "a status")
do {

try UserDefaults.standard.encode(bestBallParkToSave, forKey: "favoriteBallPark")
let loadedBallPark: BallPark = try UserDefaults.standard.decodeObject(forKey: "favoriteBallPark")
print(loadedBallPark) // BallPark(id: "1", name: Optional("Steve"), location: Optional(VenueCoordinates(latitude: Optional("20.0"), longitude: Optional("40.0"))), mapEnabled: Optional(true), facilityStatus: Optional("a status"))

} catch {
print(error)
}

How can I store an custom class as Data

Define a custom object which conforms to Codable. A simple example:

struct MyObject: Codable {
var something: String
}

And when you want to save it to UserDefaults, just encode it:

do {
let encoded = try JSONEncoder().encode(MyObject(something: "String"))
UserDefaults.standard.set(encoded, forKey: "kSavedObject")
} catch {
print(error)
}

If you want to retrieve it, you can use decode:

if let data = UserDefaults.standard.data(forKey: "kSavedObject") {
do {
let myRetrievedObject = try JSONDecoder().decode(MyObject.self, from: data)
} catch {
print(error)
}
}

converting custom object to NSData Swift

if your Enum is like this PieceType and type is Int

enum PieceType : Int {
case empty
case notEmpty

}

Then write encode and decode method like this way

 required init(coder aDecoder: NSCoder) {
isSelected = aDecoder.decodeBool(forKey: "isSelected")
type = PieceType(rawValue: aDecoder.decodeObject(forKey: "type") as! Int)!
isWhite = aDecoder.decodeBool(forKey: "isWhite")
isFirstMove = aDecoder.decodeBool(forKey: "isFirstMove")
symbol = aDecoder.decodeObject(forKey: "symbol") as! String
position = aDecoder.decodeObject(forKey: "position") as! (Int, Int)
}

func encode(with aCoder: NSCoder) {
aCoder.encode(isSelected, forKey: "isSelected")
aCoder.encode(type.rawValue, forKey: "type")
aCoder.encode(isWhite, forKey: "isWhite")
aCoder.encode(isFirstMove, forKey: "isFirstMove")
aCoder.encode(symbol, forKey: "symbol")
aCoder.encode(position.row, forKey: "position.row")
aCoder.encode(position.col, forKey: "position.col")
}

i have check bellow code and it work's

 let pice = Piece(isSelected: true, type: .empty, isWhite: true, isFirstMove: true, symbol: "Test", position: (2, 10))
let pieceData = NSKeyedArchiver.archivedData(withRootObject:pice)
print(pieceData)

And Out put is

386 bytes

ios swift, How to convert 'object to nsdata'

Xcode 8 (Swift 3) Playground:

class PacketHeader: NSObject, NSCoding {
var ver: UInt8 = 0
var len: UInt32 = 0

override init() {
super.init()
}

required init(coder aDecoder: NSCoder) {

if let ver = aDecoder.decodeObject(forKey: "ver") as? NSNumber {
self.ver = ver.uint8Value
}

if let len = aDecoder.decodeObject(forKey: "len") as? NSNumber {
self.len = len.uint32Value
}

}

func encode(with aCoder: NSCoder) {
aCoder.encode(NSNumber(value: ver), forKey: "ver")
aCoder.encode(NSNumber(value: len), forKey: "len")
}

}

let data = PacketHeader()
data.ver = 10
data.len = 8

let savedData = NSKeyedArchiver.archivedData(withRootObject: data)
let obj = NSKeyedUnarchiver.unarchiveObject(with: savedData) as? PacketHeader
obj?.ver
obj?.len

How to convert document to a custom object in Swift 5?

After contacting the firebase team, I found the solution I was looking for. It turns out I have to do import FirebaseFirestoreSwift explicitly instead of just doing import Firebase. The error will disappear after this. (And of course you'll need to add the pod to your podfile first:D)

How to convert an array of multiple object types to JSON without missing any object attribute in Swift?

class SUVCar: Car
{
enum SUVCarKeys: CodingKey {
case weight
}
var weight: Int

init(_ weight: Int)
{
self.weight = weight
super.init(brand: "MyBrand")
}

override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: SUVCarKeys.self)
try container.encode(weight, forKey: .weight)
try super.encode(to: encoder)
}
}

If you augment the subclass's implementation of encode then you can add in additional properties



Related Topics



Leave a reply



Submit