JSON.swift 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import Foundation
  2. protocol JSON: Codable {
  3. var rawJSON: String { get }
  4. init?(from: String)
  5. }
  6. extension JSON {
  7. var rawJSON: RawJSON {
  8. let encoder = JSONEncoder()
  9. encoder.outputFormatting = .prettyPrinted
  10. encoder.dateEncodingStrategy = .iso8601
  11. return String(data: try! encoder.encode(self), encoding: .utf8)!
  12. }
  13. init?(from: String) {
  14. let decoder = JSONDecoder()
  15. decoder.dateDecodingStrategy = .iso8601
  16. guard let data = from.data(using: .utf8),
  17. let object = try? decoder.decode(Self.self, from: data)
  18. else {
  19. return nil
  20. }
  21. self = object
  22. }
  23. }
  24. extension String: JSON {
  25. var rawJSON: String { self }
  26. init?(from: String) { self = from }
  27. }
  28. extension Double: JSON {}
  29. extension Int: JSON {}
  30. extension Bool: JSON {}
  31. extension Decimal: JSON {}
  32. extension Date: JSON {
  33. init?(from: String) {
  34. let dateFormatter = Formatter.iso8601withFractionalSeconds
  35. let string = from.replacingOccurrences(of: "\"", with: "")
  36. if let date = dateFormatter.date(from: string) {
  37. self = date
  38. } else {
  39. return nil
  40. }
  41. }
  42. }
  43. typealias RawJSON = String
  44. extension RawJSON {
  45. static let null = "null"
  46. }
  47. extension Array: JSON where Element: JSON {}
  48. extension Dictionary: JSON where Key: JSON, Value: JSON {}
  49. enum JSONCoding {
  50. static var encoder: JSONEncoder {
  51. let encoder = JSONEncoder()
  52. encoder.outputFormatting = .prettyPrinted
  53. encoder.dateEncodingStrategy = .customISO8601
  54. return encoder
  55. }
  56. static var decoder: JSONDecoder {
  57. let decoder = JSONDecoder()
  58. decoder.dateDecodingStrategy = .customISO8601
  59. return decoder
  60. }
  61. }