레이블이 iOS인 게시물을 표시합니다. 모든 게시물 표시
레이블이 iOS인 게시물을 표시합니다. 모든 게시물 표시

2014년 11월 24일 월요일

iOS 8에서 framework 사용시 dyld: Library not loaded: ... Reason: image not found 문제

천신만고 끝에 framework 을 app에 집어 넣어서 빌드가 됐다.
하지만 이게 웬걸 바로 crash~

구글링 하는데 이 방법 저 방법이 난무했다. 크게 build setting에서 bundle에 집어넣는 것과 framework build시 installation directory를 '@executable_path/../Frameworks'로 바꿔주는 것 두가지가 있었는데 전자는 소용없었고 후자는 이미 하라는 데로 되어 있었다.
삽질하다 app package 내용을 살펴봤는데 뭔가 묘한 느낌이 나서 저기 저 사이에 '..'을 없애 보았다.

잘 되네.

부라보~ 와 이런~ 썩을 것들! 을 동시에 외치며 stackoverflow에 다시 가서 글 좀 싸지르려고 하는데 reputation 부족으로 댓글은 못쓰고 유심히 보니 apple developer forum link가 달려있네. 가서 보니 내가 삽질하다 알아낸 얻어걸린 이 방법으로 다들 해결했다고 써 있구만.

그 문제의 stackoverflow link

대답은 위에서 말한 bundle에 집어넣는 방법을 써놓고 두번째 방법에 대한 언급 없이 link는 이걸 달아놓다니..

간단히 요약하면

(1) framework build 할땐 Build setting 에서 Installation directory 를 '@loader_path/Frameworks' (path와 Frameworks 사이에 ..이 없는것에 주의) 로 해주고
(2) General setting에서 Embedded binaries에 framework 넣어주면 끝.

p.s 처음 세팅이 loader_path 였고 구글링 결과는 executable_path 였는데 둘다 잘됨. 차이는 각자 연구해보시라.
loader_path 와 executable_path에 대한 reference

2012년 11월 21일 수요일

viewWillAppear에서 들어가는 중인지 복귀하는 중인지 구분하는 방법

Determine entering or coming back in UIViewController with UINavigationController

UINavigationController를 사용하다 보면 현재 ViewController로 들어올 때 이전 화면에서 들어오는지 다음 화면에서 복귀하는 중인지 구분을 해야 할 때가 있다. 물론 들어갈 때 ViewController를 생성을 하는 경우라면 viewDidLoad에서 들어갈 때의 동작을 하는 방법도 있을 수 있겠지만 이전으로 돌아올 때는 여전히 애매하다.
그래서 그까이꺼 만들어놨겠지 하고 API를 들쑤시다 보면 isMovingFromParentViewController, isMovingToParentViewController를 찾을 수 있는데 이 메소드의 이름이 참으로 오해하기 딱 좋다. 하나는 부모에서 들어올 때, 하나는 부모로 갈 때. 문서를 보면 movingTo는 viewXXXAppear에서, movingFrom은 viewXXXDisappear에서만 제 값을 돌려준다고 되어 있는데 가만 생각해보면 좀 이상하다.
부모에서 들어오는 중이면 현재 viewController가 나타나는 중일텐데 viewXXXDisappear에서만 확인할 수 있다?
부모로 가는 중이면 현재 viewController가 사라지는 중일텐데 viewXXXAppear에서만 확인할 수 있다?
아무리 생각해도 이해가 안된다. API 문서에는 메소드 이름 이상의 별다른 설명이 없다.
그래서 확인해 봤다. 각종 상황에서 뭐가 어떻게 값이 나오는지. 그러자 알기는 옳타쿠나 알기는 커녕 멘붕이 왔다;
그러던 중 WWDC2012 Sessions 동영상을 보았는데 iOS 6으로 오면서 viewController가 확 바뀐 부분에 대해 설명하는 부분에서 viewController가 child로 추가되고 제거될 때 어떤 일이 일어나는지 자세히 나왔다. 그순간 아하!
Parent와 Child의 의미를 잘못 이해했다;;
현재 viewController의 Parent는 이전 viewController가 아니라 UINavigationController였던 것이다!
당연한 걸 뭘 호들갑이냐고? 그렇다면 미안하다;; 난 몰랐다.. 당신의 이해력이 뛰어나서 그런거라고 대인배스럽게 넘어가주자.

isMoving으로 시작하는 두 property에서 말하는 "moving"은 다음화면 이전화면 하는 navigation의 의미가 아니라 한 viewController가 NavigationController와 같은 container view controller로 들어오고 나가는 "moving"이었던 것이다. (부끄럽지만 API 문서에 보면 이렇게 떡하니 써있다. 너무 당연한 말이기 때문에 별 의미가 없다고 생각했다. 뭐 핵심은 container view controller의 의미를 오해한 것이니;)

이것은 현재 viewController의 관점이기 때문에 응용해보면 다음과 같은 4개의 메소드를 만들어 가독성을 높일 수 있다.

// only available in viewWillAppear, viewDidAppear
- (BOOL)isNavigatingFromPrevious
{
    return self.isMovingToParentViewController;
}

// only available in viewWillAppear, viewDidAppear
- (BOOL)isNavigatingFromNext
{
    return (self.isMovingToParentViewController == NO);
}

// only available in viewWillDisappear, viewDidDisappear
- (BOOL)isNavigatingToPrevious
{
    return self.isMovingFromParentViewController;
}

// only available in viewWillDisappear, viewDidDisappear
- (BOOL)isNavigatingToNext
{
    return (self.isMovingFromParentViewController == NO);
}


본인은 이렇게 한번 감싸주지 않으면 머리속에서 번역이 안되더라;;
물론 근본적으로 들어가는 상황인지 나오는 상황인지 따위를 viewWillXXX 메소드에서 궂이 구분하지 않아도 되는 것이 이상적이다. 하지만 세상사 만들다 보면 그런 나이쓰한 구현이 잘 안될 때가 있으므로 그럴 때 요런거 쓰시면 되겠다.

사람은 동시에 생각할 수 있는 정보의 양이 그리 많지 않다. 많다고 해도 한정되어 있으므로 이것을 집중해야 할 부분에 잘 써야 한다. 저런 직관적인 표현으로 바꾸어 놓으면 저 메소드를 사용하는 부분에서 이게 뭔 뜻이지? 하고 생각하는 데에 드는 시간에 원래 하려던 것에 집중할 수 있고 오해도 방지할 수 있다.
성능을 고려하면 안 좋은 방법 아니냐고? 성능이 문제되면 그 때 최적화를 하면 된다. 가독성이 먼저다. 가독성, 기능, 성능을 동시에 고려해서 한방에 짠 하고 나이쓰하게 구현하는 것은 불가능하다. 만약 당신이 가능하다면 연락주시라. 왜냐고? 스승님으로 모시고 싶어서ㅋ

iOS / Mac OS X API들을 보다보면 해당 클래스의 개발자 관점의 네이밍이 좀 있는 것 같다.
그래도 저게 가장 정확한 표현인 것은 맞으니 뭐라고 하기도 애매하고.. 뭐 그렇네ㅋ