개발을 시작하는 이야기

04.XMLParser 02 본문

개발 이야기/우리동네 문화유산 :: JHeritage

04.XMLParser 02

Teiresias 2022. 3. 8. 18:40

XMLParserDelegate

extension OnboardingViewController: XMLParserDelegate {
    
    //XMLParser가 시작 태그(elementName)를 만나면 호출됨
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        
        if elementName == "sn" || elementName == "no" || elementName == "ccmaName" || elementName == "crltsnoNm" || elementName == "ccbaMnm1" || elementName == "ccbaMnm2" || elementName == "ccbaCtcdNm" || elementName == "ccsiName" || elementName == "ccbaAdmin" || elementName == "ccbaKdcd"  || elementName == "ccbaCtcd"  || elementName == "ccbaAsno"  || elementName == "ccbaCncl"  || elementName == "ccbaCpno"  || elementName == "longitude"  || elementName == "latitude" {
            self.key = elementName
        }
    }
    
    //태그 내부의 Data가 String으로 저장됨
    func parser(_ parser: XMLParser, foundCharacters string: String) {
        if self.key != nil {
            if self.key == "sn" {
                self.items.append([key: string])
            } else {
                self.items[ct][key] = string
            }
        }
        if key == "latitude" {
            ct = ct + 1
        }
    }
    
    //XMLParser가 종료 태그를 만나면 호출됨
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        self.key = nil
    }
    
    //XMLParser의 Error 처리
    func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
        print(parseError)
    }
    
    //XMLParser의 Error 처리
    func parser(_ parser: XMLParser, validationErrorOccurred validationError: Error) {
        print(validationError)
    }
    
    //XMLParser가 종료되면 호출됨 Parsing된 데이터를 Realm에 저장
    func parserDidEndDocument(_ parser: XMLParser) {
    	//items의 값을 Realm에 저장함
        saveRealm()
    }
}

여기서 중요한것?은 XMLParser를 통해 Pasing된 데이터를 Realm에 저장을 해서 사용하게 되었는데

문제는 이 데이터가 16,316개에 달한다는 거였다.

 

그래서 나는 일단 데이터를 저장하는데 걸리는 총 소요시간을 테스트 해보기로 했고 대략 13초라는 처참한 결과가 나왔다.

이 말은 사용자가 13초 동안은 앱을 정상적으로 사용할수 없다는 이야기가 되었다.

 

나는 여기서 선택을 해야 했는데,

  1. 이 과정을 동기화로 처리해서 13초동안 스플레시 화면에 머무르게 한 후 모든 데이터를 갖고 앱을 사용하게 하는것과
  2. 비동기화로 처리하고 앱을 사용할순 있지만 매번 조회할때마다 데이터가 하나둘 쌓여가는 방식

둘중에 하나를 선택해야 했다.

 

나는 이중에 1번을 선택했는데, 이유는 크게 두가지였다.

첫째로는 아직 비동기 처리에 대해서는 재대로 배우지 않았고 그냥 앱들을 사용하면서 '이런 기능이 있다' 정도로만 알고 있어서 이 기능을 구현하고자 한다면 머리가 아플것만 같았고,

두번째로는 앱의 데이터를 받다가 강제종료를 한 경우 데이터를 다시 받거나 이어받아야 하는데, 이 과정이 1번이 더 손쉬울것만 같았다.

 

XMLParser를 구현하는데 생각보다 오래걸렸다.

지금에야 돌이켜 생각해보면 하나하나 차근차근 진행되는거였는데 그때는 그런게 잘 안되었었다.

 

XMLParser를 다루면서 발생했던 모든 오류사항들을 모두 기록을 남겼어야 했는데 그 당시에는 이렇게 블로그를 운영할 계획 없이 노션으로만 남겨두었기 때문에 가장 골머리를 앓았던 하나를 공유하자면

Parser를 실행하고 실행되는 Data를 프린트 했을때, 하나씩 하나씩 읽어가는대로 모두 저장되어 가는것이였다.

 

위와 같은 경우는 이 Data를 불러오는 위치가 문제가 있었는데 Parsing되는 중간에 불러오는게 아닌,

'parserDidEndDocument' 에서 Parser가 끝난 뒤에 한번에 불러왔어야 했던것이 문제였다.