Created
February 27, 2020 10:44
-
-
Save godrm/c765a8a584b1e0b50913d595dfbabc50 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// archiver.swift | |
// | |
// Created by JK on 2020/02/27. | |
// Copyright © 2020 codesquad. All rights reserved. | |
// | |
import Foundation | |
class NBeverage : NSObject, NSCoding, Codable { | |
private var brand : String = "" | |
private enum CodingKeys: String, CodingKey { | |
case brand | |
} | |
init(brand : String) { | |
self.brand = brand | |
} | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.brand = try container.decode(String.self, forKey: .brand) | |
} | |
func encode(to encoder: Encoder) throws { | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
try container.encode(brand, forKey: .brand) | |
} | |
required init?(coder: NSCoder) { | |
self.brand = coder.decodeObject(forKey: "brand") as! String | |
} | |
func encode(with coder: NSCoder) { | |
coder.encode(brand, forKey: "brand") | |
} | |
override var description: String { | |
return "Beverage(\(brand))" | |
} | |
} | |
class NCoffee : NBeverage { | |
private var caffeine : Double = 0 | |
private enum CodingKeys: String, CodingKey { | |
case caffeine | |
} | |
init(brand : String, caffeine : Double) { | |
self.caffeine = caffeine | |
super.init(brand: brand) | |
} | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.caffeine = try container.decode(Double.self, forKey: .caffeine) | |
try super.init(from: decoder) | |
} | |
override func encode(to encoder: Encoder) throws { | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
try container.encode(caffeine, forKey: .caffeine) | |
try super.encode(to: encoder) | |
} | |
required init?(coder: NSCoder) { | |
self.caffeine = coder.decodeDouble(forKey: "caffeine") | |
super.init(coder: coder) | |
} | |
override func encode(with coder: NSCoder) { | |
coder.encode(caffeine, forKey: "caffeine") | |
super.encode(with: coder) | |
} | |
override var description: String { | |
return "Coffee(\(caffeine))-(\(super.description))" | |
} | |
} | |
class NSoda : NBeverage { | |
private var nitrogen : Double = 0 | |
private enum CodingKeys: String, CodingKey { | |
case nitrogen | |
} | |
init(brand: String, nitrogen : Double) { | |
self.nitrogen = nitrogen | |
super.init(brand: brand) | |
} | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.nitrogen = try container.decode(Double.self, forKey: .nitrogen) | |
try super.init(from: decoder) | |
} | |
override func encode(to encoder: Encoder) throws { | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
try container.encode(nitrogen, forKey: .nitrogen) | |
try super.encode(to: encoder) | |
} | |
required init?(coder: NSCoder) { | |
self.nitrogen = coder.decodeDouble(forKey: "nitrogen") | |
super.init(coder: coder) | |
} | |
override func encode(with coder: NSCoder) { | |
coder.encode(nitrogen, forKey: "nitrogen") | |
super.encode(with: coder) | |
} | |
override var description: String { | |
return "Soda(\(nitrogen))-(\(super.description))" | |
} | |
} | |
class NCoke : NSoda { | |
private var diet : Bool = false | |
private enum CodingKeys: String, CodingKey { | |
case diet | |
} | |
init(brand: String, nitrogen: Double, diet: Bool) { | |
self.diet = diet | |
super.init(brand: brand, nitrogen: nitrogen) | |
} | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.diet = try container.decode(Bool.self, forKey: .diet) | |
try super.init(from: decoder) | |
} | |
override func encode(to encoder: Encoder) throws { | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
try container.encode(diet, forKey: .diet) | |
try super.encode(to: encoder) | |
} | |
required init?(coder: NSCoder) { | |
self.diet = coder.decodeBool(forKey: "diet") | |
super.init(coder: coder) | |
} | |
override func encode(with coder: NSCoder) { | |
coder.encode(diet, forKey: "diet") | |
super.encode(with: coder) | |
} | |
override var description: String { | |
return "Coke(\(diet))-(\(super.description))" | |
} | |
} | |
func archive(with things: [NBeverage]) -> Data { | |
do { | |
let archived = try NSKeyedArchiver.archivedData(withRootObject: things, requiringSecureCoding: false) | |
return archived | |
} | |
catch { | |
print(error) | |
} | |
return Data() | |
} | |
func unarchive(with text: Data) -> [NBeverage]? { | |
do { | |
let object = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(text) | |
return object as? [NBeverage] | |
} | |
catch { | |
print(error) | |
} | |
return [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// codable.swift | |
// | |
// Created by JK on 2020/02/27. | |
// Copyright © 2020 codesquad. All rights reserved. | |
// | |
import Foundation | |
class Beverage : Codable, CustomStringConvertible { | |
private var brand : String = "" | |
private enum CodingKeys: String, CodingKey { | |
case brand | |
} | |
init(brand : String) { | |
self.brand = brand | |
} | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.brand = try container.decode(String.self, forKey: .brand) | |
} | |
func encode(to encoder: Encoder) throws { | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
try container.encode(brand, forKey: .brand) | |
} | |
var description: String { | |
return "Beverage(\(brand))" | |
} | |
} | |
class Coffee : Beverage { | |
private var caffeine : Double = 0 | |
private enum CodingKeys: String, CodingKey { | |
case caffeine | |
} | |
init(brand : String, caffeine : Double) { | |
self.caffeine = caffeine | |
super.init(brand: brand) | |
} | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.caffeine = try container.decode(Double.self, forKey: .caffeine) | |
try super.init(from: decoder) | |
} | |
override func encode(to encoder: Encoder) throws { | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
try container.encode(caffeine, forKey: .caffeine) | |
try super.encode(to: encoder) | |
} | |
override var description: String { | |
return "Coffee(\(caffeine))-(\(super.description))" | |
} | |
} | |
class Soda : Beverage { | |
private var nitrogen : Double = 0 | |
private enum CodingKeys: String, CodingKey { | |
case nitrogen | |
} | |
init(brand: String, nitrogen : Double) { | |
self.nitrogen = nitrogen | |
super.init(brand: brand) | |
} | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.nitrogen = try container.decode(Double.self, forKey: .nitrogen) | |
try super.init(from: decoder) | |
} | |
override func encode(to encoder: Encoder) throws { | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
try container.encode(nitrogen, forKey: .nitrogen) | |
try super.encode(to: encoder) | |
} | |
override var description: String { | |
return "Soda(\(nitrogen))-(\(super.description))" | |
} | |
} | |
class Coke : Soda { | |
private var diet : Bool = false | |
private enum CodingKeys: String, CodingKey { | |
case diet | |
} | |
init(brand: String, nitrogen: Double, diet: Bool) { | |
self.diet = diet | |
super.init(brand: brand, nitrogen: nitrogen) | |
} | |
required init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.diet = try container.decode(Bool.self, forKey: .diet) | |
try super.init(from: decoder) | |
} | |
override func encode(to encoder: Encoder) throws { | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
try container.encode(diet, forKey: .diet) | |
try super.encode(to: encoder) | |
} | |
override var description: String { | |
return "Coke(\(diet))-(\(super.description))" | |
} | |
} | |
func encode(with things: [Beverage]) -> String { | |
let jsonEncoder = JSONEncoder() | |
do { | |
let json = try jsonEncoder.encode(things) | |
return String(data: json, encoding: .utf8) ?? "" | |
} | |
catch { | |
print(error) | |
} | |
return "" | |
} | |
func decode(with text: String) -> [Beverage] { | |
let jsonDecoder = JSONDecoder() | |
do { | |
let jsonObject = try jsonDecoder.decode([Beverage].self, from: text.data(using: .utf8) ?? Data()) | |
return jsonObject | |
} | |
catch { | |
print(error) | |
} | |
return [] | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let ndrinks : [NBeverage] = [ NCoke(brand: "Coca", nitrogen: 50, diet: true), | |
NCoffee(brand: "TOP", caffeine: 256), | |
NCoke(brand: "Pepsi", nitrogen: 51, diet: false) ] | |
let archiveText = archive(with: ndrinks) | |
let archiveObject = unarchive(with: archiveText) | |
result = "" | |
archiveObject?.forEach{ | |
result += $0.description + ", " | |
} | |
print(result) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let drinks : [Beverage] = [ Coke(brand: "Coca", nitrogen: 50, diet: true), | |
Coffee(brand: "TOP", caffeine: 256), | |
Coke(brand: "Pepsi", nitrogen: 51, diet: false) ] | |
let jsonText = encode(with: drinks) | |
let jsonObject = decode(with: jsonText) | |
var result = "" | |
jsonObject.forEach{ | |
result += $0.description + ", " | |
} | |
print(result) | |
/* | |
Swift 4 Decodable Loses Subclass Type Information | |
https://bugs.swift.org/browse/SR-5331 | |
This is by design — if you need the dynamism required to do this, we recommend that you adopt NSSecureCoding and use NSKeyedArchiver/NSKeyedUnarchiver, which will allow you to decode based on the class found in the archive rather than what is requested at runtime. See https://developer.apple.com/documentation/foundation/nscoding and https://developer.apple.com/documentation/foundation/nssecurecoding for more info. | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment