Swift5 Open API - xml parsing
공공 데이터를 이용한 코로나 open api를 통해 XML parsing에 대해서 알아볼 예정.
목차
1. 공공 데이터 open API 사용하는 방법
2. 전체 코드 및 사용법에 대한 설명
✅ 1. 공공 데이터 open API 사용하는 방법
1. 공공데이터 포털에 접속한다(https://www.data.go.kr/index.do)
2. 공공데이터 포털에서 [코로나]를 검색하고, 아래에 보이는 것을 신청
- 이미 신청완료한 상태라 마이페이지에서 확인한 모습!
- 신청 후 즉시 되는 건 아니고 약간의 시간이 흘러야 가능 (금방 처리)
3. 공공데이터 활용 지원센터를 클릭해서 상세보기
여기서 중요한 것은 [참고문서] 부분에서 워드 파일을 다운받아서 어떻게 사용되는지 직접 읽어보는 것이 중요.
4. 워드 파일을 열어본 후 - 문서를 내려 요청 메시지와 응답 메시지 부분을 확인하기
이걸 확인하는 이유는 우리가 요청했을 때 응답 메시지가 어떻게 내려오는 지 알아서 우리가 xml 파싱에서 구조를 활용할 수 있음.
요청 메시지 부분을 보면 인증키라고 있는데, 마이페이지에서 Encoding 부분에 내가 발급받은 키 부분을 넣어주면 된다.
마이페이지에서 - 오픈API - 개발계정 창에 들어가면 Encoding 부분이 나옴.
❗️API 요청시 필수 파라미터 부분을 누락하면 초기에는 요청이 가능하나 시간이 지나면 제대로 요청이 되지 않음.
✅ 2. 전체 코드 및 사용법에 대한 설명
//
// ViewController.swift
// Covid19AlarmApp
//
// Created by Hamlit Jason on 2021/07/20.
//
import UIKit
enum TagType {
case createDt
case deathCnt
case defCnt
case gubun
case gubunCn
case gubunEn
case incDec
case isolClearCnt
case isolIngCnt
case localOccCnt
case overFlowCnt
case qurRate
case seq
case stdDay
case none
}
struct item {
var createDt: String
var deathCnt: String
var defCnt: String
var gubun: String
var gubunCn: String
var gubunEn: String
var incDec: String
var isolClearCnt: String
var isolIngCnt: String
var localOccCnt: String
var overFlowCnt: String
var qurRate: String
var seq: String
var stdDay: String
init() {
createDt = ""
deathCnt = ""
defCnt = ""
gubun = ""
gubunCn = ""
gubunEn = ""
incDec = ""
isolClearCnt = ""
isolIngCnt = ""
localOccCnt = ""
overFlowCnt = ""
qurRate = ""
seq = ""
stdDay = ""
}
}
class ViewController : UIViewController, XMLParserDelegate {
var isLock = true
var tagType : TagType = .none
var tempModel : item?
var books: [item] = []
override func viewDidLoad() {
var parser : XMLParser
var yourKey = "" // 공공 데이터 포털에서 발급받은 개인 키
var url = URL(string: "http://openapi.data.go.kr/openapi/service/rest/Covid19/getCovid19SidoInfStateJson?serviceKey=\(yourKey)")
parser = XMLParser(contentsOf: url!)!
parser.delegate = self
parser.parse()
}
///MARK ::: LOGIC
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
// 태그의 시작
if elementName == "item" {
isLock = true
tempModel = item.init()
} else if elementName == "createDt" {
tagType = .createDt
} else if elementName == "deathCnt" {
tagType = .deathCnt
} else if elementName == "defCnt" {
tagType = .defCnt
} else if elementName == "gubun" {
tagType = .gubun
} else if elementName == "gubunCn" {
tagType = .gubunCn
} else if elementName == "gubunEn" {
tagType = .gubunEn
} else if elementName == "incDec" {
tagType = .incDec
} else if elementName == "isolClearCnt" {
tagType = .isolClearCnt
} else if elementName == "isolIngCnt" {
tagType = .isolIngCnt
} else if elementName == "localOccCnt" {
tagType = .localOccCnt
} else if elementName == "overFlowCnt" {
tagType = .overFlowCnt
} else if elementName == "qurRate" {
tagType = .qurRate
} else if elementName == "seq" {
tagType = .seq
} else if elementName == "stdDay" {
tagType = .stdDay
} else {
tagType = .none
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "item" {
guard let tempModel = tempModel else {
return
}
books.append(tempModel)
isLock = false
} else {
print("----- didEndElement (else)-----")
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
let parseString = string.trimmingCharacters(in: .whitespacesAndNewlines)
if isLock {
switch tagType {
case .createDt:
tempModel?.createDt = parseString
case .deathCnt:
tempModel?.deathCnt = parseString
case .defCnt:
tempModel?.defCnt = parseString
case .gubun:
tempModel?.gubun = parseString
case .gubunCn:
tempModel?.gubunCn = parseString
case .gubunEn:
tempModel?.gubunEn = parseString
case .incDec:
tempModel?.incDec = parseString
case .isolClearCnt:
tempModel?.isolClearCnt = parseString
case .isolIngCnt:
tempModel?.isolIngCnt = parseString
case .localOccCnt:
tempModel?.localOccCnt = parseString
case .overFlowCnt:
tempModel?.overFlowCnt = parseString
case .qurRate:
tempModel?.qurRate = parseString
case .seq:
tempModel?.seq = parseString
case .stdDay:
tempModel?.stdDay = parseString
case .none: break
}
}
}
@IBAction func tap(_ sender: Any) {
for i in 0..<books.count {
print(books[i])
}
print(books.count)
}
}
XML Parser는 크게 3가지 부분으로 나뉨
xml은 마크 다운 언어임으로 주로 이렇게 작성되어 있는데
<title> 안녕하세요 내용입니다 </title>
// 태그의 시작
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:])
// 태그의 끝
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
// 태그 안의 내용
func parser(_ parser: XMLParser, foundCharacters string: String)
이렇게 세가지 함수로 파싱을 진행 가능.
- 태그의 시작같은 경우에는 "title"이 호출되고
- 태그안의 내용에는 "안녕하세요 내용입니다"가 호출 돼
- 태그의 끝에는 "title"이 호출되게 된다.
✅ 향후 코드에는 API키를 보호해야 함으로 .gitignore로 파일을 관리하거나 백엔드에서 키를 받아와서 사용하는 방식을 채택한다면 더욱 안전한 프로그래밍을 할 수 있을 것으로 생각된다.
'deprecated > 코로나 알림(project-ios)' 카테고리의 다른 글
[iOS14] Swift5 alertDialog 함수로 만들어 사용하기 (0) | 2021.08.04 |
---|---|
[iOS14] ♋️ SplashView를 활용해 Alert 발생하기 (0) | 2021.08.02 |
[iOS14] 백그라운드에서 특정 시간 로컬 알림보내기 (0) | 2021.07.29 |
String HTMLTag 지우기 (정규표현식) (1) | 2021.07.29 |
Swift5 네이버 검색 API 사용하기(뉴스) (0) | 2021.07.26 |