项目作者: pkh0225

项目描述 :
👻 Easy Parsing JSON to Swift
高级语言: Swift
项目地址: git://github.com/pkh0225/PKHJsonParser.git
创建时间: 2018-08-10T13:57:52Z
项目社区:https://github.com/pkh0225/PKHJsonParser

开源协议:

下载


PKHParser

👻 Easy Parsing JSON to Swift

SwiftPM compatibleLicense: MIT

목표

클라이언트 개발 시 json 파싱 과정에서 생기는 실수를 방지하고 불필요한 반복 작업을 줄여 파싱 과정을 자동화


Test

  1. let jsonString = """
  2. {"widget": {
  3. "testDebug": "on",
  4. "stringArray": ["a","b","c"],
  5. "windowT": {
  6. "title": "Sample Konfabulator Widget",
  7. "name": "main_window",
  8. "width": 500,
  9. "height": 500
  10. },
  11. "testImage": {
  12. "src": "Images/Sun.png",
  13. "name": "sun1",
  14. "hOffset": 250,
  15. "vOffset": 250,
  16. "alignment": "center"
  17. },
  18. "testText": {
  19. "data": "Click Here",
  20. "size": 36,
  21. "style": "bold",
  22. "name": "text1",
  23. "hOffset": 250,
  24. "vOffset": 100,
  25. "alignment": "center",
  26. "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
  27. }
  28. },
  29. "windowsDataList": [{
  30. "title": "Sample Konfabulator Widget",
  31. "name": "main_window",
  32. "width": 500,
  33. "height": 500
  34. },
  35. {
  36. "title": "Sample Konfabulator Widget",
  37. "name": "main_window",
  38. "width": 500,
  39. "height": 500
  40. },
  41. {
  42. "title": "Sample Konfabulator Widget",
  43. "name": "main_window",
  44. "width": 500,
  45. "height": 500
  46. }],
  47. "size": 36,
  48. "style": "bold",
  49. "name": "text1",
  50. "hOffset": 250,
  51. "vOffset": 100,
  52. "alignment": "center",
  53. "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
  54. }
  55. """
  56. let dic = jsonString.toDictionary()
  57. let obj = Test(map: dic)
  58. print(obj)
  59. Test.parser(map: dic!) { (obj: Test) in
  60. print(obj)
  61. }
  62. 🎃 RESULT
  63. ======== Test ========
  64. windowsList: ---- Array(3) ----
  65. [0] ======== WindowsDataListItem ========
  66. name: main_window
  67. title: Sample Konfabulator Widget
  68. height: 500
  69. width: 500
  70. =======================================
  71. [1] ======== WindowsDataListItem ========
  72. name: main_window
  73. title: Sample Konfabulator Widget
  74. height: 500
  75. width: 500
  76. =======================================
  77. [2] ======== WindowsDataListItem ========
  78. name: main_window
  79. title: Sample Konfabulator Widget
  80. height: 500
  81. width: 500
  82. =======================================
  83. ---------------------------
  84. widgetData: ======== Widget ========
  85. stringArray: ---- Array(3) ----
  86. [0] a
  87. [1] b
  88. [2] c
  89. ---------------------------
  90. windowT: ======== WindowT ========
  91. name: main_window
  92. title: Sample Konfabulator Widget
  93. height: 500
  94. width: 500
  95. =======================================
  96. testImage: ======== TestImage ========
  97. alignment: center
  98. name: sun1
  99. src: Images/Sun.png
  100. hOffset: 250
  101. vOffset: 250
  102. =======================================
  103. testText: ======== TestText ========
  104. name: text1
  105. data: Click Here
  106. onMouseUp: sun1.opacity = (sun1.opacity / 100) * 90;
  107. alignment: center
  108. size: 36
  109. style: bold
  110. hOffset: 250
  111. vOffset: 100
  112. =======================================
  113. testDebug: on
  114. =======================================
  115. onMouseUp: sun1.opacity = (sun1.opacity / 100) * 90;
  116. name: text1
  117. alignment: center
  118. size: 36
  119. style: bold
  120. hOffset: 250
  121. vOffset: 100
  122. =======================================

Core Functions

  1. class Test : PKHParser {
  2. var widgetData: Widget?
  3. var windowsList = [WindowsDataListItem]()
  4. var style: String = ""
  5. var onMouseUp: String = ""
  6. var size: Int = 0
  7. var hOffset: Int = 0
  8. var vOffset: Int = 0
  9. var alignment: String = ""
  10. var name: String = ""
  11. // json key ans ivar Different
  12. override func getDataMap() -> [ParserMap]? {
  13. return [ParserMap(ivar: "windowsList", jsonKey: "windowsDataList"),
  14. ParserMap(ivar: "widgetData", jsonKey: "widget")]
  15. }
  16. override func beforeParsed(dic: [String : Any], anyData: Any?) {
  17. super.beforeParsed(dic: dic, anyData: anyData)
  18. // Parsering before
  19. }
  20. override func afterParsed(_ dic: [String : Any]) {
  21. super.afterParsed(dic)
  22. // Parsering after
  23. }
  24. }
  25. @objcMembers open class PKHParser: NSObject {
  26. public override init() {
  27. super.init()
  28. }
  29. required public init(map dic: [String: Any]?, anyData: Any? = nil, serializeKey: String? = nil) {
  30. super.init()
  31. guard let dic = dic else { return }
  32. self.beforeParsed(dic:dic, anyData:anyData)
  33. if let key = serializeKey, let dataDic = dic[key] as? [String: Any] {
  34. self.setSerialize(map: dataDic, anyData: anyData)
  35. self.afterParsed(dataDic)
  36. }
  37. else {
  38. self.setSerialize(map: dic, anyData: anyData)
  39. self.afterParsed(dic)
  40. }
  41. }
  42. open func getDataMap() -> [ParserMap]? { return nil }
  43. open func beforeParsed(dic: [String: Any], anyData: Any?) {}
  44. open func afterParsed(_ dic: [String: Any]) {}
  45. open func setSerialize(map dic: [String: Any], anyData: Any?) {
  46. let maps = self.getDataMap()
  47. let ivarList = self.ivarInfoList()
  48. for ivarItem in ivarList {
  49. var changeKey = ivarItem.label
  50. var parserMap: ParserMap?
  51. if let maps = maps {
  52. for pm in maps {
  53. if pm.ivar == ivarItem.label {
  54. parserMap = pm
  55. break;
  56. }
  57. }
  58. }
  59. if parserMap != nil && parserMap!.jsonKey != "" {
  60. changeKey = parserMap!.jsonKey
  61. }
  62. // print(changeKey)
  63. guard let value = dic[changeKey] else { continue }
  64. guard value is NSNull == false else { continue }
  65. if ivarItem.classType == .array {
  66. guard let arrayValue = value as? [Any], arrayValue.count > 0 else { continue }
  67. guard let nsobjAbleType = ivarItem.subClassType as? PKHParser.Type else {
  68. fatalError("self : [\(String(describing: self))] label : \(ivarItem.label) \(String(describing: ivarItem.subClassType)) not NSObject" )
  69. continue
  70. }
  71. var array: [Any] = []
  72. array.reserveCapacity(arrayValue.count)
  73. for arraySubDic in arrayValue {
  74. if let dic = arraySubDic as? [String:Any] {
  75. let addObj = nsobjAbleType.init(map: dic, anyData: anyData)
  76. array.append(addObj)
  77. }
  78. }
  79. self.setValue(array, forKey: ivarItem.label)
  80. }
  81. else if ivarItem.classType == .dictionary {
  82. guard let nsobjAbleType = ivarItem.subClassType as? PKHParser.Type else {
  83. fatalError("self : [\(String(describing: self))] label : \(ivarItem.label) \(String(describing: ivarItem.subClassType)) not NSObject" )
  84. continue
  85. }
  86. if let dic = value as? [String:Any], dic.keys.count > 0 {
  87. let addObj = nsobjAbleType.init(map: dic, anyData: anyData)
  88. self.setValue(addObj, forKey: ivarItem.label)
  89. }
  90. }
  91. else if ivarItem.classType == .string {
  92. if value is String {
  93. self.setValue(value, forKey: ivarItem.label)
  94. }
  95. else {
  96. self.setValue("\(value)", forKey: ivarItem.label)
  97. }
  98. }
  99. else if ivarItem.classType == .int {
  100. if value is Int {
  101. self.setValue(value, forKey: ivarItem.label)
  102. }
  103. else {
  104. let text = "\(value)"
  105. self.setValue(text.toInt(), forKey: ivarItem.label)
  106. }
  107. }
  108. else if ivarItem.classType == .float {
  109. if value is Float {
  110. self.setValue(value, forKey: ivarItem.label)
  111. }
  112. else {
  113. let text = "\(value)"
  114. self.setValue(text.toFloat(), forKey: ivarItem.label)
  115. }
  116. }
  117. else if ivarItem.classType == .bool {
  118. if value is Bool {
  119. self.setValue(value, forKey: ivarItem.label)
  120. }
  121. else {
  122. let text = "\(value)"
  123. self.setValue(text.toBool(), forKey: ivarItem.label)
  124. }
  125. }
  126. else {
  127. self.setValue(value, forKey: ivarItem.label)
  128. }
  129. }
  130. }
  131. open override var description: String {
  132. return getDescription()
  133. }
  134. private enum descriptionType {
  135. case `default`
  136. case array
  137. case subInstance
  138. }
  139. private func getDescription(_ tapCount: UInt = 0, _ addType: descriptionType = .default) -> String {
  140. var tap = ""
  141. for _ in 0...tapCount { tap += "\t" }
  142. var result: [String] = []
  143. let ivarList = self.toDictionary()
  144. result.reserveCapacity(ivarList.count)
  145. switch addType {
  146. case .default:
  147. result.append("\n\(tap)✏️ ======== \(self.className) ✏️ ========")
  148. case .array:
  149. result.append("⬇️ --- \(self.className) ⬇️ ---")
  150. case .subInstance:
  151. result.append("➡️ --- \(self.className) ➡️ ---")
  152. }
  153. for (key, value) in ivarList {
  154. // print("label: \(key), class: \(self.className) value: \(value)")
  155. if let arrayValue = value as? [Any] {
  156. result.append("\(key): ---- Array(\(arrayValue.count)) -------------------------------")
  157. for (idx,obj) in arrayValue.enumerated() {
  158. if checkObjectClass(obj) {
  159. result.append("[\(idx)] \(obj)")
  160. }
  161. else {
  162. if let subArray = obj as? [Any] {
  163. result.append("[\(idx)]---- SubArray(\(subArray.count)) ----")
  164. for case let (subIdx,subItem as PKHParser) in subArray.enumerated() {
  165. result.append("\t[\(subIdx)] \(subItem.getDescription(tapCount + 1, .array))")
  166. }
  167. result.append("---------------------------")
  168. }
  169. else if let objClass = obj as? PKHParser {
  170. result.append("[\(idx)] \(objClass.getDescription(tapCount + 1, .array))")
  171. }
  172. else {
  173. result.append("[\(idx)] \(String(describing: type(of: value))) ????????")
  174. // assertionFailure("\(String(describing: value)) not NSObject" )
  175. }
  176. }
  177. }
  178. if arrayValue.count > 0 {
  179. result.append("------------------------------------------------------")
  180. }
  181. }
  182. else if checkObjectClass(value as AnyObject) {
  183. result.append("\(key): \(value)")
  184. }
  185. else {
  186. if let objClass = value as? PKHParser {
  187. result.append("\(key): \(objClass.getDescription(tapCount + 1, .subInstance))")
  188. }
  189. else {
  190. result.append("\(key): \(String(describing: type(of: value))) ????????")
  191. // assertionFailure("\(String(describing: value)) not NSObject" )
  192. }
  193. }
  194. }
  195. switch addType {
  196. case .default:
  197. result.append("✏️ ================== \(self.className) ===================== ✏️")
  198. case .array, .subInstance:
  199. result.append("----------- \(self.className) -----------")
  200. }
  201. return result.joined(separator: "\n\(tap)")
  202. }
  203. }