Skip to content

Commit c987348

Browse files
authored
Merge pull request mouredev#2465 from blackriper/main
Reto#12-swift
2 parents 015ad94 + 49f190d commit c987348

File tree

1 file changed

+290
-0
lines changed

1 file changed

+290
-0
lines changed
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
import Foundation
2+
import XMLCoder
3+
4+
/*
5+
Al proceso de convertir un objeto swift a un formato json o Xml
6+
se le conoce como serialización.
7+
8+
anteriormente se usaba la opcion JSONSerialization.dataWithJSONObject para serializar un objeto swift
9+
pero desde swift 4.0 se creo un protocolo Codable para serializar un objeto swift.
10+
11+
Codable es una composición de dos protocolos: Encodable y Decodable
12+
13+
Encondable: Permite serializar un objeto swift a un formato json o Xml
14+
Decodable: Permite deserializar un objeto json o Xml a un objeto swift
15+
16+
codable por defecto no soporta xml por lo cual hay que agregar una libreria para ello
17+
https://github.com/CoreOffice/XMLCoder
18+
19+
*/
20+
struct Person:Codable{
21+
let name:String
22+
let age:Int
23+
let birthDate:String
24+
let programmingLanguage:[String]
25+
}
26+
27+
28+
func exampleWorkingWithJson(){
29+
let fileManager=FileManager.default
30+
let encoder=JSONEncoder()
31+
encoder.outputFormatting = .prettyPrinted
32+
33+
// crear fichero
34+
let person=Person(name:"Rodolfo",age: 29,birthDate: "20/05/1994",programmingLanguage: ["swift","kotlin","go","python","typescript","java"])
35+
guard let encoded = try? encoder.encode(person)else{
36+
print("error to encode ")
37+
return
38+
}
39+
fileManager.createFile(atPath: "/home/blackriper/Descargas/person.json", contents:encoded, attributes: nil)
40+
41+
// leer fichero
42+
if let jsonData=fileManager.contents(atPath: "/home/blackriper/Descargas/person.json"){
43+
guard let decoded = try? JSONDecoder().decode(Person.self, from: jsonData)else{
44+
print("error to decode")
45+
return
46+
}
47+
let gretting="""
48+
Hello my name is \(decoded.name) and I am \(decoded.age) years old.
49+
I was born on \(decoded.birthDate) and
50+
I am learning \(decoded.programmingLanguage)
51+
"""
52+
print(gretting)
53+
}
54+
55+
// borrar fichero
56+
do{
57+
try fileManager.removeItem(atPath: "/home/blackriper/Descargas/person.json")
58+
}catch{
59+
print("error to delete")
60+
}
61+
62+
}
63+
64+
exampleWorkingWithJson()
65+
66+
func exampleWorkingWithXml(){
67+
let fileManager=FileManager.default
68+
let person=Person(name:"Rodolfo",age: 29,birthDate: "20/05/1994",programmingLanguage: ["swift","kotlin","go","python","typescript","java"])
69+
70+
// crear fichero
71+
if let xmlDoc = try? XMLEncoder().encode(person,withRootKey: "person") {
72+
fileManager.createFile(atPath: "/home/blackriper/Descargas/person.xml", contents:xmlDoc, attributes: nil)
73+
}
74+
75+
// leer fichero
76+
if let xmlData=fileManager.contents(atPath: "/home/blackriper/Descargas/person.xml"){
77+
guard let decoded = try? XMLDecoder().decode(Person.self, from: xmlData)else{
78+
print("error to decode")
79+
return
80+
}
81+
let gretting="""
82+
Hello my name is \(decoded.name) and I am \(decoded.age) years old.
83+
I was born on \(decoded.birthDate) and
84+
I am learning \(decoded.programmingLanguage)
85+
"""
86+
print(gretting)
87+
88+
}
89+
90+
// borrar fichero
91+
do{
92+
try fileManager.removeItem(atPath: "/home/blackriper/Descargas/person.xml")
93+
}catch{
94+
print("error to delete")
95+
}
96+
}
97+
98+
exampleWorkingWithXml()
99+
100+
// ejercicio extra
101+
102+
struct Product:Codable {
103+
var name: String
104+
var cantity: Int
105+
var price: Int
106+
}
107+
108+
enum Formats {
109+
case xml
110+
case json
111+
}
112+
113+
struct FileOperations{
114+
let path: String
115+
private let fileManager = FileManager.default
116+
117+
118+
func createFile(_ contents: Data?) {
119+
fileManager.createFile(atPath:self.path,contents: contents)
120+
}
121+
122+
func readFile(format: Formats) {
123+
guard let data = fileManager.contents(atPath: self.path) else {
124+
print("File not found")
125+
return
126+
}
127+
switch format{
128+
case .xml:
129+
if let xmlDoc = try? XMLDecoder().decode([Product].self, from: data) {
130+
xmlDoc.forEach{ product in
131+
print("\(product.name) | \(product.cantity) | \(product.price) | \(product.price*product.cantity)")
132+
}
133+
134+
}
135+
136+
case .json:
137+
if let jsonData = try? JSONDecoder().decode([Product].self, from: data) {
138+
jsonData.forEach{ product in
139+
print("\(product.name) | \(product.cantity) | \(product.price) | \(product.price*product.cantity)")
140+
}
141+
}
142+
}
143+
}
144+
145+
func deleteFile() {
146+
do {
147+
try fileManager.removeItem(atPath: self.path)
148+
}catch let error{
149+
print("Error deleting file: \(error)")
150+
}
151+
}
152+
}
153+
154+
155+
class Cart {
156+
private var products: [Product] = []
157+
let fileManager:FileOperations
158+
let format:Formats
159+
160+
init(src:String,fmt:Formats) {
161+
self.fileManager = FileOperations(path: src)
162+
self.format = fmt
163+
}
164+
165+
func addProduct(product: Product) {
166+
products.append(product)
167+
self.saveFile()
168+
169+
}
170+
func removeProduct(name:String) {
171+
products.removeAll(where: { $0.name == name.uppercased() })
172+
self.saveFile()
173+
}
174+
175+
func updateProduct(name:String){
176+
guard var product=products.first(where: { $0.name == name.uppercased() })else {
177+
print("Product not found")
178+
return
179+
}
180+
print("update name \(product.name):")
181+
let newName=readLine() ?? product.name
182+
183+
print("update cantity \(product.cantity):")
184+
let newCantity = Int(readLine() ?? "\(product.cantity)")
185+
186+
print("update price \(product.price):")
187+
let newPrice = Int(readLine() ?? "\(product.price)")
188+
189+
product.name=newName.uppercased()
190+
product.cantity=newCantity ?? product.cantity
191+
product.price=newPrice ?? product.price
192+
saveFile()
193+
}
194+
195+
func listProducts(){
196+
let header="""
197+
Name | cantity | Price
198+
"""
199+
print(header)
200+
fileManager.readFile(format: format)
201+
}
202+
203+
func totalSold(){
204+
let total=products.reduce(0) { $0 + $1.price }
205+
let header="""
206+
Name | cantity | Price | Total Product
207+
"""
208+
print(header)
209+
products.forEach { product in
210+
print("\(product.name) | \(product.cantity) | \(product.price) | \(product.price*product.cantity)")
211+
}
212+
print("Total sold: \(total)")
213+
}
214+
215+
216+
func exitApp(){
217+
fileManager.deleteFile()
218+
}
219+
220+
private func saveFile() {
221+
switch format {
222+
case .xml:
223+
if let xmlDoc = try? XMLEncoder().encode(products,withRootKey: "products") {
224+
fileManager.createFile(xmlDoc)
225+
}
226+
case .json:
227+
if let jsonData = try? JSONEncoder().encode(products) {
228+
fileManager.createFile(jsonData)
229+
}
230+
}
231+
}
232+
}
233+
234+
235+
236+
237+
func marketPlace(format:Formats) {
238+
let src = switch format {
239+
case .xml:
240+
"/home/blackriper/Descargas/products.xml"
241+
case .json:
242+
"/home/blackriper/Descargas/products.json"
243+
}
244+
let cart = Cart(src: src, fmt: format)
245+
marketloop:
246+
while true {
247+
print("1. Add product")
248+
print("2. Remove product")
249+
print("3. Update product")
250+
print("4. List products")
251+
print("5. Total sold")
252+
print("6. Exit")
253+
let option = Int(readLine() ?? "0") ?? 0
254+
switch option {
255+
case 1:
256+
print("Name of product:")
257+
let name = readLine() ?? ""
258+
print("Cantity:")
259+
let cantity = Int(readLine() ?? "0") ?? 0
260+
print("Price:")
261+
let price = Int(readLine() ?? "0") ?? 0
262+
let product=Product(name: name.uppercased(), cantity: cantity, price: price)
263+
cart.addProduct(product: product)
264+
265+
case 2:
266+
print("Name of product:")
267+
let name = readLine() ?? ""
268+
cart.removeProduct(name: name.uppercased())
269+
270+
case 3:
271+
print("Name of product:")
272+
let name = readLine() ?? ""
273+
cart.updateProduct(name: name.uppercased())
274+
case 4:
275+
cart.listProducts()
276+
277+
case 5:
278+
cart.totalSold()
279+
280+
case 6:
281+
cart.exitApp()
282+
break marketloop
283+
284+
default:
285+
print("Invalid option")
286+
}
287+
}
288+
}
289+
290+
marketPlace(format: Formats.json)

0 commit comments

Comments
 (0)