XML이란..?
Extensible Markup Language의 종류중 대표적인 언어에요
Markup Language 란?
태그, 등을 이용하여 문서나 데이터의 구조를 명기하는 언어의 한 가지라고 사전에 나오네요
<p>, <br>, <div> 이런 태그들 본적 있으시죠?? 그런 태그를 사용한 거에요
대표적으로 HTML, XML언어가 있죠
HTML 문자열로 응답을 받을 때 파싱받아서 앱에 적용 하고 싶은경우가 생길 수 있어요
RSS(Rich Site Summary)가 대표적인 예로 있겠네요!
RSS는 뉴스나 블로그 사이트에서 주로 사용하는 콘텐츠 표현 방식 이라고해요
아무튼!! 이러한 XML로 이루어진 응답을 파싱해보는 방법에 대해서 알아보려고 해요
예시로 구글뉴스의 RSS주소를 가져왔어요
아래의 주소를 치면 사진과같이 응답이 와요
https://news.google.com/rss?hl=ko&gl=KR&ceid=KR:ko
이러한 데이터중에서
원하는 데이터가 <title>태그에 있을 수 도있고, <link>태그에 있을 수 도있고
태그로 둘러쌓인 문자열만 골라서 가져와야겠죠??
이 작업을 편하게 할 수 있도록 Xcode에서 지원해주는게
바로 XMLParser이에요
제일 기본적인 XMLParser사용법을 알아볼게요
var parser: XMLParser
guard let url = URLComponents(string: rssURL)?.url else {
return
}
parser = XMLParser(contentsOf: url)
parser.delegate = self
parser.parse()
URL타입의 매개변수를 넣어줘서 XMLParser객체를 생성하고
parse() 를 통해서
넣어준 URL의 응답을 파싱하기 시작해요
파싱받는 값은
XMLParserDelegate 에 로직을 구현해야해요
// 태그의 시작
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)
// 에러시, abortParsing()사용시
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error)
<title>타이틀입니다</title>
이런 XML이 있다면
didStartElement elementName => title
didEndElement elementName => title
foundCharacters string => 타이틀입니다
이렇게 값을 받을 수 있어요
느낌이 오시나요??!
그리고 파싱을 그만두고싶다!?
abortParsing() 을 통해서 멈추게 할 수 있어요
이 함수를 실행 시키면
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) delegate함수를 통해서
정보가 전달된다고 하네요
문자열을 가져올 때
주의할점이 있어요
xml태그끝에 빈칸을 인식하기때문에
데이터가 아닌 빈배열저장 되는 문제가 발생해요
(예시)
<country>한국</country>
에서 한국과 </country>뒤의 공백문자를인식해요
해결방법으로는
Bool형 변수 트리거 방식
혹은
trimmingCharacters(in: .whitespacesAndNewlines) 을 이용해서 앞뒤 공백을 제거할 수도 있어요
원하는 태그의 문자열을 가져오는 코드를 간단하게 작성해 볼게요
간략하게 우선 말로 설명하자면
item태그 안에 있는 title태그의 문자열을 가져올거에요
<item>
<title> ... </title>
</item>
<item>
<title> ... </title>
</item>
으로 이루어진 형식이구요!!
item태그가 시작되면
Rss객체를 만들어주고
title의 문자열을 넣어준뒤
item태그가 끝나면
배열에 추가해줄거에요
enum TagType {
case title, none
}
class Rss {
var title: String
}
var isLock = false
var tagType: TagType = .none
var tempRssModel: Rss?
var rssList: [Rss] = []
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
if elementName == "item" {
isLock = true
tempRssModel = Rss()
} else if elementName == "title" {
tagType = .title
} else {
tagType = .none
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "item" {
guard let tempRssModel = tempRssModel else {
return
}
rssList.append(tempRssModel)
isLock = false
} else if elementName == "channel" { // xml의 마지막태그 - channel
parser.abortParsing()
rssTableView.reloadData()
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
if isLock {
switch tagType {
case .title:
let parseString = string.trimmingCharacters(in: .whitespacesAndNewlines)
tempRssModel.title = parseString
}
}
}
하다가 고민할 점이 생겼어요
XML파싱할 때 link에 있는 URL로 다시 XML파싱을 받아서 본문을 발췌해 오는 기능을 구현하는데 있어서
양이 많다보니 버벅거리는 현상이 발생했어요
저는 각 Cell안에서 link로 다시 XML을 파싱하도록 구현했는데 버벅이는 현상을 잡지 못해서
좋지 않은 방법 같다고 생각했어요
XML의 양이 많이질때의 문제를 생각해볼 필요가 있을거 같아요
'iyOmSd > Title: Swift' 카테고리의 다른 글
[Swift] - Apple Login (1/2) (0) | 2020.04.14 |
---|---|
[Swift] - MultiPart통신 (멀티파트 이미지업로드) (2) | 2020.04.11 |
[Swift] Font Custom ( 원하는 글자만 폰트적용하기 ) (0) | 2020.03.01 |
[Swift] APNS - Apple Push Notification (1) | 2020.02.28 |
[Swift] Socket.IO를 이용한 소켓통신 채팅앱 만들어보기 (3/3) (4) | 2019.12.17 |