Daily 2018-12-27
TIL
swift
오전: 강의
오후 : 제이슨파서
//
// Parser.swift
// JSONParser
//
// Created by Elena on 27/12/2018.
// Copyright © 2018 elena. All rights reserved.
//
import Foundation
//JSON 출력을 위한 Protocol
protocol JSONResult {
var resultDataPrint: String { get }
var parserResultPrint: String { get }
}
extension String {
func splitByComma() -> [String] {
return self.split(separator: ",").map({String($0)})
}
func removeBothFirstAndLast() -> String {
return String(self.dropFirst().dropLast())
}
func splitByColon() -> [String] {
return self.split(separator: ":").map({String($0)})
}
}
struct Parser{
// 입력받은 데이터를 분석해서 반환
static func DivideData(from data: String) -> JSONData? {
guard isDivideData(from: data) else {
return nil
}
// 대괄호가 나오면 Array로 괄호 갯수만 세서 출력하는걸로
if data.first?.description == "[" {
return parseBracket(data)
}
// 객체일 경우 파싱할수 있도록
let datasJSON = parserForm(data)
var parseJSONData = parseDatas(datasJSON)
parseJSONData?.datas = data.splitByComma()
return parseJSONData
}
// 열린괄호랑 닫힌 괄호랑 같은지 판별한다음 갯수를 저장해서 반환
private static func parseBracket(_ data: String) -> JSONData? {
var resultData: JSONData = JSONData()
var leftBracket = 0
var rightBracket = 0
leftBracket = data.components(separatedBy: "{").count
rightBracket = data.components(separatedBy: "}").count
if leftBracket != rightBracket {
return nil
}
resultData.objectCount = leftBracket-1
return resultData
}
// Form 만들기
private static func parserForm(_ data: String) -> [String:String]{
var dicFormData = [String:String]()
var dataSplitByComma: [String] = data.splitByComma()
for index in 0..<dataSplitByComma.count {
// 괄호를 일단 지우고 데이터를 딕셔너리로 파싱을 한다.
if dataSplitByComma[index].first?.description == "{" {
let bracket = dataSplitByComma[index].dropFirst()
dataSplitByComma[index] = String(bracket)
}else if dataSplitByComma[index].last?.description == "}" {
let bracket = dataSplitByComma[index].dropLast()
dataSplitByComma[index] = String(bracket)
}
var dataSplitByColon = dataSplitByComma[index].splitByColon()
dicFormData.updateValue(dataSplitByColon[1], forKey: dataSplitByColon[0])
}
return dicFormData
}
// 딕셔너리를 받아서 value있는 값을 파싱한다.
private static func parseDatas(_ data: [String:String]) -> JSONData?{
var resultData: JSONData = JSONData()
for (_,value) in data {
let value = value.trimmingCharacters(in: .whitespacesAndNewlines)
if isStringType(value) {
resultData.dataString.append(value)
}else if isBoolType(value) {
guard let isData = Bool(value) else { break }
resultData.dataBool.append(isData)
}else if isNumber(value) && isValidCharacter(value) {
guard let isData = Int(value) else{ break }
resultData.dataInt.append(isData)
}
}
return resultData
}
// 입력받은 데이터에 괄호가 있는지 체크
static func isDivideData(from data: String) -> Bool {
if (data.first?.description) == "{" , data.last?.description == "}" {
return true
}
guard ((data.first?.description) == "["), ((data.last?.description) == "]") else {
return false
}
return true
}
private static func isNumber (_ popData : String) -> Bool {
return popData.components(separatedBy: CharacterSet.decimalDigits).count != 0
}
private static func isValidCharacter(_ popData : String) -> Bool {
let validCharacter = CharacterSet.init(charactersIn: "0123456789")
return (popData.rangeOfCharacter(from: validCharacter.inverted) == nil)
}
private static func isStringType (_ popData : String) -> Bool {
return popData.first == "\"" && popData.last == "\""
}
private static func isBoolType (_ popData : String) -> Bool {
return popData.contains("true") || popData.contains("false")
}
}
Written on December 27, 2018