페이스북에 공유하기 기능은 대부분의 앱에서 활용을 하고 있습니다.


앱에서 공유하기 버튼을 눌렀을 때 페이스북 앱이 없다면 Web 화면을 통해 공유할 수 있도록 브라우저가 뜨게 되는데 이렇게 공유를 하면 잘 되는데, 페이스북 앱이 있어서 Native으로 앱이 실행되었을 때 글을 작성하고 게시 버튼을 누르면 게시가 되지 않고 앱으로 돌아오는 경우가 있습니다.


제 경우 Error code 102 가 나와서 검색을 해보니 페이스북 개발자 페이지의 해당 앱의 Display Name 이 문제가 되어서 그런걸로 확인되었습니다.


개발자 페이지의 Display Name : AAA 라고 되어있는데

앱의 plist의 FacebookDisplayName 항목에는 BBB 라고 되어있으면 공유가 안되네요.


해당 키값을 동일하게 맞춰놓고 테스트 해보니 공유기능이 정상적으로 돌아갑니다.


회사에서 사용하는 iMac 의 사양은 3.06 Ghz Intel Core 2 Duo, 8GB, 500GB 입니다.


Xcode를 사용하면서 빌드 - 시뮬레이터 실행 의 속도가 생각보다 많이 답답한 경우가 많습니다.


예를들면 소스를 수정하지 않고 앱 종료 - 재실행의 경우 어떤 때에는 몇 초만에 재 실행이 이루어질 때가 있고.


느릴 땐 10초 이상 걸리는 경우가 있습니다.


왜 그런지도 모르기 때문에 더 답답하죠.



웹 서핑을 하다가 램디스크를 이용한 속도 향상 방법이 있어서 따라 해 보았습니다.


해당 글을 http://blog.shpakovski.com/2014/02/how-to-reduce-xcode-and-appcode.html 입니다. 해보실분은 이곳을 참조해서 따라 해 보세요. ^^


1. DerivedData 폴더를 램디스크를 하드링크 걸어서 사용할꺼라 이 폴더의 내용을 싹 비워줍니다. 안해도 되는데 램디스크가 연결되면 어차피 폴더 내의 기존 파일은 사용이 불가능합니다.


2. 위 링크 글에서 소개하는 램디스크 생성 스크립트를 실행합니다. 저같은 경우에는 처리가 안되길래 권한을 775로 바꿨더니 실행이 되었습니다.


3. 램디스크 설치중엔 Mac이 잠시 먹통이 되었는데 몇 분 후 괜찮아졌습니다. (대략 3~4분정도 버벅임.)


4. 기존 DerivedData 폴더가 어디로갔는지 찾아볼 수 없고 Xcode에서 해당 폴더를 열면 열리긴 합니다.

  (제가 Unix 계열 OS를 잘 다루는 편이 아니라 제가 못찾은것 일 수도 있습니다 ^^; )


5. Xcode 에서 기존 프로젝트 빌드 타임 비교.


기존 HDD 만 사용하는 경우 : 35초



램디스크 설치 후 : 51초.. 응??



뭔가 이상합니다. 왜 램디스크를 사용했는데 빌드 시간이 더 오래걸린걸까요?



딱히 설정이나 최적화가 필요 없는것 같은데 말이죠 ㅡ_ㅡ;;


이번 테스트는 실패. 램디스크 해제하고 재부팅하니 이전 상태로 돌아왔습니다.



다음엔 Xcode에 맞게 최적화 해주는 스크립트 말고 그냥 램디스크만 설치하고 DerivedData를 직접 지정해서 테스트를 해봐야 할 것 같습니다.

아래 매크로는 http://dadabeatnik.wordpress.com/2013/09/12/xcode-and-asynchronous-unit-testing/ 에서 찾은 내용입니다.


// Macro - Set the flag for block completion

#define StartBlock() __block BOOL waitingForBlock = YES


// Macro - Set the flag to stop the loop

#define EndBlock() waitingForBlock = NO


// Macro - Wait and loop until flag is set

#define WaitUntilBlockCompletes() WaitWhile(waitingForBlock)


// Macro - Wait for condition to be NO/false in blocks and asynchronous calls

// Each test should have its own instance of a BOOL condition because of non-thread safe operations

#define WaitWhile(condition) \

do { \

while(condition) { \

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; \

} \

} while(0)




사용 예제


페이스북의 문자로 된 ID를 숫자 형태의 ID로 바꿀 때 사용하는 facebook의 graph api 조회를 예로 들어보겠습니다.


비동기로 수행되는 로직이 있는경우 해당 로직이 끝나기 전에 테스트 케이스가 끝나버리기 때문에 위의 매크로를 이용해서 비동기 처리가 끝날 때 까지 테스트 케이스가 종료되지 않도록 기다립니다.


주의할 점은 비동기 로직이 실패했을 때에도 EndBlock();을 호출 해 주어야 정상적으로 종료 됩니다.


- (void)testFacebookURL {

NSString *urlString = @"https://graph.facebook.com/사용자 또는 페이지 아이디";

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

manager.responseSerializer = [AFJSONResponseSerializer serializer];


StartBlock();

[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {

NSLog(@"response : %@", responseObject);

NSLog(@"id : %@", responseObject[@"id"]);


EndBlock();


} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

NSLog(@"Error : %@", error);

EndBlock();

}];

WaitUntilBlockCompletes();

}


Xcode 5로 업그레이드 한 이후 SVN에 프로젝트를 Import 하는 메뉴가 사라져서 한참을 찾았는데 결국 Xcode 상에서는 할 수 있는 방법이 없는것 같습니다.


우선은 급한대로 터미널을 이용해야 할 것 같군요.


svn import -m "Import Message"  LOCAL_PROJECT_DIRECTORY svn://서버주소/REPOSITORY_NAME


import 하고 터미널이나 Xcode를 이용하여 Checkout 해서 사용하면 됩니다 ^^

iOS7 에서 새로 생긴 기능 중 하나, 안드로이드처럼 앱 별로 셀룰러 데이터 사용량을 파악 할 수 있다는 점 입니다.


또한 개별 앱 마다 셀룰러 사용을 불허하도록 설정을 바꿀 수 있어 무의식적으로 LTE 상태에서 데이터를 급격하게 소모하는것을 방지할 수 있습니다.


예를 들면 유투브같은 동영상 시청 앱들의 셀룰러 데이터 사용을 방지함으로써 데이터가 넉넉하지 않은 요금제 사용자에게 도움이 될 수 있습니다.


셀룰러 데이터 사용량을 확인하는 방법.

설정 - 셀룰러 메뉴에 들어갑니다.


아래로 내려보면 앱 목록이 뜨면서 셀룰러 데이터 사용량이 함께 표시됩니다.

Wifi 상에서의 데이터 사용량은 제외된, 순수 셀룰러(LTE, 3G) 데이터 사용량입니다


저 같은 경우엔 사파리를 통해 데이터를 가장 많이 사용했는데요. 테스트로 한번 꺼봤습니다.


사파리의 셀룰러 데이터 사용을 금지한 후 웹 서핑을 하려고 시도하니 위와같은 메세지가 뜨면서 진행이 되지 않습니다.

설정을 누르면 셀룰러 데이터 관리 화면으로 돌아가게 됩니다.


데이터가 적은 요금제를 쓸 때, 유투브같이 데이터를 많이 쓰는 앱들을 무의식적으로 사용하는것을 방지하기 위해 셋팅해두면 좋을 것 같습니다. ^^

iOS 7 AutoLayout 과 topLayoutGuide 를 이용한 화면 맞추기 에서 했던 방법은


스토리보드를 사용 시 적용할 수 있는 방법이고 XIB 위주로 만들어진 레이아웃에서 iOS6 이하와, 7 모두 잘 맞게 맞추는 방법을 알아보겠습니다.




기존 6.0 미만을 지원하는 프로젝트인 경우 Xib의 우측 유틸리티 섹션에 첫번째 탭인 File inspector 에 보면 Use Autolayout 항목이 체크 해제되어있을 것입니다.


보통 이 상태로 iOS7 에서 실행해보면 아래와같이 상태바 영역까지 콘텐츠가 밀려 올라와있는것을 볼 수 있습니다.


일단 iOS7 에서 잘 보일 수 있도록 ViewController.view의 sub view 들을 모두 선택하여 20포인트 아래로 끌어줍니다.


메인 뷰의 자식뷰들을 모두 선택


객체들을 상태바 아래로 이동


일단 에디터 창에서 상태바 아래로 모두 내렸으면 하위뷰들을 모두 선택한 상태에서 오른쪽 Size inspector 를 선택합니다.


그리고 아래와 같이 iOS6 / 7 Deltas 라고 되어있는곳의 Delta Y 항목을 -20을 셋팅합니다.


그리고 iOS6으로 실행!


짜잔~ 잘 나왔죠? (Text Field 문자열 짤린건 패스.. ㅋㅋ)



xib에서 배치된 객체들은 이렇게 한번에 처리가 됩니다.


다만 뷰가 로드된 이후 프로그램 로직에 의해 재 배치 되는 경우는 iOS 버전에 따라 위치를 보정해줘야 합니다.


자~ 이제 모두모두 즐거운 iOS7 호환성 작업을 시작해 봅시다!


아이패드 2 사용자로서 iOS7이 마냥 반가운것은 아닙니다.


예전 3Gs 사용중에 iOS6이 배포되었을 때 별 생각없이 업그레이드를 했다가


카카오톡 한번 실행하는 데 10여초 씩 걸리던 기억을 떠올려보니 iOS7 업그레이드에 망설여질 수 밖에 없죠.


마침 같은 모델에 iOS7을 설치한 분이 있어 가용 메모리를 비교해 보았습니다.


기기는 둘 다 재부팅 완료 후 다른 작업 없이 메모리 체크 앱만 실행시켜서 캡쳐한 것입니다.


iOS6 @ iPad2


iOS7 @ iPad2


아이패드 2의 기본 메모리 용량이 512MB 인데다 OS가 사용하고 남은 용량을 비교해보니 iOS7 을 올리면 기본적으로 80메가정도의 메모리를 더 사용하고 남은 메모리용량이 140MB 정도밖에 되지 않습니다. 조금 사용하다 보면 앱을 다 종료시켜도 120MB정도밖에 확보되지 않습니다. (iOS6의 경우 200MB정도 확보 됨)


iOS7은 그냥 아이폰 5 에서 사용하는것으로 만족해야 겠다는 생각이 드는군요. ^^

iOS 2.x 일 때 부터 개발을 해왔지만 그땐 메모리 관리도 잘 몰라서 자주 뻗고 그랬는데

어느덧 iOS 7 이 정식으로 공개가 되었습니다.


iOS7에서 UI가 급격하게 변하면서 개인적으로 가장 시급한 문제는 네비게이션 컨트롤러를 사용하지 않는 Single View 스타일의 앱을 업데이트 하면서 생긴 문제인데, 기존에는 상태바 아래부터 콘텐츠 배치가 되었으나, 이제는 모든 화면을 콘텐츠 영역으로 사용하게 되면서 개발자들에게 멘붕을 선물해주고있죠. ㅋ

기존 버전들과의 호환성을 맞추기 위해 iOS7에서도 여전히 상태바 영역만큼을 띄운 채로 보여주려면 하나하나 OS버전에 따라 분기를 해주거나 AutoLayout과 UIViewController.topLayoutGuide 를 사용해야 합니다.


일단 다른 앱들에 적용하기 전에 샘플로 하나 만들어보았습니다.


참고로 스토리보드에서만 가능하고 XIB 에서는 Top, Bottom Layout Guide가 나오지 않는다. XIB에서는 어떻게 하는지 좀 찾아봐야 할 듯 합니다.



일단 화면 구성은 메인 뷰 안에 UILabel을 하나 추가하고 시계 아래쪽에 보이도록 만듭니다.


그리고 Label의 y 값을 0으로 하고 SuperView에 맞춰진 경우 아래와 같은 화면을 보게 됩니다.


iOS6 에서는 기존대로 잘 나오게 됨.


iOS7 에서는 라벨이 상태바 영역을 침범하게 됨.



일단 여기서 한번 멘붕을 겪고 y 값을 20을 주고 띄워서 iOS7으로 실행해본다.

일단 잘 iOS7 에서는 잘 나오게 되지만..

iOS6 에서는 반대로 20pt 떨어져서 나오게 됩니다.


이렇게 되면 어떻게 처리해야 하나 한참 구글신께 물어보면 edgesForExtendedLayout 를 사용하라고 나오는데, 이런 답변은 대부분 iOS7 Beta 초반의 얘기들입니다.


이 방식으로는 아무리 셋팅을 해봐도 Single View 스타일의 앱에서는 효과가 없었습니다.


이에 대한 해결 방법은. UILabel을 선택하고 Xcode의 Utility 섹션(화면 우측)의 Size 탭에 가보면 아래와 같은 제약조건들이 설정되어있다.


여기서 중요한건 Top Space to 라고 되어있는건데 Xcode 4.5까지는 이 기본 보라색 속성을 지울 수가 없었죠.

하지만 Xcode 5 에서는 이 기본 속성도 삭제가 가능합니다.


일단 오른쪽 설정 버튼을 눌러 해당 제약사항을 삭제해버린다.


그리고 Status Bar가 있는것으로 생각하고 20포인트를 띄워준다. (UILabel.frame.origin.y = 20)



이제 왼쪽의 뷰 구조 쪽에서 제약 조건을 설정하고 싶은 객체를 선택하고 마우스 우클릭을 한 채로 위쪽에 보이는 Top Layout Guide로 끌어놓습니다.


그러면 위와 같이 Spacing 항목 두개가 뜨는데 Vertical Spacing을 선택하고 다시 오른쪽에 제약사항들 목록을 보면 Top Space to : Top Layout Guide 항목이 추가되어있습니다.


이제 실행해보면 아래와 같이 iOS6, iOS7 둘 다 똑같은 위치에 UILabel이 표시됩니다.

하지만.... 여기서 끝이 아닌것이, AutoLayout은 iOS6.0 부터 지원하는 기능이라 iOS4.3 ~ 5.x 까지는 여전히 따로 작업을 해줘야 하는 문제가 있습니다.


설명이 길었는데 중요한건 Top Space to 의 Target이 Superview 가 아니라 topLayoutGuide 가 되어야 한다는 것!



openssl smime -sign -signer mdm.pem -inkey privateKey.pem -certfile WWDR.pem -nodetach -outform der -in unsigned.mobileconfig -out signed.mobileconfig


아래 pem 파일은 각각의 파일을 pem으로 변환하여 사용합니다.

mdm.pem : MDM 인증서

privateKey.pem : MDM 인증서를 발급 받을 때 사용한 개인 키

WWDR.pem : 애플 WWDR 파일

unsigned.mobileconfig : 서명되지 않은 설정 파일

signed.mobileconfig : 서명처리 후 파일의 이름


Apple WWDR certificate : https://developer.apple.com/certificationauthority/AppleWWDRCA.cer


정상적으로 서명이 완료되면 프로파일을 설치 할 때 아래와 같이 초록색으로 '확인 완료' 라고 표시됩니다.




언제부터인가 개발하던 앱을 실행시켰을 때 에러가 발생해도 해당 위치를 보여주지 않아서 답답했습니다.


아래와 같이 말이죠.



이렇게 에러 위치를 알려주지 않아서, 에러가 발생했을 때 의심가는 부분에다가 로그를 출력해 가면서 위치를 찾았습니다.


오늘은 하도 답답해서 검색해보니 방법이 있네요. 역시 구글이야.. ㅠ_ㅠ


1. Xcode 좌측 네비게이터 쪽 BreakPoint Navigator 를 열어봅니다. (Cmd + 6)


2. 네비게이터 아래쪽에 + 버튼을 누르면 아래와 같이 Add 항목이 2개가 뜹니다.


3. Add Exception Breakpoint... 를 선택합니다.

속성은 그대로 놔두고 Done을 누릅니다.


테스트용으로 Dictionary에 nil을 셋팅하게 해두고 실행해봤습니다.

예전처럼 에러 발생 위치가 잘 뜨네요.

+ Recent posts