Created
April 4, 2019 15:57
-
-
Save YannisDC/2cc945f78b92f91d07e13d74684211bf 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
import Cocoa | |
struct Person: Codable { | |
let name: String | |
let age: Int | |
let friends: [Person]? | |
} | |
let person = Person(name: "Brad", age: 53, friends: nil) | |
protocol Identifiable { | |
var uuid: String { get set } | |
} | |
protocol Encryptable { | |
var encrypted: Bool { get } | |
func encrypt() | |
func decrypt() | |
} | |
public class EncryptableProperty<T: Codable>: Encryptable { | |
var value: T | |
var encryptedValue: String | |
var encrypted: Bool | |
init(value: T, encrypted: Bool) { | |
self.value = value | |
self.encrypted = encrypted | |
self.encryptedValue = "" | |
} | |
func encrypt() { | |
if value is LosslessStringConvertible, let value = value as? LosslessStringConvertible { | |
self.encryptedValue = value.description | |
} else { | |
do { | |
let object = try JSONEncoder().encode(value) | |
// Do actual encryption and get the signature back | |
if let string = String(data: object, encoding: .utf8) { | |
encryptedValue = string | |
} else { | |
print("not a valid UTF-8 sequence") | |
} | |
} catch{ | |
print("Encoding failed") | |
} | |
} | |
} | |
func decrypt() { | |
if value is LosslessStringConvertible { | |
print("It's going to come here instead of in the extension decrypt") // Be LosslessStringConvertible conforms to Codable | |
} else { | |
do { | |
let data : [UInt8] = [UInt8](self.encryptedValue.utf8) | |
// Do actual decryption and get the data back | |
let object = try JSONDecoder().decode(T.self, from: Data(data)) | |
self.value = object | |
} catch{ | |
print("Decoding failed") | |
} | |
} | |
} | |
} | |
extension EncryptableProperty where T: LosslessStringConvertible { | |
func decrypt() { | |
guard let convertedValue = T(self.encryptedValue) else { | |
return | |
} | |
self.value = convertedValue | |
} | |
} | |
protocol EncryptableObject { | |
func encryptObject() | |
func decryptObject() | |
} | |
struct Test: EncryptableObject, Identifiable { | |
public let testInt: EncryptableProperty<Array<String>> | |
var uuid: String | |
init(uuid: String = UUID().uuidString) { | |
self.testInt = EncryptableProperty<Array<String>>(value: ["one", "two"], encrypted: true) | |
self.uuid = uuid | |
} | |
func encryptObject() { | |
print("\nEncryption happens") | |
Mirror(reflecting: self) | |
.children | |
.forEach { (property) in | |
if let encryptableValue = property.value as? Encryptable { | |
encryptableValue.encrypt() | |
} | |
} | |
} | |
func decryptObject() { | |
print("\nDecryption happens") | |
Mirror(reflecting: self) | |
.children | |
.forEach { (property) in | |
if let encryptableValue = property.value as? Encryptable { | |
encryptableValue.decrypt() | |
} | |
} | |
} | |
} | |
let test = Test() | |
print("Value= \(test.testInt.value) EncryptedValue= \(test.testInt.encryptedValue)") | |
test.encryptObject() | |
print("Value= \(test.testInt.value) EncryptedValue= \(test.testInt.encryptedValue)") | |
print("\nDecrypted value gets updated") | |
test.testInt.encryptedValue = #"["sir", "yannis"]"# | |
print("Value= \(test.testInt.value) EncryptedValue= \(test.testInt.encryptedValue)") | |
test.decryptObject() | |
print("Value= \(test.testInt.value) EncryptedValue= \(test.testInt.encryptedValue)") | |
struct Test2: EncryptableObject, Identifiable { | |
public let testString: EncryptableProperty<String> | |
public let testInt: EncryptableProperty<Int> | |
var uuid: String | |
init(uuid: String = UUID().uuidString) { | |
self.testString = EncryptableProperty<String>(value: "Blockstack", encrypted: true) | |
self.testInt = EncryptableProperty<Int>(value: 5, encrypted: true) | |
self.uuid = uuid | |
} | |
func encryptObject() { | |
print("\nEncryption happens") | |
Mirror(reflecting: self) | |
.children | |
.forEach { (property) in | |
if let encryptableValue = property.value as? Encryptable { | |
encryptableValue.encrypt() | |
} | |
} | |
} | |
func decryptObject() { | |
print("\nDecryption happens") | |
Mirror(reflecting: self) | |
.children | |
.forEach { (property) in | |
if let encryptableValue = property.value as? Encryptable { | |
encryptableValue.decrypt() | |
} | |
} | |
} | |
} | |
let test2 = Test2() | |
print("Value= \(test2.testInt.value) EncryptedValue= \(test2.testInt.encryptedValue)") | |
test2.encryptObject() | |
print("Value= \(test2.testInt.value) EncryptedValue= \(test2.testInt.encryptedValue)") | |
print("\nDecrypted value gets updated") | |
test2.testInt.encryptedValue = "6" | |
print("Value= \(test2.testInt.value) EncryptedValue= \(test2.testInt.encryptedValue)") | |
test2.decryptObject() | |
print("Value= \(test2.testInt.value) EncryptedValue= \(test2.testInt.encryptedValue)") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment