BLOG main image
분류 전체보기 (92)
Cocoa Touch (11)
Cocoa (10)
Objective-C (13)
Swift (6)
Development (11)
Tools (11)
Books (7)
etc (21)
Application release (1)
Document Project (1)
105,799 Visitors up to today!
Today 2 hit, Yesterday 2 hit
daisy rss
tistory 티스토리 가입하기!
2015. 6. 18. 18:09

Objective-C를 처음 접했을 때 가장 마음에 드는 것 중 하나가 collection에 저장될 수 있는 객체의 타입이 달라도 된다는 것이었다. 하나의 array안에 NSString과 NSNumber를 같이 넣는 다는 것은 C++을 주로 사용하던 나에게는 정말 충격적인 일이었다.


세월이 흘러 어느덧 Swift라는 새로운 언어에 익숙해져야 하는 순간이 왔다. 첫 인상부터 별로였던지라 (genertic이 첫 인상을 나쁘게 하는데 일조했다.) 마지못해서 슬슬 보고는 있는데... 역시 오늘 완전 사람 속을 뒤집어 놓는 케이스를 만났다.


JSON 데이터를 파싱하는 NSJSONSerialization 클래스를 한번 보자.


+ (id nullable)JSONObjectWithData:(NSData * nonnull)data
                          options:(NSJSONReadingOptions)opt
                            error:(NSError * nullable * nullable)error // nullable은 도대체 또 뭐냐


위는 Objective-C의 경우이다. 리턴 타입이 id라고 되어있지만 우리는 경험상 이것이 NSArray거나 NSDictionary임을 알고 있다.

그냥 안에든 객체를 id로 다루면 아무 문제없이 깔끔하게 원하는 작업을 수행할 수 있다.


하지만...


다음은 Swift이다 . Objective-C에서 id는 즉 Swift에서 AnyObject. 뭐 이 정도는 봐줄만 하다.


class func JSONObjectWithData(_ data: NSData,
                      options opt: NSJSONReadingOptions) throws -> AnyObject


가지고 있는 JSON이 Dictionary라는 사실은 알고 있다. 그래서 다음과 같은 방법으로 casting을 시도했다.


let dict = jsonObject as? [AnyObject: AnyObject]

let dict = jsonObject as? [AnyObject: Any]


Objective-C에서는 key는 NSCopying만 지원하면 된다고 규정하고 있고 value는 id이면 뭐든 가능하다.

첫 시도는 가당찮게 에러를 보는 것으로 끝났다. 그럼 어떻게 하면 되지?


let dict = jsonObject as? [NSCopying: AnyObject]


위는 어처구니 없는 다음 시도였으나 될리가 없다. 안될 것이라고 생각하고 쓴 멍청한 코드다.

잠시 머리를 돌려본다. Dictionary의 key 조건은 hashable이다. 이렇게 해본다.


let dict = jsonObject as? [HashableAnyObject]


역시 에러다. 이쯤되면 조금 짜증이 나기 시작한다. 다시 다음과 같은 방법들도 써본다


let dict = jsonObject as? Dictionary<AnyObject, AnyObject>

let dict = jsonObject asDictionary<HashableAnyObject>

let dict = jsonObject asDictionary<AnyObjectAnyObject?>


역시 안된다. 이쯤되면 완전 짜증이 머리 끝까지 솟구친다.

키를 string으로 제한시켜본다.


let dict = jsonObject as? Dictionary<String, AnyObject>

let dict = jsonObject as? [StringAnyObject]


아... 이제 된다. 키가 String이 아닌 dictionary나 가변적인 경우는 어떡하지? 하지만 이런 고민은 잠시 접어두자. 된것만 해도 어디냐며...

여기에 키의 타입을 바꾸거나 value의 타입을 바꾸면 또 안된다. 아, value를 AnyObject?로 해도 안됨을 주의!


이 사단은 별로 유용하지도 않은 generic이라는 이상한걸 들고와서 벌어진 일이다.

Objective-C를 사용하던 사람입장에서는 Swift의 casting과 generic이 얼마나 사람을 열받게  만드는지 한번 느껴보시기 바란다.

yagom | 2015.06.19 01:53 신고 | PERMALINK | EDIT/DEL | REPLY
저는 그래서 JSON 파싱은 Objective-C로 해요...^^; 마음속에서 솟구쳐 오르는 저 무언가를 참기는 힘들 것 같아요...ㅎㅎ
maccrazy | 2015.06.19 09:40 신고 | PERMALINK | EDIT/DEL
:) 그런 방법을 쓰시는군요.
저는 한 프로젝트에 여러 언어를 섞어쓰는 것을 좀 싫어해서 swift로 하면 최대한 swift로 하고 있는데 계속 마음속에서 뭔가가 솟구치는군요. ㅋㅋ
하지만 뭐 어쩌겠습니다. 돌이키기엔... 애플이 그리로 가겠다는데 방법이 없네요.
Name
Password
Homepage
Secret