2015년 1월 22일 목요일

NSScanner 기초​

NSScanner는 문자열(String, NSString)에서 값을 스캔하기 위한 클래스이다. 아래 공식 레퍼런스에는 Abstract Superclass 라고 소개되어 있긴 하지만 예상외로 별도로 구현할 필요 없이 그대로 써도 된다.

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSScanner_Class/

무슨 용도로 쓸 수 있을까는 매뉴얼의 메소드들을 잘 보면 아마도 감을 잡을 수 있지 않을까 생각된다.

NSScanner 인스턴스 생성

앞서 이야기 한 것 처럼 문자열을 기반으로 NSScanner 인스턴스를 생성 할 수 있다. 별도로 상속받아 구현한 형태가 아니라면 NSConcreteScanner 라는 타입 인스턴스로 생성된다.
import Foundation

let scanner = NSScanner(string: "String Value")
Objective-C의 경우 + scannerWithString: 같은 정적 메소드를 써서 인스턴스를 만드는 편이 더 편하겠다.

무엇을 스캔 할 것인가

일단 예제로 숫자로 구성된 문자열을 정수로 받아오는 코드를 만들어 보자.
let scanner = NSScanner(string: "10")
var value: Int32 = 0
scanner.scanInt(&value)
이 경우 value에는 10이 들어온다.

Int32 타입을 쓰는 건 위 scanInt의 파라미터가 Int32의 UnsafeMutablePointer를 요구하기 때문이다. 그나마 inout 정의식으로 레퍼런스를 넘겨주면 포인터 인스턴스를 만들어 줄 필요가 없으니 다행이다 =_=

다른 예제로 문자열로 구성된 16진수를 10진수 정수로 받아와 보자.
let scanner = NSScanner(string: "a02e")
var value: UInt32 = 0
scanner.scanHexInt(&value)

value
이 경우 value의 값은 41006이 들어온다.

이번에는 UInt32 타입이 쓰였는데, 일반적인 HEX 타입의 16진수 데이터는 unsigned (부호없는) 타입일테니까...

무시할 문자 설정

NSScanner의 charactersToBeSkipped 프로퍼티를 세팅하면 스캐너가 좀 더 원하는 데이터에 정확하게 접근 할 수 있도록 지원 할 수 있다. 예를 들어, “string 100 string” 이라는 문자열에서 scanInt 메소드를 호출 할 경우 무조건 리턴은 false가 되고 값이 스캔되지 않는다. 하지만 무시할 캐릭터셋으로 알파벳과 공백을 몽땅 넣어버리면 원하는 데이터를 뽑아 낼 수도 있다.

아래는 실제 예제이다.
let scanner = NSScanner(string: "I am 100 year old")
let ignoreChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "
scanner.charactersToBeSkipped = NSCharacterSet(charactersInString: ignoreChars)
var value = Int32(0)
scanner.scanInt(&value)

value
최종적으로 value에는 100이라는 값이 돌아온다.
물론 이런 예제의 코드는 이 보다 정규표현식으로 추출하는게 훨신 간단할 것 같기도 하다.

이 외에 scanLocation 등을 설정해서 스캔할 위치를 정하는 것 등도 가능하니 필요하다면 레퍼런스 문서를 뒤져보자.

댓글 없음 :