2013년 12월 25일 수요일

C++ / C with xcode 5.0.2

그동안 회사에서 맥을 이용하여 개발을 하여도
정작 xcode를 이용하지 않았다.
처음 app을 개발을 할 때는 xcode에 엄청난 code complete 기능 때문에
익숙하지 않은 objective-c 코딩과
익숙지 않은 코코아 터치 프레임워크를 암기 하지 않고도 타이핑 할 수 있어서 너무 좋았다.

하지만 실제 회사에서 업무는 C/C++이고
회사 소스 코드를 xcode로 프로젝트를 만들면 인덱싱도 안되고 해서 사용하지 못했다.

그런데... 그렇게 있고 살았던 xcode

xcode가 안돼서 그냥 eclipse를 써왔는데...

드디어 5버젼에서 무언가 엄청난 C/C++ 파싱 능력이 생긴 것인지

인덱싱이 된다.

물론 callee/ caller 검색 이라든지 다른 IDE에 비해 부족하지만
jump to define은 확실하게 된다.

그리고 무엇보다. code complete가 완벽히 되고 있다.

이제 eclipse에서 xcode로.... 갈아 타려 한다.

그러기에 가장 중요한 단축키 몇 가지는 반드시 익히고 가야 한다.

먼저 좌측에 있는 창을 바꾸는 단축키



그리고 각 화면에서 선택 필터링을 하려면
하단에 직접 입력 해도 되지만

Option+Command+J

그리고 프로젝트 전체에서 찾기는
Shift+Command+F

에디터 변경

중앙 에디터의 변경

Standard Editor
Command + Enter

Assistant Editor
Option + Command + Enter

Version Editor
Option + Shift + Command + Enter



코드 분석중에 가장 필요한 Navigator 단축키들..

Jump to definition
Ctrl+Command+J
Jumpt to definition Assistant Editor
오른쪽 보조 에디터에 정의 부분을 보여주는 아주 좋은 기능
Ctrl + Otpion+Command + J

Ctrl + Command + <-- back
Ctrl + Command + --> Go

그리고 Find next previous는
Command +G / Shift + Command + G

이 정도만 익히면 될 것 같다.


짧은 코드들을 등록해서 빨리 찾아서 코드에 넣고 싶다면
code snippet
Ctrl + Option + Command + 2



osx 타임머신 백업 디스크 변경 작업

기존에 타임머신을 설정하고 백업을 하고 있는데
용량이 부족 하는 이유이거나 나처럼 백업 디스크가 새로 생겨서
이전 백업에서 새로운 디스크로 백업을 옮기고 타임머신을 설정 하고 싶을 때가
분명이 있을 것이다...

그래서 검색 했다.

http://macs.about.com/od/backupsarchives/qt/Moving-Time-Machine-To-A-New-Hard-Drive.htm

http://support.apple.com/kb/HT5096?viewlocale=en_US&locale=en_US

이 글들의 간단하게 요약하면
타임머신을 끄고

새로운 백업 디스크를 GPT 파티션 테이블로 디스크를 구성하고

디스크 정보를 보기
Get Info를 수행 하여
맨 아래에 있는 체크를 해제 하고 기존에 백업 디스크에 백업되어 있는 데이터 폴더
Backups.backupdb 전체를 새로운 디스크에 복사를 하는 것이다.

그런 후 타임머신을 다시 켜고 백업 디스크를 새로운 디스크로 교체 하면
이전 백업에 추가로 백업이 되고
이전 백업 정보도 모두 된다는 것인데....

내가 실제로 해보니 수백 기가바이트 복사하는 과정에 복사 오류가 난다.
복사 오류 메세지는 iWork 버전이 어쩌구...

참을성이 없는 나는 바로 취소해 버리고

이전 백업을 모두 제거하고

새로운 디스크에 처음부터 그대로 다시 백업 했다.

결국 실패!!



2013년 10월 14일 월요일

iOS 개발 인증서 갱신 ... 오랜만에 하려고 하니 어질.....

오랜만에 먼가 개발해보려고 하니 인증서가 다 만료 되었다.

APP id를 만들고
Provisioning을 만들려고 하는데...
먼가 안된다..

개발 인증서가 없나 보다.

developer certificate와 distribute certificate를 만들어야 한다.



먼저 developer.apple.com에서 인증서 추가를 누른다.


키체인 접근을 실행시킨 다음 환경 설정에서 위와 같이 해준다.

인증서 요청을 한다.


메일주소를 입력하고 디스크에 저장.


developer.apple.com에서 제너레이트 버튼을 누르고 나면 생성된 인증서를 내려 받아 더블클릭 한다.



간 만에 접속 해서 앱 한번 만들려고 하니 생각도 안 나고 어질 어질 했다.

이 개발 용 배포 용 인증서를 다른 맥 머신에 내려 받아서 더블 클릭하면 해당 머신 에서도 개발 배포가 가능하다.








2013년 9월 4일 수요일

cocos2d 기본 클래스들...

CCNode

iPhone SDK의 NSObject와 같이 cocos2d의 최상위 클래스
CCNode 클래스는 당양한 프로퍼티가 있다. 위치, 색상, 투명도, 크기, 회전, 가시성 여부, 카메라, 그리드 등 등이 있다.
이 객체는 자식 노드를 가질 수 있고 계층 구조로 만들수 있다.
계층구조로 만들면 부모 객체의 투명도 같은 속성이 바뀔때 자식 노드도 함께 손쉽게 변경이 가능하다.
스케줄러도 포함하고 있다.

CCDirector

싱글톤 클래스임, 어플리케이션에서 단 하나의 인스턴스만이 존재한다.
cocos2d는 게임의 화면을 장면 (Scene) 단위로 구성해서 처리한다.
CCDirector는 여러 장면들을 뒤로 가게 하거나 앞으로 가게 하는 등의 역할을 한다.

CCScene & CCLayer

UIKit의 UIView의 해당하는 클래스다. 
Sprite, Label, Menu등과 같은 클래스 객체들을 자식으로 가질 수 있다.
CCScen과 CCLayer의 차이점은 CCScen은 사용자의 터치 이벤트를 받아서 처리할 수 없고 Accelerometer 입력 또한 처리 할 수 없지만 CCLayer는 사용자의 터치 이벤트를 받아서 처리할 수 있다.

CCSprite

Sprite는 화면을 구성하는 정적인 이미지나 애니메이션이 되는 일련의 이미지를 가리키는 표현으로, 보통 게임에서 사용되는 이미지를 말하는데, 이러한 CCSprtie는 이미지 파일을 화면에 출력하는 역할을 하므로 이미지 파일의 로딩과 화면 출력과 관련한 다양한 메서드를 제공 한다.

Action

Sprite의 애니메이션 처리를 위해 Action 클래스를 제공한다.
[sonesprite runAction: [[CCMoveBy actionWithDuration:2 position: ccp(50,10)]];
2초동안 50픽셀 오른쪽으로 이동, 위쪽으로 10픽셀 이동

다양한 액션을 제공한다.
이동, 회전, 점프, 크기 변환 등의 기본 액션과 기본 액션을 결합하거나 반복하는 액션을 제공한다.
By , To 라는 두 가지 종류로 나뉘는데, By는 현재 값에서 지정한 값만큼 변하는 액션을 수행하고, To는 지정한 값으로 변하는 액션을 수행한다.


2013년 8월 28일 수요일

Logitech Ultrathin keyboard cover 사용기

일단 이제품 리뷰는 인터넷에서 엄청나게 많고 나도 그러한 리뷰를 보고 구매 충동이 있었지만....
참고 견디고 참아 드디어 이제야 내 손에 들어 왔다.

아이패드 악세사리 중에 정말 사고 싶었던 아이템이다.
인터넷에서 처음 이제품을 보고 사고 싶었고
실제로 사용하는 사람들을 보고도 부러워만 했다.
문제는 가격이다.
10만원... 후덜덜... 소셜에서 8만원정도... 그것도 후덜덜...
그런데 갑자기 49000원에 .. 올라와서 덮석 사버렸다.

지금 이 글도 이 키보드를 이용해서 아이패드로 쓰고 있다.

대략 이틀정도 사용 하고 후기를 기록한다.

가격 10만원대 에 샀다면 땅을 치고 후회 했을 것이다.
49000도 싸다고 생각 되지는 않다.
29000짜리 이미테이션 제품도 있다.

품질 사진상으로는 엄청 좋아 보였지만 실제로 만져 보니 로지텍 답지 않게 좀 어설픈 면도 있다.
일단 전원 스위치나 블루투스 스위치는 싸구려 틱하다.
그리고 알루미늄 커버가 아이패드 알루미늄과 결코 같지 않다. 훨씬 저렴한 느낌이 난다.
그리고 키보드로 사용할때 하판이 되는데 고무 받침이 조금은 있어야 하지 않나 생각된다.
너무 잘 미끄러진다. 그리고 바로 잔기스가 생길 듯 하다.

거치 부분이 후면 커버를 사용하면 잘 맡지가 않다. 난 그래서 벨킨 백커버를 과감하게 톱질 해서 쓴다.
물론 세로 방향으로는 쓸수가 없다.
좀더 얇은 백커버를 쓰거나 아에 쓰지 않거나 해야 할 듯 하다.

자석 채결부분, 이 부분... 음... 순정 아이패드 스마트커버에 자석 채결 부분에 비해 완전 싸구려 느낌이 난다.
자석 새기도 너무 약해서 실수로 키보드만 잡는다면 아이패드가 바닥과 키스하는 장면을 목격 할 것이다.
자석 채결 부분을 스마트 커버에 자석 채결로 바꾸고 싶은데 분해 방법을 모르겠다. 정말 이겄담 스마트 커버의 자석 채결로 변경하면 훨씬더 좋을 듯 하다.

너무 단점만 썻나...
장점이라면 좀 가볍고
덮어 놧을때 어울리고
이쁘고 베터리가 오래간다고 한다. 아직 얼마 사용하지 않았기 때문에 베터리는 써봐야 알겟다.
일단 메뉴얼 상으로는 한번 충전으로 하루 2시간 사용하고 사용하지 않을때 전원을 끈다면 6개월 사용한다고 한다.

또하나의 장점은 단축키이다. 이것은 애플 무선 키보드로 아이패드에 연결 했을때 보다. 훨씬 좋은 장점이 되는듯 하다. 홈키.. 이거 정말 좋은거 같다. 더블 클릭으로 실행중 앱도 되고.
요부분은 정말 만족한다.

키감은 처음에는 오타가 조금 나고 어색했지만 금새 익숙해지는 듯 하다.
최고의 장점은 역시나 휴대성이다. 애플 무선 키보드가 있지만 그걸 들고 다니기에는 먼가 그렇지만
이 제품은 아이패드와 일체로 휴대하게 되니 좋다.

여하튼 49000원도 좀 비싼감은 있는 아이템이다.
이가격에 풀리는 이유는 아무래도 애플 아이패드에 이 디자인은 이제 끝이라고 판단하는 업자들이
제고를 푸는거 같다.

조금더 기다리면 엄청 싸게 나올수도 있을듯...

2013년 8월 15일 목요일

cocos2d 시작해봅시다!


cocos2d를 한번 해보자
몇달 전에 책을 훑어 보았다.
생활이 바빠서인지 맥미니를 켜본지도 한참 오래된거 같다.
실제로 코딩을 해보지 않으니까 다 잊어 버렸다.
다시 시작..!


http://www.cocos2d-iphone.org/download/

안정버젼을 다운로드 받는다
현재 시점 안정버젼은 2.1

다운로드 받은 파일에 압축을 풀고 적당한 위치로 저장 한다.

터미널에서 다음과 같이 수행하면 xcode 템플릿을 설치 할수 있다.

sparrow-mac-mini2:cocos2d-iphone sparrow$ ./install-templates.sh -f
cocos2d-iphone template installer



Installing cocos2d templates
----------------------------------------------------

...creating destination directory: /Users/sparrow/Library/Developer/Xcode/Templates/cocos2d v2.x/
...copying cocos2d files
...copying CocosDenshion files
...copying Kazmath files
...copying template files
done!



Installing Physics Engines templates
----------------------------------------------------

...copying Box2d files
...copying Chipmunk files
done!



Installing JS Bindings templates
----------------------------------------------------

...copying JSBindings files
...copying JSBindigns Support files
...copying SpiderMonkey files
...copying JR Swizzle files
...copying CocosBuilderReader files
done!



Installing CCNode file templates...
----------------------------------------------------

...creating destination directory: /Users/sparrow/Library/Developer/Xcode/Templates/File Templates/cocos2d v2.x/
done!

설치된 템플릿은 다음과 같이 Xcode에서 보인다.



이제 모든 기본 프로그램 hello world를 작성해봅시다.!

이런 아무것도 작성하지 않고 템플릿으로 만들어진 코드가 hello World 다!


이미 책도 오래 되었고 
소개된 버젼도 1.0.1

버젼도 2.0

많이 바뀐듯 하지만

실제로 코딩을 하면서 틈틈이 블로그에 글을써서 익혀야 겠다.



2013년 8월 5일 월요일

PRW-2500 TOUGH SOLAR

태양광 충전
어릴적 집에 전자 계산기에 태양광 충전을 손으로 가리면 점차 글씨들이 흐리 흐리 하게 변하면서 꺼진다.

이 시계도 태양광 충전이라고 되어 있다.
처음 개봉했을때 베터리 레벨이 M이였다.
해외 배송을 길게 오면서 어두운 상자 속에서 베터리가 닳았나?
C L M H 
C는 충전이 필요한 상태이고
Low, Mid, High 표시다.

처음부터 M이라서 좀 그랬다.
거기에 장마라서 날도 흐리고 좀처럼 H가 되지 않았다.

강원도에 가서 부모님 농사일을 이틀 도와드리고 나니 H가 되었다.
그러다가 다시 장마철 주말 방콕을  했더니 다시 M

아무래도 AUTO LIGHT 기능이 밤에 내가 자면서 자주 불이 켜져서 베터리 소모가 심한가 보다.
그래서 설정을 OFF했는데도 좀처럼 베터리 레벨은 H로 오르지 않는다.

지난 7월 중순 소야도에서 땡볕 백사장에서 애들과 하루를 놀아 주었더니 짜짠 H가 되었다.
그후로 지금껏 계속 H상태를 유지 하고있다.

물론 AUTO LIGHT는 OFF로 사용중이다.

아무리 태양광 충전이라고 해도 내부 베터리에 수명은 잇겟지만 그래도 베터리 교환 없이 오래도록 사용할수 있을듯 하다.

2013년 7월 2일 화요일

PRW-2500 전파수신

어릴적 전자시계는 가운데 핀으로 눌러야 세팅 모드가 되었고
깜빡 깜빡 세팅모드에서 정확한 초를 맞추기 위해 TV에서 나오는 시간을 바라 보며
동기화를 시켜 주었다.

요즘은 핸드폰 네비게이션 등등...
모두 시간이 정확히 동기화 되는 장비들이 주의에 많고 많지만
그 당시에는 시간을 동기화 하는건 사람이 TV를 보고 수동으로 하는게 다였다.

전파수신
이 기능 때문에 PRG-250을 구매하지 않고 해외 구매 까지 하면서
더 비싼 PRW-2500을 구매 했다.

메뉴얼에 하루 6번 동기화 한다고 되어 있다.
영어를 대충 읽고 하루 6번... 와우!

도교와 후쿠시마 신호를 받는다고 되어 있는데
너무 멀어서인가.. 처음 개봉했을때도 메뉴얼과 다르게 인디케이터가 없었다.

나중에 알게된 사실.. 하루 6번 이란것은 00시 부터 05시 까지 매 1시간
정확히 00, 01, 02, 03, 04, 05시 에 6번 동기화를 시도 한다.
2 ~ 14분 정도 시도 하다가 안되겠다 싶으면 바로 포기 한다.

동기화가 되면 인디케이터 표시가 나타나고 그날 하루가 지나 00시가 되면 인디케이터 표시가
사라지면서 00시에 다시 동기화를 시도 한다.

그런데.. 그런데.. 이게 2일 3일 내내 실패 하는 경우도 있다.
우리집이 않좋은듯...

수동으로 해도 수신 레벨이 L1으로 표시된다.
여기는 도교랑 후쿠시마랑 너무 먼가 보다.

그래도 알아서 시간이 척척 맞는다는거 참좋은 듯 하다.
머 핸드폰시간도 정확한데.. 하며 당연하다고 생각 할지 모르지만 난 어릴적에 시간을 무조건 정확히 맞추었다.

이런걸 밤 12시가 되면 내가 자는 동안 계속 시도 한다는게.. 너무 신기하고 좋다.


2013년 6월 14일 금요일

CASIO PRW-2500 리뷰

PRW-2500-1CR



뒤에 1CR 은 멀 뜻하지 모르지만 내가 구매한것은 1CR 모델이다.
T가 들어간 모델은 티타늄 밴드이고 다른 모델 들은 우레탄 밴드 정도
그리고 티타늄 밴드 모델들은 가격이 훨씬 비싸고 본체도 메탈 색상인듯 하다
하지만 실제로 만저 보지 못했으니 알수가 없고
내가 구매한 우레탄 밴드 모델도 위에 베젤도 금속 같고 본체 도 금속 느낌이 난다.
밴드와 버튼과 하단 일부가 플라스틱 같다.

일단 셀프 생일 선물로 구매하고 실제로 사용한지 3일 정도 되었는데 매우 만족하고 있다.

어린 시절 초등 (나는 사실 국민학교 출신) 시절 돌핀 시계가 있었다.
반달 모양에 유리에 하단에 버튼이 두개 있던 모델
그 다음으로 돌핀 다음 버젼 좀 비뚤어진 화면에 아래 위로 버튼이 있었다.
그리고 중딩 시절에 CASIO 크로노 그래프? 트라이 그래프? 여튼 돌핀 보다 훨씬 좋은
특히 백라이트가 화면 전체가 들어오는 EL 백라이트가 적용된 모델
그리고 군대에서 카시오 저가 바늘 시계 이면서 하단에 작은 전자가 있는 모델
그리고 마지막 궁극에 카시오 G샥 초창기 버젼
당시에 어떤 모델인지도 모르고 그냥 동그란 그래프가 두개정도 예전 중딩시절에 카시오와
비슷하고 기능도 비슷하지만 크고 두껍고 튼튼한 기억이 난다.
이게 나의 마지막 전자 시계 였다.
군대에서 사용하다가 제대해서 복학해서도 잘차고 다녔는데.. 당시에 휴대전화가 있어도 이 시계를 잘차고 다녔다. 그런데.. 그런데.. 초등학교 랜설치 아르바이트를 하다가 그만 수돗가에 플러두고 그냥 다른 학교 작업 하러 가는 바람에 잃어 버렸다.

어린 시절에 휴대 전화가 없었던 시절 그리고 고딩 까지 삐삐가 없었기에 시계는 필수 이었고 난 전자 시계 그중에서도 CASIO가 좋았다.

하지만 마지막 G샥을 잃어버린 후 10여년이 지나서 기능 많은 전자 시계를 갖고 싶어졌다.
그러던 중 김병만에 정글에 법칙 같은 걸 보면서 연예인들이 차고 나오는 큼지막한 전자시계를 보면서 다시 전자시계가 갖고 싶어졌다.

그래서 검색에 검색에 고르고 고르고 또 골라서 프로트랙.... PRG...

그러다가 또 전파 수신 PRW...

나의 선택은 PRW-2500 물론 5000이 더 좋아 보이지만 가격에 압박과 많은 기능이 과연 저 작은 LCD에 나올 수 있을까?

해서 이중 LCD 모델 2500을 선택했다.

좋은점
전파 수신이라서 시간이 정확히 맡다.
난 낚시꾼이다. 타이드 그래프가 나온다. 월령도 비슷한 의미로 필요 할지 모른다.
난 캠퍼다 온도계가 된다.
디자인 죽인다.
시계줄이 크지 않아서 나 같은 손목이 얇아도 착용할 수 있고 어울린다.
기압계가 측정 뿐만 아니라 실시간으로 변화 추이가 추적 되는데 이걸로 날씨를 예측 할 수가 있다. 실제로 3일정도 착용했는데 얼추 맞는다.
기압이 저-->고로 가면 흐림에서 점차 맑아지고
고-->저로 가면 맑은 날씨가 흐려진다.


나쁜점
일단 10여년만에 착용이라 그런지 아직 이질감이 있다.
전에 G샥도 크다고 느꼇는데 이거는 좀 더 커서 인지 무게 감이 있다. 팔운동 기능이 있다.
전파 수신이란 것이 실패가 잘된다.
그래서 처음 개봉 했을때 시간이 6초 정도 틀리고 전파수신 수동으로 계속 ERR가 뜨고
안테나 표시도 없고
결국 간신이 성공하고 나니 하루 1번 정도 수신 하는듯 하다.
메뉴얼이 영어라서 한동안 독해 했다.
나침반이 약간 오차가 있는듯하다 아이폰과 비교 할때
메뉴얼에 켈리브레이션 하는 메뉴가 있는 걸로 보아 보정해줘야 하는 듯 한대 그냥 내버려 둔다.
기능이 만치만 사용하기 어렵다. 메뉴얼이 영어라서 아직 숙지를 못했다.

좋은점도 있고 나쁜점도 있지만 난 매우 만족한다.
아주 좋다.
잃어버리지 않고 오래 차야 겠다.




2013년 5월 30일 목요일

2012 late 맥미니 가상환경에 설치된 windows 7 체험지수는?



프로세서 6.9
메모리 7.6
그래픽 5.9
게임 그래픽 5.0
하드 디스크 6.6

와우!

엄청난 성능이!!

하나 밖에 남지 않은 윈도우 머신인 lenovo T60 보다 훨 성능이 좋다.

부트 캠프도 날려 버렸다.

은준이 생일 선물로 사준 xbox360에 하고 싶은 fps게임을 하면 되니
구지 mac mini 부트 캠프에 윈도우 구동 할일이 없다 싶어서 바로 제거해 버렸다.


2013년 4월 30일 화요일

xbox360 간단리뷰

우리 아들 은준이 생일선물 xbox360 스타워즈 한정판

사실 키넥트 스타워즈를 엄청 좋아 할 줄 알았는데 은준이가 아직 잘 하지 못한다.
그리고 컨트롤러를 이용하는 게임에 아직 관심을 갖지 않는다.
하지만 언젠가는 아빠랑 같이 놀아 줄거라 믿는다.

현재 6살 은준이에게는 조금 어려운 키넥트다.

한 1년이나 몇 개월은 더 있어야 스타워즈를 잘 할거 같다.
조금은 이른감이있다.
내가 게임을 하는것을 옆에서 구경 하며 좋아 하는데
나는 제다이 수업을 마치고 실전에 들어가니 너무 힘들다.

키넥트 스포츠나 댄스센트럴 등을 데모로 해 보았는데 괞찮다.
구매 하고 싶을 정도다.

엑스박스의 외관은 생각보다 크기가 좀 크다.
무선 컨트롤러는 아주 훌륭했다.
콘솔 게임기를 처음 접해본 나에겐 엄청 신기하고 이렇게 많은 키와 컨트롤이 필요한가 했지만
추억에 고스트리콘 어드벤스 워파이터2 데모를 실행해 보니 모두 필요 했다.
총을 맞으면 진동이 오는게 게임에 몰입도가 한층올라간다. 정말 즐겁다.
은준이 생일 선물인데 내가 더 즐겁다.

하드디스크를 연결하니 어라 인식을 못하는지 아무것도 안보인다.
설정에서 디스크를 구성하고 나니까 30기가로 인식이된다.
맥미니에 연결해 보니 그대로 80기가 하드이고 FAT32로 포멧이 되어 있는데
히든 디렉토리가 몇개 구성되어 있다.

동영상 몇개를 복사해서 엑스박스에 연결하니 훌륭한 미디어 재생기가 된다.
요즘 LED TV는 머 USB디스크로 영화 감상이 되지만 우리집 LCD TV 는 구형이라서 안된다.
IPTV세탑도 여러번 교체 했지만 불안한 플레이, 지원안되는 파일은 갑자기 재부팅도 된다.
해서 구형 맥미니를 xbmc머신으로 TV에 연결해 두었는데 이제 그 일을  엑스박스가 할 듯 하다.

엑스박스로 베를린이라는 영화를 감상했다. 영화도 아주 재미있게 잘 보았다.
영화를 보다 손을 휘저으면 키넥트가 리모컨 역할을 해준다. 정말 편리 하다.


엑스박스를 평가 하자면 게임 재미, 소프트웨어의 완성도, 하드웨어 외관, 그리고 컨트롤러 모든 점에서
나는 매우 만족한다.
다음 세대 엑스박스가 나오기 때문에 지금 시점에서 엑스박스360이라...
그냥 나는 머 지난 게임들 천천히 싸게 구매해서 하고
은준이가 자라면서 아빠랑 같이 FIFA같은 2인 게임을 같이 하며 즐거워 할날을 기다린다.
아직은 키넥트 게임도 제대로 못하고 잊지만.... 언젠가는 아빠 한게임 해요!!!!
하겠지....

2013년 4월 29일 월요일

iOS 프로그래밍 팁 - fastpdfkit 사용하기

ALTIBASE HDB Manual app
https://itunes.apple.com/us/app/altibase-hdb-manual/id597190444?l=ko&ls=1&mt=8

처음 만들때는 QuartzCore 이용해서 pdf를 다루는 API를 직접 이용해서 작성해 보았다.

확대 축소 부 터 해서 제스처에 의한 페이지 컨트롤
모든 게 부 자연스러웠고

인터넷에서 PDF 를 다루는 코드 들을 조합해서 나름 만들었지만 매우 불안정했다.

특히 검색 속도는 너무 느렸다.

http://support.fastpdfkit.com/kb/how-to/three-minutes-implementation-guide

fastpdfkit이라는 라이브러를 이용해서 바로 프로그램을 업데이트 했다.

성능 속도 모든 면에서 우수하다.

단 무료 버전에 경우 로고가 잠시 뜨지만

간단한 PDF를 보여주어야 할 경우에 이를 이용하는 것이 좋은 듯 하다.

위 링크 3분 가이드를 그대로 한다면 어렵지 않게 구현 가능 할 것이다.


실제로 ALTIBASE HDB Manual app에서

ManualViewController.h

ManualViewController.m


#import <UIKit/UIKit.h>
#import <FastPdfKit/FastPdfKit.h>
@class MFDocumentManager;

@interface ManualViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, MFDocumentViewControllerDelegate>
{
    UITableView * tableView_;
    NSArray *keys_;
    NSDictionary * datasource_;
    NSDictionary * filename_;
}

-(void)actionOpenPlainDocument:(NSString *)docName withPage:(NSInteger)pageNum;

@end

ManualViewController.m

테이블 뷰 선택 시 파일이름과 페이지 번호만 넘기면 된다.!!


/테이블 선택
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    
    
//    PDFViewController * pdfviewController = [[[PDFViewController alloc] init]autorelease];
    
    id key = [keys_ objectAtIndex:indexPath.section];
    NSString * filename = [[filename_ objectForKey:key] objectAtIndex:indexPath.row];
    
    //pdfviewController.filename = filename;
    
    //현재 페이지 번호 전달
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    NSInteger pageNum = [userDefault integerForKey:filename];
    if (pageNum == 0) {
        pageNum = 1;
    }
    
    [self actionOpenPlainDocument:filename withPage:pageNum];

    //pdfviewController.currentPage = pageNum;

    //[self.navigationController pushViewController: pdfviewController animated:YES];
    
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}





-(void)actionOpenPlainDocument:(NSString *)docName withPage:(NSInteger)pageNum{
    /** Set document name */
    NSString *documentName = docName;
    
    /** Get temporary directory to save thumbnails */
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    
    /** Set thumbnails path */
    NSString *thumbnailsPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",documentName]];
    
    /** Get document from the App Bundle */
    NSURL *documentUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:documentName ofType:@"pdf"]];
    
    /** Instancing the documentManager */
    MFDocumentManager *documentManager = [[MFDocumentManager alloc]initWithFileUrl:documentUrl];
    
    
    
    /** Instancing the readerViewController */
    ReaderViewController *pdfViewController = [[ReaderViewController alloc]initWithDocumentManager:documentManager];
    
    /** Set resources folder on the manager */
    documentManager.resourceFolder = thumbnailsPath;
    
    /** Set document id for thumbnail generation */
    pdfViewController.documentId = documentName;
    

    
    pdfViewController.startingPage = pageNum;
    //pdfViewController.page = pageNum;

    
    /** Present the pdf on screen in a modal view */
    //[self presentModalViewController:pdfViewController animated:YES];
    [self.navigationController pushViewController: pdfViewController animated:YES];
    
    //현재 페이지 번호 저장
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    [userDefault setInteger:pdfViewController.page forKey:docName];
    [userDefault synchronize];

    
    /** Release the pdf controller*/
    
    [pdfViewController release];
}


2013년 4월 27일 토요일

iOS 프로그래밍팁 - XCode Analyze 이용하기 (정적 분석)



XCode 에서 Product -> Analyze

static analyze 기능이 포함 되어 있다.


ARC option이 설정된 프로젝트를 ARC 설정을 제거 하고 
이 기능을 이용해서 문제점을 찾아 작업을 할 수도 있다.

Codesonar 나 SPARROW 같은 정적 분석툴을 XCode에서는 사용할 필요가 없겠다.
아주 훌륭한 정적 분석기가 내장되어 있는 XCode 정말 아름답다.


이 기능을 모르던 시절에 작업한 프로젝트를 돌려 보니 다양한 문제점을 보여준다.
아래는 그러한 유형을... 
이걸 보면 코드를 아름답게 다시 작성 할수 있다.


1. Memory Potential leak : 잠재적 메모리 누수


request 객체가 잠재적인 메모리 누수가 있음을 알려준다.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:
                                    [NSURL URLWithString:[NSString 
.... 생략
--> autorelease를 추가 해야 한다.


2. Logic error : 논리 오류

if 문 ~ else if 의 else가 없다. rowCount는 초기화 되지 않고 리턴 될수 있음을 알린다.


3. Optimization 사용하지 않는 객체를 Class  선언시 멤버로 가지고 있다.


4. Dead Store : 설정만 하고 사용하지 않는 변수





iOS 프로그래밍 팁 - Objective - C 메모리 관리

ARC  옵션을 끄고 프로그래밍을 했고
수동으로 메모리 관리를 했는데
그래도 알고 넘어 가자

Objective-C  의 수동 메모리 관리 관련 메서드


retainCount : 객체 혹은 인스턴스의 변수가 특정 메모리 공간을 참조 하고 있는가를 나타내는 정수

alloc :  생성된 객체에 메모리 공간을 할장한다.

retain : 객체가 메모리 공간을 참조 하고 있다는 사실을 iOS에 알린다. reationCount를 1증가 시킨다.

release : retainCount 1감소 시킨다.

dealloc : 메모리 공간을 참조하고 있는 모든 객체가 더는 해당 메모리 공간을 사용하지 말라는 명령을 내린다. retainCount = 0


retainCount 값이 1또는 그이상이면 iOS는 메모리 공간을 소유하고 사용할수 있다.
retainCount 값이 0이 될경우 공간에 대한 소유권을 반환받아 할당되었던 메모리 공간을 회수 한다.



약한 참조 (weak reference)
Foo * myFooOne = [[Foo alloc[ initWithName:@"James"];
Foo * myFooTwo = myFooOne       //<--- 약한 참조
[myFooOne release];
//myFooTwo  사용시 런타임 에러 발생



Foo * myFooOne = [[Foo alloc[ initWithName:@"James"];
Foo * myFooTwo = myFooOne       //<--- 약한 참조
[myFooTwo retain]; //<-- 해주어야
[myFooOne release];

//myFooTwo 이용가능


자동 메모리 관리 ARC


ARC는 Automatic Reference Counting의 약자로 기존에 수동(MRC라고 함)으로 개발자가 직접 retain/release를 통해 reference counting을 관리해야 하는 부분을 자동으로 해준다.

1. retain/release/autorelease 키워드 사용금지
2. C 구조체 내에 Object 타입 사용 금지
3. Core Foundation은 Objective-C의 Object 타입이 아니므로 Core Foundation 과 Object 간의 명시적인 타입 캐스팅이 필요 하다.


프로퍼티 속성
strong --> retain 과 거의 같다.

weak 는 assign 키워드 처럼 retainCount를 증가 시키지 않는다.
assign과는 다르게 참조하는 객체가 해제(deallocated)되면 weak로 선언된 프로퍼티는 자동으로 nil이 대입된다

ARC가 없던시절
reain --> strong
assing --> weak 
라고 이해 하면
weak가 assign과 차이점이라면
음 assign은 int float 등등 primitive타입에 사용하는 것이고 weak는 객체에 사용한다고 생각하면 
될듯 하다.

그래도 역시 ARC보단 ARC off가 편할듯 하다.


2013년 4월 25일 목요일

iOS 프로그래밍 팁 - XMLParser


XML 파싱을 위해서는 NSXMLParserDelegate를 구현해야 한다.

헤더 파일에 아래와 같이 <NSXMLParserDelegate>를 추가 한다.

@interface AlumnusViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, NSXMLParserDelegate>


그리고 NSXMLParserDelegate 함수를 구현 한다.
#pragma mark XMLParse delegate methods

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    
   //xml 엘리먼트 종류 별로 분류 elementType 변수에 설정 한다....
.....
    [_xmlValue setString:@""];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    
    if (elementType != kBOARDXML)
        return;
    
    if ([elementName isEqualToString:@"boardName"]) {
        [boardData setValue:[NSString stringWithString:_xmlValue] forKey:elementName];
    }
 
//위와 같은 방법으로 엘리먼트 문자열을 비교하여 boardData와 같은 파싱에 결과가 되는
//NSMutableDictionary 에 값을 설정 한다.

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

//파서에 들어오는 string을 NSMutableString *_xmlValue에 추가하는 작업을 한다.

    if (elementType == kBOARDXML) {
        if (!_xmlValue) {
            _xmlValue = [[NSMutableString alloc]initWithCapacity:0];
        }
        [_xmlValue appendString:string];
    }
    
 
}



 통신에 결과로  XML데이터를 수신 하였을 경우


- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSXMLParser* parser = [[[NSXMLParser alloc] initWithData:receiveData] autorelease];
    [parser setDelegate:self];
    [boardData removeAllObjects];
    [boardParseData removeAllObjects];
    BOOL success = [parser parse];
    if (success) {
        NSLog(@"XML parse success");
        //테이블 작업....

//파싱에 결과로 생성된 baoradData, boardParseData의 키 밸류를 적절히 활용한다.


        
    }else {
        NSLog(@"XML parse ERROR");
    }



connectionDidFinishLoading 메서드에서 receiveData를 parser로 할당 하고
[parser parse] 메세지가 성공하면 xml 파싱이 성공한 것이다.

success 가 YES일때 파싱 성공에 의해 생성된  NSMutableDictionary 객체 boardData, boardParseData 를 이용한다.

이상 간단하게 XML파서를 이용하는 방법이다.




iOS 프로그래밍 팁 - NSThread 사용하기

알티베이스 메뉴얼 앱을 최초 개발 할 때의 일이다.
기본 아이디어가 알티베이스 메뉴얼 pdf 파일이 여러 개이고
사용자는 이 여러 개의 pdf 파일에서 검색어 하나로 찾고 싶어 할 것이라는 가정 하에

찾을 대상에 pdf 파일 선택 화면을 만들고
선택된 pdf 파일에서 검색어로 키워드를 찾는 것이다.

 pdf에서 text 를 검색하는 것은 상당한 시간이 걸리는 작업이고
이를 여러 파일에 대해서 하려니 UI가 그동안 얼어 버린다.

해서 thread로 구현 해야 했다.


- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    [searchBar resignFirstResponder];
    [self.view bringSubviewToFront:webActInd];

    [webActInd startAnimating];
    [resultFilename removeAllObjects];
    [resultThumbImg removeAllObjects];
    [resultPageNum removeAllObjects];
    
    [tableView_ reloadData];
    //스레드
    searchText = [NSString stringWithString:searchBar.text];
    [NSThread detachNewThreadSelector:@selector(searchDoJob) toTarget:self withObject:nil];
    
    
    //[webActInd stopAnimating];
}


알티베이스 메뉴얼 버젼 1.0에서 검색 버튼을 눌렀을 때 코드이다.
NSThread 를 사용하여 구동 될 메서드 searchDoJob을 설정 한다.




- (void) searchDoJob
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    //pdfSearch = [[[PDFSearch alloc]init]autorelease];
    
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    
    NSString *text = [NSString stringWithString:searchText];
    
    //모든 파일이름을 루프로 돌려 검색 한다.
    
    for (NSInteger j = 0; j< [filename_ count]; j++)
    {
        NSString * filename = [filename_ objectAtIndex:j];
        if ([userDefault boolForKey:filename])
        {
//            NSURL *pdfURL = [[NSBundle mainBundle] URLForResource:filename withExtension:@"pdf"];
//            
//            MFDocumentManager *documentManager = [[MFDocumentManager alloc]initWithFileUrl:pdfURL];



            
            
//            CGPDFDocumentRef document =  CGPDFDocumentCreateWithURL(( CFURLRef)pdfURL);
//            for (NSInteger i=1; i< CGPDFDocumentGetNumberOfPages(document); i++ )
//            {
//                CGPDFPageRef PDFPage = CGPDFDocumentGetPage(document, i);
//                
//                if ([pdfSearch page:PDFPage containsString:text] )
//                {
//                    NSString * pageNumStr= [NSString stringWithFormat:@"%i",i];
//                    [resultFilename addObject:filename];
//                    [resultPageNum addObject:pageNumStr];
//                    
//                    [resultThumbImg addObject:[self imageFromPDFWithDocumentRef:document andPageNum:i]];
//                    
//                    if ([resultFilename count] > 100)
//                        break;
//                    
//                    [tableView_ reloadData];
//                }
//                
//            }
//            CGPDFDocumentRelease(document);
        }
        
        if ([resultFilename count] > 100)
            break;
        
    }
    [webActInd stopAnimating];
    [pool release];
}

선택된 파일들 (filename_ ) array에서 CGPDocuemntRef를 이용해서 주석처리된 부분이 실제로 PDF파일에서 문자열 검색을 하는 부분이고 결과로 pdf 파일 명과 페이지 번호 그리고 썸네일 이미지를 생성하는 부분이다.

현재 1.5버젼 이상 부 터는 fastpdfkit 라이브러리를 사용하기 때문에 관련 코드는 모두 주석 처리 되었다.

이렇게 수행 시간이 오래 걸리는 작업을 처리 하기 위해서는 NSThread가 필요하다.

2013년 4월 24일 수요일

parallels desktop 제거 후 런치패드에 남아 있는 windows7 Applications 폴더 제거 하기

parallels desktop 8 trial을 설치해보았다.

역시 Virtual Box보다 한수위 인 듯 하다.
VirtualBox의 seamless 모드는 시작 메뉴와 바가 mac os 상단에 떡하니 표시 되는것이 거슬려서
사용 하지 않았는데 parallels의 기본 모드는 완전히 통합되어 windows 응용 프로그램이 마치
mac용 응용프로그램과 같이 되고 너무 좋은 듯 했다.

하지만 90000원, 적어도 84000원 이라는 금액의 압박

바로 언인스톨
그냥 Applications 폴더에서 제거 했다.

dock에 남아 있는 windows7 Applications폴더는 그냥 제거 했다.
그럼 끝인 줄 알았는데......

Launchpad 화면에 떡하니 남아 있는 windows7 Applications

헐.....

이거 어떻게 지우지

http://macnews.tistory.com/385
런치패드에 finder 넣기에서 맨 아래 제거 하기...

해서 이 방법으로 잘된다.

sudo sqlite3 ~/Library/Application\ Support/Dock/*.db "DELETE from apps WHERE title='windows7 Applications';" && killall Dock

터미널에서 위와 같이 입력하면 windows7 Applications 폴더를 제거 할 수 있다.

2013년 4월 16일 화요일

iOS 프로그래밍 팁, jSON 객체를 주고 받는 클라이언트 개발

서버 <-----> iOS 클라이언트 관에 데이터 통신을 하는 앱 개발에 필요한 방법을 정리한다.



1. jSON 객체를 주고 받는다.
2. HTTP 프로토콜을 이용한다.
3. jSON 객체 string은 다음에 과정을 거친다.
jSON string --> base64Enc --> AES256Enc --> byte2Hex String --> HTTP 통신 --> 서버
서버 --> HTTP 통신 ---> hex2byte --> AES256Dec --> base64Dec --> JSON string


4. 필요한 모듈
이를 위해 필요한 것은 아래의 NSString 및 NSData 카테고리 클래스를 구해야 한다.



NSString+Base64.m / h

https://github.com/kyoshikawa/ZUtilities/blob/master/NSData%2BAES256.m

NSData+AES25.m / h

https://github.com/nicklockwood/Base64

NSData+Base64.m / h


5. 인크립트 디크립트 함수를 구현 하는 crypto클래스를 작성한다.
... 생략 ....



//string -> base64Enc -> aes256Enc -> byte2hex
- (NSString *) encryptString:(NSString *)textString {
    NSString * base64Enc = [self base64Encode:textString];
    NSData * aes256enc = [self encryptString:base64Enc withKey:[self generateKey]];
    return [self byteToHexString:aes256enc];
}

// hex2byte-> aes256Dec --> Base64Dec --> string
- (NSString *) decryptString:(NSString *)textString {
    NSData * data = [self hexToBytes:textString];
    NSString * aes256dec = [self decryptData:data withKey:[self generateKey]];
    return [self base64Decode:aes256dec];
}

... 생략 ...



6. jSON객체를 핸들링 하기 위한 모듈을 준비한다.
json 객체를 이용하기 위해서는 

http://superloopy.io/json-framework/

에서 jSON 모듈이 필요하다.


7. 서버에 요청 하기 위한 jSON객체 생성과 인크립트를 한다.


NSArray *keys = [NSArray arrayWithObjects:@"graduateNo", @"name", @"alumniName", nil];
    NSArray *objects = [NSArray arrayWithObjects:txtFieldNumber.text, txtFieldName.text, txtFiledAlumiName.text, nil];
    NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
    
    NSString *jsonString =[jsonDictionary JSONRepresentation];



위와 같이 key와 key값을 NSArray와 NSDictionary 를 이용하여 jsonString을 얻어 낼수 있다.

인크립트 메서드를 가지고 있는 crypto클래스를 이용해서 전송에 필요한 데이터를 구성한다.


8. 서버에 전송
NSMutableURLRequest,  NSURLConnection 을 이용해서 서버에 전송한다.

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:
                                    [NSURL URLWithString:[NSString stringWithFormat: @"%@/api/xxxx.api",
                                                          SERVER_URL]]
                                                                cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5.0];
    
    [request addValue:@"application/x-www-from-urlencoded" forHTTPHeaderField:@"content-type"];
    [request setHTTPBody:jsonData];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d",[jsonData length]] forHTTPHeaderField:@"Content-Length"];
    
    NSURLConnection *connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
        
    if(connection) {
receiveData = [[NSMutableData alloc] init];
}

9. 서버로 부터 응답 처리


- (void)connection:(NSURLConnection *)connection didReceiveResponse:

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

응답에 관련된 메서드를 각각 구현한다.

서버에 응답 데이터에 대해서는
didReceiveResponse 에서 NSData 를 append 하고

connectionDidFinishLoading
에서 완성된 데이터를 crypto 클래스의 decryp 메서드를 이용해서 json 스트링으로 변환 한다.

마지막으로 JSONValue 를 통해서 NSDictionary로 변환 하여 
필요한 값을 valeuForKey로 얻어 낸다.











2013년 4월 15일 월요일

디바이스 좌표계를 OpenGL 좌표계로 변환


OpenGL의 좌표계는 화면에 중심에 0,0 으로 부터 좌측 -1.0 우측 +1.0
위로 +1.0 아래로 -1.0 이더라

마치 수학시간 좌표계

이게 지금까지 컴퓨터 그래픽 좌표계와 달라서 혼돈스럽다.


gwidth
gheight

가 설정되어 있다고 가정 하고 아래에 함수를 이용해서 x,y를 입력하면
OpenGL에서 사용하는 화면에 중앙을 기준으로 float -1.0 ~ +1.0까지의 x, y
좌표 체계로 변환 하는 함수이다.

  void convertDeviceXY2OpenglXY(int x, int y, float * ox, float  * oy)
  {
      int w = gwidth;
      int h = gheight;
      *ox = (float)((x - (float)w/2.0)*(float)(1.0/ (float)(w/2.0)));
      *oy = -(float)((y - (float)h/2.0)*(float)(1.0/ (float)(h/2.0)));
  }

를 이용 할수 있다.


https://github.com/sparrowapps/CohenSutherlandLineClipp

코헨서덜런드 라인클립핑 알고리즘을 mac os에서 OpenGL로 구현할때 
이함수를 이용 하였다.

2013년 3월 20일 수요일

iOS 프로그래밍 팁 - Custom URL Scheme

custom URL scheme 기능은

사파리에서 특정 URL 을 입력하면 앱이 활성되게 할수 있다.

아래 apple 사이트에서

Implementing Custom URL Schemes 

항목을 참고하면 이해가 갈것이다.


http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/AdvancedAppTricks/AdvancedAppTricks.html

여기를 참조 하여 xxxxx-info.plist 파일을 수정 하는 방법을 쉽게 이해 할수 있다.


http://iosdevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html


실제로 xxxxx-info.pilist 파일에 내용을 확인 해보면
다음과 같다.


<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>sparrowapps</string>
</array>
</dict>
</array>


사파리에서  주소창에 sparrowapss://를 입력 하면 해당 앱이 활성된다.

2013년 3월 14일 목요일

2007 lenovo Thinkpad T60의 부활

이 글을 T60으로 쓴다면 스크린 샷 이랑 해서 좀 더 자세히 쓸수 있겠지만
이글은 2012 mac mini로 작성하고 있다.

2007년 당시 170만원에 육박하는 가격으로 lenovo Thinkpad T60을 구입했다.
지금은 2013년 3월이니까 벌써 6년이 지났다.

당시의 최신의 CPU와 엄청난 용량의 메모리 최고의 성능이라 자부 했지만
지금은 그냥 오래된 노트북이다.

2012 late mac mini 의 엄청난 속도에 비하면 느리고 답답하다.

인터넷 쇼핑을 하기에도 부족한 성능이다.

메롬 플랫폼은 램이 2GB를 두개 꽂아도 3GB로 인식 한다.
OS가 64bit여도 소용이 없다.

그래서 1GB, 2GB를 꽂아서 T60과 구형 맥미니를 사이좋게 3GB 머신으로 만든지
오래 되었다.

메모리가 3GB나 되지만 느린 120GB 5400rpm 하드 디스크 그리고 CPU로 인해 답답하다.

시스템 메모리를 2기가로 줄이고 1기가를 램 디스크로 설정해서

인터넷 익스플로러의 temp를 램 디스크로 설정
램 디스크에 readyboost 설정
환경 변수 TEMP와 TMP의 경로도 램 디스크로 설정

이렇게 설정을 하니 인터넷 속도가 훨씬 빨라 졌다.

잠시 SSD를 구매할까 고민했던,..
아니면 버리고 새로 노트북을 장만할까.. 고민 했던...
그냥 더 쓰자..
어짜피 난 mac을 쓰고
이건 그냥 인터넷 쇼핑 용이니까...



2013년 2월 14일 목요일

iOS 프로그래밍 팁 - NSLog() 사용시 릴리즈 빌드시 제거하기

NSLog() 자체가 릴리즈 빌드에서 저절로 사라 질까?

그랫으면 좋으련만

그럼 NSLog()를 사용한곳 앞뒤로 #ifndef ~ #endif 로 해야 하나?

아니면 NSLog()를 매크로로 만들고 DebugLog() ?

NSLog()를 사용한 곳을 모두 replace 해서 DebugLog()로 바꿔야 하나 ?

가장 간단한 해답을 찾았다.

그리고 DEBUG=1  같은 것을 설정 할 필요도 없이


앱이름-Prefix.pch 

파일에

#ifndef __OPTIMIZE__
#    define NSLog(…) NSLog(__VA_ARGS__)
#else
#    define NSLog(…) {}
#endif


를 추가해주면 된다.




2013년 1월 5일 토요일

iOS 프로그래밍 팁 - UIActivityIndicatorView 가 에니메이션 되는 동안 UI 잠그기

어떤 버튼이 네트워크 통신을 시도 한다고 할때

버튼을 누르면 네트워크 전송 코드가...

네트워크 응답에 관련된 함수들이 대기 할것이다.

UIActivityIndicatorView를 이용해서 에니메이션을 진행 하고
네트워크 수신이 완료되거나 에러가 나거나 처리가 완료 되면

에니메이션을 중지 할 것이다.

그런데 버튼을 누르고 바로 또 누르면
또는 어떠한 UI 동작을 한다면..

문제를 일으킬 것이다.

인디케이터 에니메이션이 동작 하는 동안 UI 동작을 막도록 하려면

에니메이션 시작에서

self.view setUserInteractionEnabled:NO];
    [webActInd startAnimating];

끝에 다시 

webActInd stopAnimating];
    [self.view setUserInteractionEnabled:YES];

이렇게 하여 UI 동작을 막을 수 있다.